From b5ecdd0995e65f90c61aa0d476aec619476ba6b4 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:30:22 -0700 Subject: [PATCH] wip --- Cargo.lock | 35 -------- Cargo.toml | 6 +- .../crates/napi/src/next_api/project.rs | 27 ++++++- .../crates/napi/src/next_api/utils.rs | 21 ++++- packages/next-swc/crates/next-core/src/lib.rs | 1 + .../next-core/src/next_client/context.rs | 12 ++- .../crates/next-core/src/next_edge/context.rs | 17 ++-- .../next-core/src/next_server/context.rs | 13 ++- .../next-core/src/next_shared/resolve.rs | 79 ++++++++++++++++++- .../crates/next-core/src/next_telemetry.rs | 36 +++++++++ 10 files changed, 190 insertions(+), 57 deletions(-) create mode 100644 packages/next-swc/crates/next-core/src/next_telemetry.rs diff --git a/Cargo.lock b/Cargo.lock index 6715331bf4282..c92c27084e202 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,6 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "serde", ] @@ -3602,7 +3601,6 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "serde", @@ -7262,7 +7260,6 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-trait", @@ -7294,7 +7291,6 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "cargo-lock", @@ -7306,7 +7302,6 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "bytes", @@ -7321,7 +7316,6 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "dotenvs", @@ -7335,7 +7329,6 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "indexmap", @@ -7352,7 +7345,6 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "auto-hash-map", @@ -7382,7 +7374,6 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "base16", "hex", @@ -7394,7 +7385,6 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7408,7 +7398,6 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "proc-macro2", "quote", @@ -7418,7 +7407,6 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "mimalloc", ] @@ -7426,7 +7414,6 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "auto-hash-map", @@ -7449,7 +7436,6 @@ dependencies = [ [[package]] name = "turbo-tasks-testing" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "auto-hash-map", @@ -7462,7 +7448,6 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-recursion", @@ -7492,7 +7477,6 @@ dependencies = [ [[package]] name = "turbopack-bench" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "chromiumoxide", @@ -7522,7 +7506,6 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "auto-hash-map", "mdxjs", @@ -7564,7 +7547,6 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "indexmap", @@ -7584,7 +7566,6 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "clap 4.1.11", @@ -7608,7 +7589,6 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-trait", @@ -7636,7 +7616,6 @@ dependencies = [ [[package]] name = "turbopack-create-test-app" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "clap 4.1.11", @@ -7649,7 +7628,6 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-trait", @@ -7671,7 +7649,6 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "indexmap", @@ -7695,7 +7672,6 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-compression", @@ -7731,7 +7707,6 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-trait", @@ -7764,7 +7739,6 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-trait", @@ -7787,7 +7761,6 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "indoc", @@ -7804,7 +7777,6 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "indexmap", @@ -7820,7 +7792,6 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "base64 0.21.0", @@ -7840,7 +7811,6 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "serde", @@ -7855,7 +7825,6 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "mdxjs", @@ -7870,7 +7839,6 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "async-stream", @@ -7905,7 +7873,6 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "serde", @@ -7921,7 +7888,6 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "swc_core", "turbo-tasks", @@ -7932,7 +7898,6 @@ dependencies = [ [[package]] name = "turbopack-test-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230718.2#46bb9b755ec1661d3dea5986572576f7db9280c8" dependencies = [ "anyhow", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 5b5c5615b68e9..6669a8f27e4c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,11 +44,11 @@ swc_core = { version = "0.79.13" } testing = { version = "0.33.20" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230718.2" } +turbopack-binding = { path = "../turbo_upstream/crates/turbopack-binding" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230718.2" } +turbo-tasks = { path = "../turbo_upstream/crates/turbo-tasks" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230718.2" } +turbo-tasks-fs = { path = "../turbo_upstream/crates/turbo-tasks-fs" } # General Deps diff --git a/packages/next-swc/crates/napi/src/next_api/project.rs b/packages/next-swc/crates/napi/src/next_api/project.rs index 3d66d3e747050..ca7848ac339af 100644 --- a/packages/next-swc/crates/napi/src/next_api/project.rs +++ b/packages/next-swc/crates/napi/src/next_api/project.rs @@ -8,7 +8,11 @@ use next_api::{ }; use turbo_tasks::{TurboTasks, Vc}; use turbopack_binding::{ - turbo::tasks_memory::MemoryBackend, turbopack::core::error::PrettyPrintError, + turbo::{tasks::TryJoinIterExt, tasks_memory::MemoryBackend}, + turbopack::core::{ + diagnostics::{Diagnostic, DiagnosticContextExt}, + error::PrettyPrintError, + }, }; use super::{ @@ -180,12 +184,27 @@ pub fn project_entrypoints_subscribe( func, move || async move { let entrypoints = project.entrypoints(); + let captured_diags = entrypoints.peek_diagnostics().await?; + let entrypoints = entrypoints.strongly_consistent().await?; + let captured_diags = captured_diags.strongly_consistent().await?; + + let diags = captured_diags + .diagnostics + .iter() + .map(|d| d.into_plain()) + .try_join() + .await? + .iter() + .map(|d| NapiDiagnostic::from(&d)) + .collect::>(); + // TODO peek_issues and diagnostics - Ok(entrypoints) + Ok((entrypoints, diags)) }, move |ctx| { - let entrypoints = ctx.value; + let (entrypoints, diags) = ctx.value; + Ok(vec![NapiEntrypoints { routes: entrypoints .routes @@ -200,7 +219,7 @@ pub fn project_entrypoints_subscribe( .map(|m| NapiMiddleware::from_middleware(m, &turbo_tasks)) .transpose()?, issues: vec![], - diagnostics: vec![], + diagnostics: diags, }]) }, ) diff --git a/packages/next-swc/crates/napi/src/next_api/utils.rs b/packages/next-swc/crates/napi/src/next_api/utils.rs index 82a2926c0cbaa..71ba6c60d026b 100644 --- a/packages/next-swc/crates/napi/src/next_api/utils.rs +++ b/packages/next-swc/crates/napi/src/next_api/utils.rs @@ -1,4 +1,4 @@ -use std::{future::Future, ops::Deref, sync::Arc}; +use std::{future::Future, ops::Deref, sync::Arc, collections::HashMap}; use anyhow::{anyhow, Context, Result}; use napi::{ @@ -9,7 +9,8 @@ use napi::{ use serde::Serialize; use turbo_tasks::{unit, TaskId, TurboTasks}; use turbopack_binding::{ - turbo::tasks_memory::MemoryBackend, turbopack::core::error::PrettyPrintError, + turbo::tasks_memory::MemoryBackend, + turbopack::core::{diagnostics::PlainDiagnostic, error::PrettyPrintError}, }; /// A helper type to hold both a Vc operation and the TurboTasks root process. @@ -75,7 +76,21 @@ pub fn root_task_dispose( pub struct NapiIssue {} #[napi(object)] -pub struct NapiDiagnostic {} +pub struct NapiDiagnostic { + pub category: String, + pub name: String, + pub payload: HashMap, +} + +impl NapiDiagnostic { + pub fn from(diagnostic: &PlainDiagnostic) -> Self { + Self { + category: diagnostic.category.clone(), + name: diagnostic.name.clone(), + payload: diagnostic.payload.clone(), + } + } +} pub struct TurbopackResult { pub result: T, diff --git a/packages/next-swc/crates/next-core/src/lib.rs b/packages/next-swc/crates/next-core/src/lib.rs index c118178539ad2..f1cf7091d1baa 100644 --- a/packages/next-swc/crates/next-core/src/lib.rs +++ b/packages/next-swc/crates/next-core/src/lib.rs @@ -36,6 +36,7 @@ mod next_route_matcher; pub mod next_server; pub mod next_server_component; pub mod next_shared; +mod next_telemetry; mod page_loader; mod page_source; pub mod pages_structure; diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index 8ec9f5b2c18bd..952ce6979e62e 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -46,7 +46,7 @@ use crate::{ get_next_client_resolved_map, mdx_import_source_file, }, next_shared::{ - resolve::UnsupportedModulesResolvePlugin, + resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin}, transforms::{ emotion::get_emotion_transform_plugin, get_relay_transform_plugin, styled_components::get_styled_components_transform_plugin, @@ -145,9 +145,13 @@ pub async fn get_client_resolve_options_context( resolved_map: Some(next_client_resolved_map), browser: true, module: true, - plugins: vec![Vc::upcast(UnsupportedModulesResolvePlugin::new( - project_path, - ))], + plugins: vec![ + Vc::upcast(ModuleFeatureReportResolvePlugin::new( + project_path, + Vc::cell("next_client".to_string()), + )), + Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)), + ], ..Default::default() }; Ok(ResolveOptionsContext { diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index a3cdc16b3bd05..5055b7f1de175 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -17,8 +17,11 @@ use turbopack_binding::{ }; use crate::{ - mode::NextMode, next_config::NextConfig, next_import_map::get_next_edge_import_map, - next_server::context::ServerContextType, next_shared::resolve::UnsupportedModulesResolvePlugin, + mode::NextMode, + next_config::NextConfig, + next_import_map::get_next_edge_import_map, + next_server::context::ServerContextType, + next_shared::resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin}, util::foreign_code_context_condition, }; @@ -91,9 +94,13 @@ pub async fn get_edge_resolve_options_context( import_map: Some(next_edge_import_map), module: true, browser: true, - plugins: vec![Vc::upcast(UnsupportedModulesResolvePlugin::new( - project_path, - ))], + plugins: vec![ + Vc::upcast(ModuleFeatureReportResolvePlugin::new( + project_path, + Vc::cell("next_edge".to_string()), + )), + Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)), + ], ..Default::default() }; diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index fffc81e33b272..4247d80902033 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -46,7 +46,7 @@ use crate::{ next_import_map::{get_next_server_import_map, mdx_import_source_file}, next_server::resolve::ExternalPredicate, next_shared::{ - resolve::UnsupportedModulesResolvePlugin, + resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin}, transforms::{ emotion::get_emotion_transform_plugin, get_relay_transform_plugin, styled_components::get_styled_components_transform_plugin, @@ -97,6 +97,8 @@ pub async fn get_server_resolve_options_context( get_next_server_import_map(project_path, ty, mode, next_config, execution_context); let foreign_code_context_condition = foreign_code_context_condition(next_config).await?; let root_dir = project_path.root().resolve().await?; + let module_feature_report_resolve_plugin = + ModuleFeatureReportResolvePlugin::new(project_path, Vc::cell("next_server".to_string())); let unsupported_modules_resolve_plugin = UnsupportedModulesResolvePlugin::new(project_path); let server_component_externals_plugin = ExternalCjsModulesResolvePlugin::new( project_path, @@ -118,6 +120,7 @@ pub async fn get_server_resolve_options_context( custom_conditions: vec![mode.node_env().to_string(), "node".to_string()], import_map: Some(next_server_import_map), plugins: vec![ + Vc::upcast(module_feature_report_resolve_plugin), Vc::upcast(external_cjs_modules_plugin), Vc::upcast(unsupported_modules_resolve_plugin), ], @@ -146,6 +149,7 @@ pub async fn get_server_resolve_options_context( ], import_map: Some(next_server_import_map), plugins: vec![ + Vc::upcast(module_feature_report_resolve_plugin), Vc::upcast(server_component_externals_plugin), Vc::upcast(unsupported_modules_resolve_plugin), ], @@ -175,6 +179,7 @@ pub async fn get_server_resolve_options_context( ], import_map: Some(next_server_import_map), plugins: vec![ + Vc::upcast(module_feature_report_resolve_plugin), Vc::upcast(server_component_externals_plugin), Vc::upcast(unsupported_modules_resolve_plugin), ], @@ -197,6 +202,7 @@ pub async fn get_server_resolve_options_context( custom_conditions: vec![mode.node_env().to_string(), "node".to_string()], import_map: Some(next_server_import_map), plugins: vec![ + Vc::upcast(module_feature_report_resolve_plugin), Vc::upcast(server_component_externals_plugin), Vc::upcast(unsupported_modules_resolve_plugin), ], @@ -218,7 +224,10 @@ pub async fn get_server_resolve_options_context( enable_node_externals: true, module: true, custom_conditions: vec![mode.node_env().to_string()], - plugins: vec![Vc::upcast(unsupported_modules_resolve_plugin)], + plugins: vec![ + Vc::upcast(module_feature_report_resolve_plugin), + Vc::upcast(unsupported_modules_resolve_plugin), + ], ..Default::default() }; ResolveOptionsContext { diff --git a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs index 30f2693d29eca..26e518b4b2010 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use anyhow::Result; use lazy_static::lazy_static; @@ -7,6 +7,7 @@ use turbo_tasks_fs::glob::Glob; use turbopack_binding::{ turbo::tasks_fs::FileSystemPath, turbopack::core::{ + diagnostics::DiagnosticExt, issue::{unsupported_module::UnsupportedModuleIssue, IssueExt}, resolve::{ parse::Request, @@ -17,9 +18,27 @@ use turbopack_binding::{ }, }; +use crate::next_telemetry::ModuleFeatureTelemetry; + lazy_static! { static ref UNSUPPORTED_PACKAGES: HashSet<&'static str> = ["@vercel/og"].into(); static ref UNSUPPORTED_PACKAGE_PATHS: HashSet<(&'static str, &'static str)> = [].into(); + // Set of the features we want to track, following existing references in webpack/plugins/telemetry-plugin. + static ref FEATURE_MODULES: HashMap<&'static str, Vec<&'static str>> = HashMap::from([ + ( + "next", + vec![ + "/image", + "/future/image", + "/legacy/image", + "/script", + "/dynamic", + "/font/google", + "/font/local" + ] + ), + ("@next", vec!["/font/google", "/font/local"]) + ]); } #[turbo_tasks::value] @@ -82,3 +101,61 @@ impl ResolvePlugin for UnsupportedModulesResolvePlugin { Ok(ResolveResultOption::none()) } } + +/// A resolver plugin tracks the usage of certain import paths, emit +/// telemetry events if there is a match. +#[turbo_tasks::value] +pub(crate) struct ModuleFeatureReportResolvePlugin { + root: Vc, + event_name: Vc, +} + +#[turbo_tasks::value_impl] +impl ModuleFeatureReportResolvePlugin { + #[turbo_tasks::function] + pub fn new(root: Vc, event_name: Vc) -> Vc { + ModuleFeatureReportResolvePlugin { root, event_name }.cell() + } +} + +#[turbo_tasks::value_impl] +impl ResolvePlugin for ModuleFeatureReportResolvePlugin { + #[turbo_tasks::function] + fn after_resolve_condition(&self) -> Vc { + ResolvePluginCondition::new(self.root.root(), Glob::new("**".to_string())) + } + + #[turbo_tasks::function] + async fn after_resolve( + &self, + _fs_path: Vc, + _context: Vc, + request: Vc, + ) -> Result> { + if let Request::Module { + module, + path, + query: _, + } = &*request.await? + { + let feature_module = FEATURE_MODULES.get(module.as_str()); + if let Some(feature_module) = feature_module { + let sub_path = feature_module + .iter() + .find(|sub_path| path.is_match(sub_path)); + + if let Some(sub_path) = sub_path { + ModuleFeatureTelemetry { + event_name: self.event_name.await?.to_string(), + feature_name: format!("{}{}", module, sub_path), + invocation_count: 1, + } + .cell() + .emit(); + } + } + } + + Ok(ResolveResultOption::none()) + } +} diff --git a/packages/next-swc/crates/next-core/src/next_telemetry.rs b/packages/next-swc/crates/next-core/src/next_telemetry.rs new file mode 100644 index 0000000000000..2057d5f611dcf --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_telemetry.rs @@ -0,0 +1,36 @@ +use std::collections::HashMap; + +use turbopack_binding::{ + turbo::tasks::Vc, + turbopack::core::diagnostics::{Diagnostic, DiagnosticPayload}, +}; + +/// A struct represent telemetry event for the feature usage, +/// referred as `importing` a certain module. (i.e importing @next/image) +#[turbo_tasks::value(shared)] +pub struct ModuleFeatureTelemetry { + pub event_name: String, + pub feature_name: String, + pub invocation_count: usize, +} + +#[turbo_tasks::value_impl] +impl Diagnostic for ModuleFeatureTelemetry { + #[turbo_tasks::function] + fn category(&self) -> Vc { + Vc::cell("ModuleFeatureTelemetry_category_tbd".to_string()) + } + + #[turbo_tasks::function] + fn name(&self) -> Vc { + Vc::cell("NEXT_BUILD_FEATURE_USAGE".to_string()) + } + + #[turbo_tasks::function] + fn payload(&self) -> Vc { + Vc::cell(HashMap::from([( + self.feature_name.clone(), + self.invocation_count.to_string(), + )])) + } +}