Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add module id strategy option to next config #69319

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions crates/next-api/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use next_core::{
middleware::middleware_files,
mode::NextMode,
next_client::{get_client_chunking_context, get_client_compile_time_info},
next_config::{JsConfig, NextConfig},
next_config::{JsConfig, ModuleIdStrategy as ModuleIdStrategyConfig, NextConfig},
next_server::{
get_server_chunking_context, get_server_chunking_context_with_client_assets,
get_server_compile_time_info, get_server_module_options_context,
Expand Down Expand Up @@ -1184,14 +1184,19 @@ impl Project {
Ok(Vc::cell(modules))
}

/// Get the module id strategy for the project.
/// In production mode, we use the global module id strategy with optimized ids.
/// In development mode, we use a standard module id strategy with no modifications.
/// Gets the module id strategy for the project.
#[turbo_tasks::function]
pub async fn module_id_strategy(self: Vc<Self>) -> Result<Vc<Box<dyn ModuleIdStrategy>>> {
match *self.next_mode().await? {
NextMode::Build => Ok(Vc::upcast(GlobalModuleIdStrategyBuilder::build(self))),
NextMode::Development => Ok(Vc::upcast(DevModuleIdStrategy::new())),
let module_id_strategy = self.next_config().module_id_strategy_config();
match *module_id_strategy.await? {
Some(ModuleIdStrategyConfig::Named) => Ok(Vc::upcast(DevModuleIdStrategy::new())),
Some(ModuleIdStrategyConfig::Deterministic) => {
Ok(Vc::upcast(GlobalModuleIdStrategyBuilder::build(self)))
}
None => match *self.next_mode().await? {
NextMode::Development => Ok(Vc::upcast(DevModuleIdStrategy::new())),
NextMode::Build => Ok(Vc::upcast(GlobalModuleIdStrategyBuilder::build(self))),
},
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ pub struct ExperimentalTurboConfig {
pub resolve_extensions: Option<Vec<RcStr>>,
pub use_swc_css: Option<bool>,
pub tree_shaking: Option<bool>,
pub module_id_strategy: Option<ModuleIdStrategy>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)]
Expand Down Expand Up @@ -432,6 +433,17 @@ pub enum LoaderItem {
LoaderOptions(WebpackLoaderItem),
}

#[turbo_tasks::value]
#[derive(Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub enum ModuleIdStrategy {
Named,
Deterministic,
}

#[turbo_tasks::value(transparent)]
pub struct OptionModuleIdStrategy(pub Option<ModuleIdStrategy>);

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)]
#[serde(untagged)]
pub enum MdxRsOptions {
Expand Down Expand Up @@ -1132,6 +1144,20 @@ impl NextConfig {
) -> Result<Vc<OptionTreeShaking>> {
Ok(Vc::cell(Some(TreeShakingMode::ReexportsOnly)))
}

#[turbo_tasks::function]
pub async fn module_id_strategy_config(self: Vc<Self>) -> Result<Vc<OptionModuleIdStrategy>> {
let this = self.await?;
let Some(module_id_strategy) = this
.experimental
.turbo
.as_ref()
.and_then(|t| t.module_id_strategy.as_ref())
else {
return Ok(Vc::cell(None));
};
Ok(Vc::cell(Some(module_id_strategy.clone())))
}
}

/// A subset of ts/jsconfig that next.js implicitly
Expand Down
22 changes: 22 additions & 0 deletions docs/02-app/02-api-reference/05-next-config-js/turbo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,25 @@ module.exports = {
This overwrites the original resolve extensions with the provided list. Make sure to include the default extensions.

For more information and guidance for how to migrate your app to Turbopack from webpack, see [Turbopack's documentation on webpack compatibility](https://turbo.build/pack/docs/migrating-from-webpack).

## Module ID strategy

Turbopack currently supports two strategies for assigning module IDs: `'named'` and `'deterministic'`.

`'named'` assigns readable module IDs based on the module's path and functionality.

`'deterministic'` assigns small hashed numeric module IDs, which are mostly consistent between builds and therefore help with long-term caching.

If not set, Turbopack will use `'named'` for development builds and `'deterministic'` for production builds.

To configure the module IDs strategy, use the `moduleIdStrategy` field in `next.config.js`:

```js filename="next.config.js"
module.exports = {
experimental: {
turbo: {
moduleIdStrategy: 'deterministic',
},
},
}
```
1 change: 1 addition & 0 deletions packages/next/src/server/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ export const configSchema: zod.ZodType<NextConfig> = z.lazy(() =>
useSwcCss: z.boolean().optional(),
treeShaking: z.boolean().optional(),
memoryLimit: z.number().optional(),
moduleIdStrategy: z.enum(['named', 'deterministic']).optional(),
})
.optional(),
optimizePackageImports: z.array(z.string()).optional(),
Expand Down
7 changes: 7 additions & 0 deletions packages/next/src/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ export interface ExperimentalTurboOptions {
* Enable tree shaking for the turbopack dev server and build.
*/
treeShaking?: boolean

/**
* The module ID strategy to use for Turbopack.
* If not set, the default is `'named'` for development and `'deterministic'`
* for production.
*/
moduleIdStrategy?: 'named' | 'deterministic'
}

export interface WebpackConfigContext {
Expand Down
Loading