feat(turbopack): embed build time info, emits next features telemetry event (#53028)
### What? closes WEB-1301. To collect some information inside of rust binary, embed it as build-time constant. It supersedes existing target triple embedding as well.
This commit is contained in:
parent
f1bd1eda8e
commit
974accc2c7
15 changed files with 285 additions and 21 deletions
50
Cargo.lock
generated
50
Cargo.lock
generated
|
@ -2640,6 +2640,12 @@ version = "1.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
|
||||
|
||||
[[package]]
|
||||
name = "is_debug"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89"
|
||||
|
||||
[[package]]
|
||||
name = "isahc"
|
||||
version = "1.7.2"
|
||||
|
@ -3378,6 +3384,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shadow-rs",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
|
@ -3548,6 +3555,7 @@ dependencies = [
|
|||
"sentry",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shadow-rs",
|
||||
"tracing",
|
||||
"tracing-chrome",
|
||||
"tracing-futures",
|
||||
|
@ -3743,6 +3751,15 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
|
@ -5189,6 +5206,18 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shadow-rs"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "970538704756fd0bb4ec8cb89f80674afb661e7c0fe716f9ba5be57717742300"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"is_debug",
|
||||
"time 0.3.20",
|
||||
"tzdb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
|
@ -6870,6 +6899,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros 0.2.8",
|
||||
|
@ -7983,6 +8014,25 @@ version = "1.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "tz-rs"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33851b15c848fad2cf4b105c6bb66eb9512b6f6c44a4b13f57c53c73c707e2b4"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdb"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec758958f2fb5069cd7fae385be95cc8eceb8cdfd270c7d14de6034f0108d99e"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"tz-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
|
|
|
@ -121,6 +121,7 @@ serde = { version = "1.0.152", features = ["derive"] }
|
|||
serde_json = "1.0.93"
|
||||
serde_qs = "0.11.0"
|
||||
serde_yaml = "0.9.17"
|
||||
shadow-rs = { version = "0.23.0", default-features = false, features = ["tzdb"] }
|
||||
syn = "1.0.107"
|
||||
tempfile = "3.3.0"
|
||||
thiserror = "1.0.38"
|
||||
|
|
|
@ -50,6 +50,7 @@ turbo-tasks = { workspace = true }
|
|||
once_cell = { workspace = true }
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
shadow-rs = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-futures = "0.2.5"
|
||||
tracing-subscriber = { workspace = true }
|
||||
|
@ -84,6 +85,8 @@ sentry = { version = "0.27.0", default-features = false, features = [
|
|||
napi-build = "2"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
# It is not a mistake this dependency is specified in dep / build-dep both.
|
||||
shadow-rs = { workspace = true }
|
||||
turbopack-binding = { workspace = true, features = [
|
||||
"__turbo_tasks_build"
|
||||
]}
|
||||
|
|
|
@ -10,22 +10,15 @@ use turbopack_binding::turbo::tasks_build::generate_register;
|
|||
extern crate napi_build;
|
||||
|
||||
fn main() {
|
||||
// Emit current platform's target-triple into a text file to create static const
|
||||
// in util.rs
|
||||
let out_dir = env::var("OUT_DIR").expect("Outdir should exist");
|
||||
let dest_path = Path::new(&out_dir).join("triple.txt");
|
||||
let mut f =
|
||||
BufWriter::new(File::create(dest_path).expect("Failed to create target triple text"));
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
env::var("TARGET").expect("Target should be specified")
|
||||
)
|
||||
.expect("Failed to write target triple text");
|
||||
// Generates, stores build-time information as static values.
|
||||
// There are some places relying on correct values for this (i.e telemetry),
|
||||
// So failing build if this fails.
|
||||
shadow_rs::new().expect("Should able to generate build time information");
|
||||
|
||||
// Emit current package.json's version field into a text file to create static
|
||||
// const in util.rs This is being used to set correct release version for
|
||||
// the sentry's crash reporter.
|
||||
let out_dir = env::var("OUT_DIR").expect("Outdir should exist");
|
||||
let pkg_file =
|
||||
File::open(Path::new("../../package.json")).expect("Should able to open package.json");
|
||||
let json: serde_json::Value = serde_json::from_reader(pkg_file).unwrap();
|
||||
|
|
|
@ -58,6 +58,9 @@ pub mod turbopack;
|
|||
pub mod turbotrace;
|
||||
pub mod util;
|
||||
|
||||
// Declare build-time information variables generated in build.rs
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
// don't use turbo malloc (`mimalloc`) on linux-musl-aarch64 because of the
|
||||
// compile error
|
||||
#[cfg(not(any(
|
||||
|
|
|
@ -41,6 +41,9 @@ pub struct NapiProjectOptions {
|
|||
/// The contents of next.config.js, serialized to JSON.
|
||||
pub next_config: String,
|
||||
|
||||
/// The contents of ts/config read by load-jsconfig, serialized to JSON.
|
||||
pub js_config: String,
|
||||
|
||||
/// A map of environment variables to use when compiling code.
|
||||
pub env: Vec<NapiEnvVar>,
|
||||
}
|
||||
|
@ -58,6 +61,7 @@ impl From<NapiProjectOptions> for ProjectOptions {
|
|||
project_path: val.project_path,
|
||||
watch: val.watch,
|
||||
next_config: val.next_config,
|
||||
js_config: val.js_config,
|
||||
env: val
|
||||
.env
|
||||
.into_iter()
|
||||
|
|
|
@ -41,13 +41,12 @@ use sentry::ClientOptions;
|
|||
use tracing_chrome::{ChromeLayerBuilder, FlushGuard};
|
||||
use tracing_subscriber::{filter, prelude::*, util::SubscriberInitExt, Layer};
|
||||
|
||||
static TARGET_TRIPLE: &str = include_str!(concat!(env!("OUT_DIR"), "/triple.txt"));
|
||||
#[allow(unused)]
|
||||
static PACKAGE_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/package.txt"));
|
||||
|
||||
#[napi]
|
||||
pub fn get_target_triple() -> String {
|
||||
TARGET_TRIPLE.to_owned()
|
||||
crate::build::BUILD_TARGET.to_string()
|
||||
}
|
||||
|
||||
pub trait MapErr<T>: Into<Result<T, anyhow::Error>> {
|
||||
|
|
|
@ -23,6 +23,7 @@ next-core = { workspace = true }
|
|||
once_cell = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
shadow-rs = { workspace = true }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
turbopack-binding = { workspace = true, features = [
|
||||
"__turbo_tasks_memory",
|
||||
|
@ -42,6 +43,8 @@ tracing = { workspace = true }
|
|||
tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
|
||||
|
||||
[build-dependencies]
|
||||
# It is not a mistake this dependency is specified in dep / build-dep both.
|
||||
shadow-rs = { workspace = true }
|
||||
turbopack-binding = { workspace = true, features = [
|
||||
"__turbo_tasks_build"
|
||||
]}
|
|
@ -1,5 +1,10 @@
|
|||
use turbopack_binding::turbo::tasks_build::generate_register;
|
||||
|
||||
fn main() {
|
||||
// Generates, stores build-time information as static values.
|
||||
// There are some places relying on correct values for this (i.e telemetry),
|
||||
// So failing build if this fails.
|
||||
shadow_rs::new().expect("Should able to generate build time information");
|
||||
|
||||
generate_register();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ mod pages;
|
|||
pub mod project;
|
||||
pub mod route;
|
||||
|
||||
// Declare build-time information variables generated in build.rs
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
pub fn register() {
|
||||
next_core::register();
|
||||
turbopack_binding::turbopack::build::register();
|
||||
|
|
|
@ -7,8 +7,9 @@ use next_core::{
|
|||
get_edge_chunking_context, get_edge_compile_time_info,
|
||||
mode::NextMode,
|
||||
next_client::{get_client_chunking_context, get_client_compile_time_info},
|
||||
next_config::NextConfig,
|
||||
next_config::{JsConfig, NextConfig},
|
||||
next_server::{get_server_chunking_context, get_server_compile_time_info},
|
||||
next_telemetry::NextFeatureTelemetry,
|
||||
util::NextSourceConfig,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -23,8 +24,8 @@ use turbopack_binding::{
|
|||
turbopack::{
|
||||
build::BuildChunkingContext,
|
||||
core::{
|
||||
chunk::ChunkingContext, compile_time_info::CompileTimeInfo, environment::ServerAddr,
|
||||
PROJECT_FILESYSTEM_NAME,
|
||||
chunk::ChunkingContext, compile_time_info::CompileTimeInfo, diagnostics::DiagnosticExt,
|
||||
environment::ServerAddr, PROJECT_FILESYSTEM_NAME,
|
||||
},
|
||||
dev::DevChunkingContext,
|
||||
ecmascript::chunk::EcmascriptChunkingContext,
|
||||
|
@ -35,6 +36,7 @@ use turbopack_binding::{
|
|||
|
||||
use crate::{
|
||||
app::{AppProject, OptionAppProject},
|
||||
build,
|
||||
entrypoints::Entrypoints,
|
||||
pages::PagesProject,
|
||||
route::{Endpoint, Route},
|
||||
|
@ -53,6 +55,9 @@ pub struct ProjectOptions {
|
|||
/// The contents of next.config.js, serialized to JSON.
|
||||
pub next_config: String,
|
||||
|
||||
/// The contents of ts/config read by load-jsconfig, serialized to JSON.
|
||||
pub js_config: String,
|
||||
|
||||
/// A map of environment variables to use when compiling code.
|
||||
pub env: Vec<(String, String)>,
|
||||
|
||||
|
@ -92,12 +97,14 @@ impl ProjectContainer {
|
|||
let this = self.await?;
|
||||
let options = this.state.get();
|
||||
let next_config = NextConfig::from_string(Vc::cell(options.next_config.clone()));
|
||||
let js_config = JsConfig::from_string(Vc::cell(options.js_config.clone()));
|
||||
let env: Vc<EnvMap> = Vc::cell(options.env.iter().cloned().collect());
|
||||
Ok(Project {
|
||||
root_path: options.root_path.clone(),
|
||||
project_path: options.project_path.clone(),
|
||||
watch: options.watch,
|
||||
next_config,
|
||||
js_config,
|
||||
env: Vc::upcast(env),
|
||||
browserslist_query: "last 1 Chrome versions, last 1 Firefox versions, last 1 Safari \
|
||||
versions, last 1 Edge versions"
|
||||
|
@ -128,6 +135,9 @@ pub struct Project {
|
|||
/// Next config.
|
||||
next_config: Vc<NextConfig>,
|
||||
|
||||
/// Js/Tsconfig read by load-jsconfig
|
||||
js_config: Vc<JsConfig>,
|
||||
|
||||
/// A map of environment variables to use when compiling code.
|
||||
env: Vc<Box<dyn ProcessEnv>>,
|
||||
|
||||
|
@ -225,6 +235,11 @@ impl Project {
|
|||
Ok(self.await?.next_config)
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub(super) async fn js_config(self: Vc<Self>) -> Result<Vc<JsConfig>> {
|
||||
Ok(self.await?.js_config)
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub(super) fn execution_context(self: Vc<Self>) -> Vc<ExecutionContext> {
|
||||
let node_root = self.node_root();
|
||||
|
@ -305,6 +320,84 @@ impl Project {
|
|||
)
|
||||
}
|
||||
|
||||
/// Emit a telemetry event corresponding to webpack configuration telemetry
|
||||
/// (https://github.com/vercel/next.js/blob/9da305fe320b89ee2f8c3cfb7ecbf48856368913/packages/next/src/build/webpack-config.ts#L2516)
|
||||
/// to detect which feature is enabled.
|
||||
#[turbo_tasks::function]
|
||||
async fn collect_project_feature_telemetry(self: Vc<Self>) -> Result<Vc<()>> {
|
||||
let emit_event = |feature_name: &str, enabled: bool| {
|
||||
NextFeatureTelemetry::new(feature_name.to_string(), enabled)
|
||||
.cell()
|
||||
.emit();
|
||||
};
|
||||
|
||||
// First, emit an event for the binary target triple.
|
||||
// This is different to webpack-config; when this is being called,
|
||||
// it is always using SWC so we don't check swc here.
|
||||
emit_event(build::BUILD_TARGET, true);
|
||||
|
||||
// Go over jsconfig and report enabled features.
|
||||
let compiler_options = self.js_config().compiler_options().await?;
|
||||
let compiler_options = compiler_options.as_object();
|
||||
let experimental_decorators_enabled = compiler_options
|
||||
.as_ref()
|
||||
.and_then(|compiler_options| compiler_options.get("experimentalDecorators"))
|
||||
.is_some();
|
||||
let jsx_import_source_enabled = compiler_options
|
||||
.as_ref()
|
||||
.and_then(|compiler_options| compiler_options.get("jsxImportSource"))
|
||||
.is_some();
|
||||
|
||||
emit_event("swcExperimentalDecorators", experimental_decorators_enabled);
|
||||
emit_event("swcImportSource", jsx_import_source_enabled);
|
||||
|
||||
// Go over config and report enabled features.
|
||||
// [TODO]: useSwcLoader is not being reported as it is not directly corresponds (it checks babel config existence)
|
||||
// need to confirm what we'll do with turbopack.
|
||||
let config = self.next_config();
|
||||
|
||||
emit_event("swcMinify", *config.swc_minify().await?);
|
||||
emit_event(
|
||||
"skipMiddlewareUrlNormalize",
|
||||
*config.skip_middleware_url_normalize().await?,
|
||||
);
|
||||
|
||||
emit_event(
|
||||
"skipTrailingSlashRedirect",
|
||||
*config.skip_trailing_slash_redirect().await?,
|
||||
);
|
||||
|
||||
let config = &config.await?;
|
||||
|
||||
emit_event("modularizeImports", config.modularize_imports.is_some());
|
||||
emit_event("transpilePackages", config.transpile_packages.is_some());
|
||||
emit_event("turbotrace", config.experimental.turbotrace.is_some());
|
||||
|
||||
// compiler options
|
||||
let compiler_options = config.compiler.as_ref();
|
||||
let swc_relay_enabled = compiler_options.and_then(|c| c.relay.as_ref()).is_some();
|
||||
let styled_components_enabled = compiler_options
|
||||
.map(|c| c.styled_components.is_some())
|
||||
.unwrap_or_default();
|
||||
let react_remove_properties_enabled = compiler_options
|
||||
.and_then(|c| c.react_remove_properties)
|
||||
.unwrap_or_default();
|
||||
let remove_console_enabled = compiler_options
|
||||
.map(|c| c.remove_console.is_some())
|
||||
.unwrap_or_default();
|
||||
let emotion_enabled = compiler_options
|
||||
.map(|c| c.emotion.is_some())
|
||||
.unwrap_or_default();
|
||||
|
||||
emit_event("swcRelay", swc_relay_enabled);
|
||||
emit_event("swcStyledComponents", styled_components_enabled);
|
||||
emit_event("swcReactRemoveProperties", react_remove_properties_enabled);
|
||||
emit_event("swcRemoveConsole", remove_console_enabled);
|
||||
emit_event("swcEmotion", emotion_enabled);
|
||||
|
||||
Ok(unit())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub(super) fn ssr_chunking_context(self: Vc<Self>) -> Vc<BuildChunkingContext> {
|
||||
self.server_chunking_context().with_layer("ssr".to_string())
|
||||
|
@ -349,6 +442,8 @@ impl Project {
|
|||
/// provided page_extensions).
|
||||
#[turbo_tasks::function]
|
||||
pub async fn entrypoints(self: Vc<Self>) -> Result<Vc<Entrypoints>> {
|
||||
self.collect_project_feature_telemetry().await?;
|
||||
|
||||
let mut routes = IndexMap::new();
|
||||
let app_project = self.app_project();
|
||||
let pages_project = self.pages_project();
|
||||
|
|
|
@ -117,12 +117,14 @@ pub struct NextConfig {
|
|||
public_runtime_config: IndexMap<String, serde_json::Value>,
|
||||
server_runtime_config: IndexMap<String, serde_json::Value>,
|
||||
static_page_generation_timeout: f64,
|
||||
swc_minify: bool,
|
||||
swc_minify: Option<bool>,
|
||||
target: Option<String>,
|
||||
trailing_slash: bool,
|
||||
typescript: TypeScriptConfig,
|
||||
use_file_system_public_routes: bool,
|
||||
webpack: Option<serde_json::Value>,
|
||||
skip_middleware_url_normalize: Option<bool>,
|
||||
skip_trailing_slash_redirect: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)]
|
||||
|
@ -446,15 +448,13 @@ pub struct ExperimentalConfig {
|
|||
runtime: Option<serde_json::Value>,
|
||||
scroll_restoration: Option<bool>,
|
||||
shared_pool: Option<bool>,
|
||||
skip_middleware_url_normalize: Option<bool>,
|
||||
skip_trailing_slash_redirect: Option<bool>,
|
||||
sri: Option<serde_json::Value>,
|
||||
swc_file_reading: Option<bool>,
|
||||
swc_minify: Option<bool>,
|
||||
swc_minify_debug_options: Option<serde_json::Value>,
|
||||
swc_trace_profiling: Option<bool>,
|
||||
transpile_packages: Option<Vec<String>>,
|
||||
turbotrace: Option<serde_json::Value>,
|
||||
pub turbotrace: Option<serde_json::Value>,
|
||||
url_imports: Option<serde_json::Value>,
|
||||
web_vitals_attribution: Option<serde_json::Value>,
|
||||
worker_threads: Option<bool>,
|
||||
|
@ -653,6 +653,25 @@ impl NextConfig {
|
|||
self.await?.sass_options.clone().unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn swc_minify(self: Vc<Self>) -> Result<Vc<bool>> {
|
||||
Ok(Vc::cell(self.await?.swc_minify.unwrap_or(false)))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn skip_middleware_url_normalize(self: Vc<Self>) -> Result<Vc<bool>> {
|
||||
Ok(Vc::cell(
|
||||
self.await?.skip_middleware_url_normalize.unwrap_or(false),
|
||||
))
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn skip_trailing_slash_redirect(self: Vc<Self>) -> Result<Vc<bool>> {
|
||||
Ok(Vc::cell(
|
||||
self.await?.skip_trailing_slash_redirect.unwrap_or(false),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn next_configs() -> Vc<Vec<String>> {
|
||||
|
@ -799,6 +818,34 @@ pub async fn has_next_config(context: Vc<FileSystemPath>) -> Result<Vc<bool>> {
|
|||
)))
|
||||
}
|
||||
|
||||
/// A subset of ts/jsconfig that next.js implicitly
|
||||
/// interops with.
|
||||
#[turbo_tasks::value(serialization = "custom", eq = "manual")]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct JsConfig {
|
||||
compiler_options: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[turbo_tasks::value_impl]
|
||||
impl JsConfig {
|
||||
#[turbo_tasks::function]
|
||||
pub async fn from_string(string: Vc<String>) -> Result<Vc<Self>> {
|
||||
let string = string.await?;
|
||||
let config: JsConfig = serde_json::from_str(&string)
|
||||
.with_context(|| format!("failed to parse next.config.js: {}", string))?;
|
||||
|
||||
Ok(config.cell())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
pub async fn compiler_options(self: Vc<Self>) -> Result<Vc<serde_json::Value>> {
|
||||
Ok(Vc::cell(
|
||||
self.await?.compiler_options.clone().unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[turbo_tasks::value]
|
||||
struct OutdatedConfigIssue {
|
||||
path: Vc<FileSystemPath>,
|
||||
|
|
|
@ -5,6 +5,48 @@ use turbopack_binding::{
|
|||
turbopack::core::diagnostics::{Diagnostic, DiagnosticPayload},
|
||||
};
|
||||
|
||||
/// A struct represent telemetry event if certain feature of next.js
|
||||
/// is enabled, such as next.config.swcMinify.
|
||||
/// This is an equivalent representation of the following code:
|
||||
/// https://github.com/vercel/next.js/blob/9da305fe320b89ee2f8c3cfb7ecbf48856368913/packages/next/src/build/webpack-config.ts#L2516
|
||||
#[turbo_tasks::value(shared)]
|
||||
pub struct NextFeatureTelemetry {
|
||||
pub event_name: String,
|
||||
pub feature_name: String,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl NextFeatureTelemetry {
|
||||
pub fn new(feature_name: String, enabled: bool) -> Self {
|
||||
NextFeatureTelemetry {
|
||||
event_name: "EVENT_BUILD_FEATURE_USAGE".to_string(),
|
||||
feature_name,
|
||||
enabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[turbo_tasks::value_impl]
|
||||
impl Diagnostic for NextFeatureTelemetry {
|
||||
#[turbo_tasks::function]
|
||||
fn category(&self) -> Vc<String> {
|
||||
Vc::cell("NextFeatureTelemetry_category_tbd".to_string())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
fn name(&self) -> Vc<String> {
|
||||
Vc::cell(self.event_name.clone())
|
||||
}
|
||||
|
||||
#[turbo_tasks::function]
|
||||
fn payload(&self) -> Vc<DiagnosticPayload> {
|
||||
Vc::cell(HashMap::from([(
|
||||
self.feature_name.clone(),
|
||||
self.enabled.to_string(),
|
||||
)]))
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct represent telemetry event for the feature usage,
|
||||
/// referred as `importing` a certain module. (i.e importing @next/image)
|
||||
#[turbo_tasks::value(shared)]
|
||||
|
|
|
@ -340,6 +340,17 @@ interface ProjectOptions {
|
|||
*/
|
||||
nextConfig: NextConfigComplete
|
||||
|
||||
/**
|
||||
* Jsconfig, or tsconfig contents.
|
||||
*
|
||||
* Next.js implicitly requires to read it to support few options
|
||||
* https://nextjs.org/docs/architecture/nextjs-compiler#legacy-decorators
|
||||
* https://nextjs.org/docs/architecture/nextjs-compiler#importsource
|
||||
*/
|
||||
jsConfig: {
|
||||
compilerOptions: object
|
||||
}
|
||||
|
||||
/**
|
||||
* A map of environment variables to use when compiling code.
|
||||
*/
|
||||
|
@ -561,6 +572,7 @@ function bindingToApi(binding: any, _wasm: boolean) {
|
|||
return {
|
||||
...options,
|
||||
nextConfig: await serializeNextConfig(options.nextConfig),
|
||||
jsConfig: JSON.stringify(options.jsConfig ?? {}),
|
||||
env: Object.entries(options.env).map(([name, value]) => ({
|
||||
name,
|
||||
value,
|
||||
|
|
|
@ -226,6 +226,9 @@ const nextDev: CliCommand = async (argv) => {
|
|||
if (experimentalTurbo) {
|
||||
const { loadBindings } =
|
||||
require('../build/swc') as typeof import('../build/swc')
|
||||
const { default: loadJsConfig } =
|
||||
require('../build/load-jsconfig') as typeof import('../build/load-jsconfig')
|
||||
const { jsConfig } = await loadJsConfig(dir, config)
|
||||
|
||||
resetEnv()
|
||||
let bindings = await loadBindings()
|
||||
|
@ -236,6 +239,7 @@ const nextDev: CliCommand = async (argv) => {
|
|||
projectPath: dir,
|
||||
rootPath: args['--root'] ?? findRootDir(dir) ?? dir,
|
||||
nextConfig: config,
|
||||
jsConfig,
|
||||
env: {
|
||||
NEXT_PUBLIC_ENV_VAR: 'world',
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue