diff --git a/crates/mako/src/config/config.rs b/crates/mako/src/config/config.rs index 443f3f37c..e3a5d2fe0 100644 --- a/crates/mako/src/config/config.rs +++ b/crates/mako/src/config/config.rs @@ -122,6 +122,7 @@ pub struct OutputConfig { pub skip_write: bool, #[serde(deserialize_with = "deserialize_cross_origin_loading")] pub cross_origin_loading: Option, + pub global_module_registry: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] @@ -722,7 +723,8 @@ const DEFAULT_CONFIG: &str = r#" "preserveModules": false, "preserveModulesRoot": "", "skipWrite": false, - "crossOriginLoading": false + "crossOriginLoading": false, + "globalModuleRegistry": false, }, "resolve": { "alias": [], "extensions": ["js", "jsx", "ts", "tsx"] }, "mode": "development", diff --git a/crates/mako/src/generate/chunk_pot/util.rs b/crates/mako/src/generate/chunk_pot/util.rs index d4ff22554..11bf8148d 100644 --- a/crates/mako/src/generate/chunk_pot/util.rs +++ b/crates/mako/src/generate/chunk_pot/util.rs @@ -115,6 +115,7 @@ pub(crate) fn runtime_code(context: &Arc) -> Result { .optimization .as_ref() .map_or(false, |o| o.concatenate_modules.unwrap_or(false)), + global_module_registry: context.config.output.global_module_registry, }; let app_runtime = app_runtime.render_once()?; let app_runtime = app_runtime.replace( diff --git a/crates/mako/src/generate/runtime.rs b/crates/mako/src/generate/runtime.rs index f18c8589b..1a80cd306 100644 --- a/crates/mako/src/generate/runtime.rs +++ b/crates/mako/src/generate/runtime.rs @@ -12,4 +12,5 @@ pub struct AppRuntimeTemplate { pub is_browser: bool, pub concatenate_enabled: bool, pub cross_origin_loading: Option, + pub global_module_registry: bool, } diff --git a/crates/mako/templates/app_runtime.stpl b/crates/mako/templates/app_runtime.stpl index 7d2a870f0..e3b00e912 100644 --- a/crates/mako/templates/app_runtime.stpl +++ b/crates/mako/templates/app_runtime.stpl @@ -1,5 +1,11 @@ function createRuntime(makoModules, entryModuleId, global) { +<% if global_module_registry { %> + var modulesRegistry = ( + (typeof globalThis !== "undefined" ? globalThis : self).__mako_module_registry = + ((typeof globalThis !== "undefined" ? globalThis : self).__mako_module_registry || {})); +<% } else { %> var modulesRegistry = {}; +<% } %> function requireModule(moduleId) { var cachedModule = modulesRegistry[moduleId]; diff --git a/docs/config.md b/docs/config.md index 2a2cab624..a29061414 100644 --- a/docs/config.md +++ b/docs/config.md @@ -484,6 +484,7 @@ Output related configuration. - `preserveModules`, whether to preserve the module directory structure (Bundless Only) - `preserveModulesRoot`, preserve the root directory of the module directory structure (Bundless Only) - `crossOriginLoading`, control the `crossorigin` attribute of the `script` tag and `link` tag for load async chunks +- `globalModuleRegistry`, whether enable shared module registry across multi entries ### optimization diff --git a/docs/config.zh-CN.md b/docs/config.zh-CN.md index 261dd42f1..819f92a78 100644 --- a/docs/config.zh-CN.md +++ b/docs/config.zh-CN.md @@ -485,6 +485,7 @@ e.g. - `preserveModules`,是否保留模块目录结构(仅适用于 Bundless) - `preserveModulesRoot`,是否保留模块目录结构的根目录(仅限 Bundless) - `crossOriginLoading`,控制异步 chunk 加载时 `script` 及 `link` 标签的 `crossorigin` 属性值 +- `globalModuleRegistry`,是否允许在多 entry 之间共享模块注册中心 ### optimization diff --git a/e2e/fixtures/config.global-module-registry/expect.js b/e2e/fixtures/config.global-module-registry/expect.js new file mode 100644 index 000000000..67207a25f --- /dev/null +++ b/e2e/fixtures/config.global-module-registry/expect.js @@ -0,0 +1,4 @@ +const assert = require("assert"); + +require('./dist/common'); +assert(require('./dist/A').common === require('./dist/B').common, 'global module registry should work'); diff --git a/e2e/fixtures/config.global-module-registry/mako.config.json b/e2e/fixtures/config.global-module-registry/mako.config.json new file mode 100644 index 000000000..222ecfe19 --- /dev/null +++ b/e2e/fixtures/config.global-module-registry/mako.config.json @@ -0,0 +1,25 @@ +{ +"entry": { + "A": "./src/entryA.ts", + "B": "./src/entryB.ts" + }, + "minify": false, + "platform": "node", + "cjs": true, + "codeSplitting": { + "strategy": "advanced", + "options": { + "groups": [ + { + "name": "common", + "allowChunks": "all", + "minSize": 1, + "minChunks": 2 + } + ] + } + }, + "output": { + "globalModuleRegistry": true + } +} diff --git a/e2e/fixtures/config.global-module-registry/src/common.ts b/e2e/fixtures/config.global-module-registry/src/common.ts new file mode 100644 index 000000000..71090afa0 --- /dev/null +++ b/e2e/fixtures/config.global-module-registry/src/common.ts @@ -0,0 +1,3 @@ +export const common = { + value: 1 +} diff --git a/e2e/fixtures/config.global-module-registry/src/entryA.ts b/e2e/fixtures/config.global-module-registry/src/entryA.ts new file mode 100644 index 000000000..1cbd0c274 --- /dev/null +++ b/e2e/fixtures/config.global-module-registry/src/entryA.ts @@ -0,0 +1,2 @@ +export { common } from "./common"; + diff --git a/e2e/fixtures/config.global-module-registry/src/entryB.ts b/e2e/fixtures/config.global-module-registry/src/entryB.ts new file mode 100644 index 000000000..1cbd0c274 --- /dev/null +++ b/e2e/fixtures/config.global-module-registry/src/entryB.ts @@ -0,0 +1,2 @@ +export { common } from "./common"; +