@lwrjs/module-bundler 0.10.0-alpha.9 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,11 +28,13 @@ __export(exports, {
28
28
  });
29
29
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
30
30
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
+ var import_path = __toModule(require("path"));
31
32
  var TASK_POOL = new import_shared_utils.TaskPool();
32
33
  var LwrModuleBundler = class {
33
34
  constructor(config, globalConfig) {
34
35
  this.cache = new Map();
35
36
  this.providers = [];
37
+ this.transformers = [];
36
38
  this.inflightBundleDefinitions = new import_shared_utils.InflightTasks();
37
39
  this.moduleRegistry = config.moduleRegistry;
38
40
  this.appObserver = config.appObserver;
@@ -44,6 +46,9 @@ var LwrModuleBundler = class {
44
46
  addBundleProviders(providers) {
45
47
  this.providers.push(...providers);
46
48
  }
49
+ addBundleTransformers(transformers) {
50
+ this.transformers.push(...transformers);
51
+ }
47
52
  async getModuleBundle(moduleId, runtimeEnvironment, runtimeParams = {}, bundleConfigOverrides) {
48
53
  const {format, minify, debug} = runtimeEnvironment;
49
54
  const cacheKey = `${moduleId.specifier}|${moduleId.version}|${(0, import_shared_utils.getCacheKeyFromJson)({
@@ -95,6 +100,18 @@ var LwrModuleBundler = class {
95
100
  }
96
101
  uri = String(await this.moduleRegistry.resolveModuleUri({...moduleId, version: resolvedVersion}, runtimeEnvironment, runtimeParams, signature));
97
102
  }
103
+ const bundleUri = {
104
+ artifactType: "bundle",
105
+ uri: (0, import_path.join)(runtimeEnvironment.basePath || "", uri),
106
+ immutable: runtimeEnvironment.immutableAssets,
107
+ entry: uri
108
+ };
109
+ for (const transformPlugin of this.transformers) {
110
+ const resolveUriResult = await transformPlugin.transformUri?.(bundleUri, bundleDefinition, runtimeEnvironment);
111
+ if (resolveUriResult && resolveUriResult.uri) {
112
+ uri = resolveUriResult.uri;
113
+ }
114
+ }
98
115
  return uri;
99
116
  }
100
117
  getPublicApi() {
@@ -32,7 +32,30 @@ var import_plugin_replace = __toModule(require("@rollup/plugin-replace"));
32
32
  var import_rollup_amd_bundler_plugin = __toModule(require("./rollup-amd-bundler-plugin.cjs"));
33
33
  var import_bundle_common = __toModule(require("./bundle-common.cjs"));
34
34
  var AMD_DEFINE = "LWR.define";
35
- async function bundle(id, moduleGraphs, minify = false) {
35
+ var groupieCodeCache = new Map();
36
+ function includeIdFactory(graphSpecifier, external, exclude = [], requiredImports, groups) {
37
+ return (moduleRef) => {
38
+ if (external[moduleRef.specifier] !== void 0) {
39
+ return false;
40
+ }
41
+ const moduleRefIsGroupie = (0, import_shared_utils.isGroupie)(moduleRef.specifier, groups);
42
+ const rootModuleIsGroupie = (0, import_shared_utils.isGroupie)(graphSpecifier, groups);
43
+ const moduleIsNotRoot = graphSpecifier !== moduleRef.specifier;
44
+ if (moduleRefIsGroupie) {
45
+ if (moduleIsNotRoot && !rootModuleIsGroupie) {
46
+ requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
47
+ }
48
+ return false;
49
+ } else if (exclude?.includes(moduleRef.specifier)) {
50
+ if (moduleIsNotRoot) {
51
+ requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
52
+ }
53
+ return false;
54
+ }
55
+ return true;
56
+ };
57
+ }
58
+ async function bundle(id, moduleGraphs, minify = false, unVersionedAliases = false) {
36
59
  const plugins = [(0, import_rollup_amd_bundler_plugin.bundleDefinitions)({moduleGraphs})];
37
60
  minify && plugins.push((0, import_plugin_replace.default)({
38
61
  "process.env.NODE_ENV": JSON.stringify("production"),
@@ -44,35 +67,36 @@ async function bundle(id, moduleGraphs, minify = false) {
44
67
  exports: "named",
45
68
  format: "amd"
46
69
  });
47
- return output[0].code;
70
+ let code = output[0].code;
71
+ if (unVersionedAliases) {
72
+ const idObject = (0, import_shared_utils.explodeSpecifier)(id);
73
+ const specifier = idObject.specifier;
74
+ const aliasModule = (0, import_shared_utils.createAmdAlias)(specifier, id);
75
+ code += aliasModule;
76
+ }
77
+ return code;
48
78
  }
49
- async function amdBundler(moduleId, moduleRegistry, minify = false, runtimeEnvironment, runtimeParams = {}, {bundleConfig}, bundleConfigOverrides) {
50
- const {exclude, external = {}} = (0, import_bundle_common.overrideBundleConfig)(bundleConfig, bundleConfigOverrides);
51
- const externalsArray = Object.keys(external);
52
- const requiredImports = new Map();
53
- const dynamicImports = new Map();
54
- const includedModules = [];
55
- const graphOptions = {
56
- includeLinkedDefinitions: true,
57
- depth: {
58
- static: import_shared_utils.GraphDepth.ALL,
59
- dynamic: 0,
60
- includeId: (moduleRef) => {
61
- if (externalsArray.includes(moduleRef.specifier)) {
62
- return false;
63
- } else if (exclude?.includes(moduleRef.specifier)) {
64
- requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
65
- return false;
79
+ async function getBundleCode(rootModule, moduleGraphs, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, unVersionedAliases, includeId, moduleRegistry, runtimeEnvironment, runtimeParams = {}, visitedSpecifiers) {
80
+ const modules = [rootModule, ...moduleGraphs.graphs[0].static];
81
+ const {moduleRecord} = await moduleRegistry.getModule((0, import_shared_utils.explodeSpecifier)(rootModule));
82
+ if (moduleRecord.importMeta) {
83
+ for (const specifier of modules) {
84
+ const linkedDefinition = moduleGraphs.linkedDefinitions[specifier];
85
+ const imports = linkedDefinition?.linkedModuleRecord.imports || [];
86
+ for (const imp of imports) {
87
+ const modId = (0, import_shared_utils.explodeSpecifier)(imp.specifier);
88
+ if (!modules.includes(imp.specifier) && includeId(modId)) {
89
+ modules.push(imp.specifier);
90
+ if (!moduleGraphs.linkedDefinitions[imp.specifier]) {
91
+ const missingLinkedModule = await moduleRegistry.getLinkedModule({specifier: modId.specifier, version: modId.version}, runtimeEnvironment, runtimeParams);
92
+ moduleGraphs.linkedDefinitions[imp.specifier] = missingLinkedModule;
93
+ }
66
94
  }
67
- return true;
68
95
  }
69
96
  }
70
- };
71
- const moduleGraphs = await (0, import_shared_utils.getModuleGraphs)(moduleId.specifier, graphOptions, moduleRegistry, moduleRegistry, runtimeEnvironment, runtimeParams);
72
- const rootModule = moduleGraphs.graphs[0];
73
- const modules = [rootModule.specifier, ...moduleGraphs.graphs[0].static];
74
- const bundles = await Promise.all(modules.reduce((filteredModules, specifier2) => {
75
- const linkedDefinition = moduleGraphs.linkedDefinitions[specifier2];
97
+ }
98
+ const bundles = (await Promise.all(modules.reduce((filteredModules, specifier) => {
99
+ const linkedDefinition = moduleGraphs.linkedDefinitions[specifier];
76
100
  if (!linkedDefinition) {
77
101
  return filteredModules;
78
102
  }
@@ -81,18 +105,82 @@ async function amdBundler(moduleId, moduleRegistry, minify = false, runtimeEnvir
81
105
  dynamicImports.set(`${dynamicImport.specifier}_${dynamicImport.version}`, dynamicImport);
82
106
  }
83
107
  });
84
- if (specifier2.includes("#")) {
108
+ if (specifier.includes("#")) {
85
109
  return filteredModules;
86
110
  }
87
111
  filteredModules.unshift(linkedDefinition);
88
112
  return filteredModules;
89
113
  }, []).map((linkedDefinition) => {
90
- const id2 = (0, import_shared_utils.getSpecifier)(linkedDefinition);
91
- if (id2 !== rootModule.specifier) {
92
- includedModules.push(id2);
114
+ const id = (0, import_shared_utils.getSpecifier)(linkedDefinition);
115
+ if (visitedSpecifiers?.has(id)) {
116
+ return false;
117
+ } else {
118
+ visitedSpecifiers?.set(id, true);
93
119
  }
94
- return bundle(id2, moduleGraphs, minify);
95
- }));
120
+ if (id !== rootModule) {
121
+ includedModules.push(id);
122
+ } else {
123
+ bundleGroupsIncludedModules.push(id);
124
+ }
125
+ return bundle(id, moduleGraphs, minify, unVersionedAliases);
126
+ }))).filter((x) => typeof x === "string");
127
+ return bundles;
128
+ }
129
+ async function amdBundler(rootModuleId, moduleRegistry, minify = false, runtimeEnvironment, runtimeParams = {}, {bundleConfig}, bundleConfigOverrides) {
130
+ const {exclude, external = {}, groups = {}} = (0, import_bundle_common.overrideBundleConfig)(bundleConfig, bundleConfigOverrides);
131
+ const requiredImports = new Map();
132
+ const dynamicImports = new Map();
133
+ const groupName = (0, import_shared_utils.getGroupName)(rootModuleId.specifier, groups);
134
+ const groupies = groupName && groups[groupName];
135
+ const cacheKey = (0, import_shared_utils.getCacheKeyFromJson)({groupName, exclude, external});
136
+ const cachedGroupieCode = groupName && groupieCodeCache.get(cacheKey);
137
+ const getModuleGraphsWrapper = (graphSpecifier) => {
138
+ const graphOptions = {
139
+ includeLinkedDefinitions: true,
140
+ depth: {
141
+ static: import_shared_utils.GraphDepth.ALL,
142
+ dynamic: 0,
143
+ includeId: includeIdFactory(graphSpecifier, external, exclude, requiredImports, groups)
144
+ }
145
+ };
146
+ return (0, import_shared_utils.getModuleGraphs)(graphSpecifier, graphOptions, moduleRegistry, moduleRegistry, runtimeEnvironment, runtimeParams);
147
+ };
148
+ const moduleGraphs = await getModuleGraphsWrapper(rootModuleId.specifier);
149
+ const rootModule = moduleGraphs.graphs[0];
150
+ const groupModuleGraphsMap = new Map();
151
+ if (!cachedGroupieCode && groupies && groupies.length) {
152
+ for (const specifier2 of groupies) {
153
+ if (specifier2 !== rootModuleId.specifier) {
154
+ const groupieModuleGraph = await getModuleGraphsWrapper(specifier2);
155
+ groupModuleGraphsMap.set(specifier2, groupieModuleGraph);
156
+ }
157
+ }
158
+ }
159
+ let bundleCode, includedModules, bundleGroupsIncludedModules;
160
+ const cachedBundleGroupCode = cachedGroupieCode;
161
+ const bundledSpecifiersMap = new Map();
162
+ if (!cachedBundleGroupCode) {
163
+ includedModules = [], bundleGroupsIncludedModules = [];
164
+ const bundles = await getBundleCode(rootModule.specifier, moduleGraphs, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, !!runtimeEnvironment.featureFlags?.EXPERIMENTAL_UNVERSIONED_ALIASES, includeIdFactory(rootModuleId.specifier, external, exclude, requiredImports, groups), moduleRegistry, runtimeEnvironment, runtimeParams, bundledSpecifiersMap);
165
+ if (groupName) {
166
+ for (const rawGroupieSpecifier of groupies) {
167
+ if (rawGroupieSpecifier !== rootModuleId.specifier) {
168
+ const groupieModuleGraph = groupModuleGraphsMap.get(rawGroupieSpecifier);
169
+ const groupieSpecifer = groupieModuleGraph.graphs[0].specifier;
170
+ const groupieBundles = await getBundleCode(groupieSpecifer, groupieModuleGraph, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, !!runtimeEnvironment.featureFlags?.EXPERIMENTAL_UNVERSIONED_ALIASES, includeIdFactory(rawGroupieSpecifier, external, exclude, requiredImports, groups), moduleRegistry, runtimeEnvironment, runtimeParams, bundledSpecifiersMap);
171
+ bundles.push(...groupieBundles);
172
+ }
173
+ }
174
+ }
175
+ bundleCode = bundles.join("");
176
+ if (groupName) {
177
+ includedModules.push(...bundleGroupsIncludedModules);
178
+ groupieCodeCache.set(groupName, {code: bundleCode, includedModules});
179
+ }
180
+ } else {
181
+ bundleCode = cachedBundleGroupCode.code;
182
+ includedModules = cachedBundleGroupCode.includedModules;
183
+ }
96
184
  const {id, name, namespace, version, specifier} = moduleGraphs.linkedDefinitions[rootModule.specifier];
97
185
  return {
98
186
  id,
@@ -100,7 +188,7 @@ async function amdBundler(moduleId, moduleRegistry, minify = false, runtimeEnvir
100
188
  namespace,
101
189
  version,
102
190
  specifier,
103
- code: bundles.join(""),
191
+ code: bundleCode,
104
192
  config: {external, exclude},
105
193
  bundleRecord: {
106
194
  imports: Array.from(requiredImports.values()),
@@ -1,4 +1,4 @@
1
- import { AbstractModuleId, BundleConfigOverrides, BundleDefinition, BundleProvider, ProviderAppConfig, ProviderContext, PublicModuleRegistry, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
1
+ import type { AbstractModuleId, BundleConfigOverrides, BundleDefinition, BundleProvider, ProviderAppConfig, ProviderContext, PublicModuleRegistry, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
2
2
  export default class AmdBundlerProvider implements BundleProvider {
3
3
  name: string;
4
4
  config: ProviderAppConfig;
@@ -1,4 +1,4 @@
1
- import { AbstractModuleId, BundleConfigOverrides, BundleDefinition, BundleProvider, ProviderAppConfig, ProviderContext, PublicModuleRegistry, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
1
+ import type { AbstractModuleId, BundleConfigOverrides, BundleDefinition, BundleProvider, ProviderAppConfig, ProviderContext, PublicModuleRegistry, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
2
2
  export default class AmdBundlerProvider implements BundleProvider {
3
3
  name: string;
4
4
  config: ProviderAppConfig;
@@ -1,4 +1,4 @@
1
- import { AbstractModuleId, BundleConfig, BundleConfigOverrides, BundleDefinition, BundleProvider, LwrAppObserver, ModuleBundler, ModuleId, ModuleRegistry, NormalizedLwrGlobalConfig, PublicModuleBundler, RuntimeEnvironment, RuntimeParams, SourceMapRuntimeEnvironment } from '@lwrjs/types';
1
+ import type { AbstractModuleId, BundleConfig, BundleConfigOverrides, BundleDefinition, BundleProvider, LwrAppObserver, ModuleBundler, ModuleId, ModuleRegistry, NormalizedLwrGlobalConfig, PublicModuleBundler, RuntimeEnvironment, RuntimeParams, SourceMapRuntimeEnvironment, UriTransformPlugin } from '@lwrjs/types';
2
2
  interface LwrModuleBundlerConfig {
3
3
  moduleRegistry: ModuleRegistry;
4
4
  appObserver?: LwrAppObserver;
@@ -8,10 +8,12 @@ export declare class LwrModuleBundler implements ModuleBundler {
8
8
  appObserver: LwrAppObserver | undefined;
9
9
  cache: Map<string, BundleDefinition>;
10
10
  providers: BundleProvider[];
11
+ transformers: UriTransformPlugin[];
11
12
  bundleConfig: BundleConfig;
12
13
  private inflightBundleDefinitions;
13
14
  constructor(config: LwrModuleBundlerConfig, globalConfig: NormalizedLwrGlobalConfig);
14
15
  addBundleProviders(providers: BundleProvider[]): void;
16
+ addBundleTransformers(transformers: UriTransformPlugin[]): void;
15
17
  getModuleBundle<T extends AbstractModuleId>(moduleId: T, runtimeEnvironment: SourceMapRuntimeEnvironment, runtimeParams?: RuntimeParams, bundleConfigOverrides?: BundleConfigOverrides): Promise<BundleDefinition>;
16
18
  /**
17
19
  * Resolve the URI to the bundle rooted at the `moduleId`
package/build/es/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { LwrUnresolvableError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
2
2
  import { getCacheKeyFromJson, InflightTasks, TaskPool } from '@lwrjs/shared-utils';
3
+ import { join } from 'path';
3
4
  const TASK_POOL = new TaskPool();
4
5
  export class LwrModuleBundler {
5
6
  constructor(config, globalConfig) {
6
7
  this.cache = new Map();
7
8
  this.providers = [];
9
+ this.transformers = [];
8
10
  // Pending bundle definitions are tracked to prevent concurrent resolution of the same bundle.
9
11
  // Subsequent requests for the same bundle will await the original promise.
10
12
  // Cache entries will be removed once the bundle is resolved.
@@ -22,6 +24,9 @@ export class LwrModuleBundler {
22
24
  addBundleProviders(providers) {
23
25
  this.providers.push(...providers);
24
26
  }
27
+ addBundleTransformers(transformers) {
28
+ this.transformers.push(...transformers);
29
+ }
25
30
  async getModuleBundle(moduleId, runtimeEnvironment, runtimeParams = {}, bundleConfigOverrides) {
26
31
  const { format, minify, debug } = runtimeEnvironment;
27
32
  const cacheKey = `${moduleId.specifier}|${moduleId.version}|${getCacheKeyFromJson({
@@ -85,13 +90,27 @@ export class LwrModuleBundler {
85
90
  }
86
91
  else {
87
92
  let resolvedVersion = moduleId.version || bundleDefinition.version;
88
- // If we do not know the verison, look it up.
93
+ // If we do not know the version, look it up.
89
94
  if (!resolvedVersion) {
90
95
  const { version } = await this.moduleRegistry.getModuleEntry(moduleId);
91
96
  resolvedVersion = version;
92
97
  }
93
98
  uri = String(await this.moduleRegistry.resolveModuleUri({ ...moduleId, version: resolvedVersion }, runtimeEnvironment, runtimeParams, signature));
94
99
  }
100
+ const bundleUri = {
101
+ artifactType: 'bundle',
102
+ uri: join(runtimeEnvironment.basePath || '', uri),
103
+ immutable: runtimeEnvironment.immutableAssets,
104
+ entry: uri,
105
+ };
106
+ // Perform any transforms
107
+ for (const transformPlugin of this.transformers) {
108
+ // eslint-disable-next-line no-await-in-loop
109
+ const resolveUriResult = await transformPlugin.transformUri?.(bundleUri, bundleDefinition, runtimeEnvironment);
110
+ if (resolveUriResult && resolveUriResult.uri) {
111
+ uri = resolveUriResult.uri;
112
+ }
113
+ }
95
114
  return uri;
96
115
  }
97
116
  getPublicApi() {
@@ -1,3 +1,3 @@
1
1
  import type { AbstractModuleId, BundleConfigOverrides, BundleDefinition, ModuleRegistry, ProviderAppConfig, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
2
- export declare function amdBundler(moduleId: AbstractModuleId, moduleRegistry: ModuleRegistry, minify: boolean | undefined, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams | undefined, { bundleConfig }: ProviderAppConfig, bundleConfigOverrides?: BundleConfigOverrides): Promise<BundleDefinition>;
2
+ export declare function amdBundler(rootModuleId: AbstractModuleId, moduleRegistry: ModuleRegistry, minify: boolean | undefined, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams | undefined, { bundleConfig }: ProviderAppConfig, bundleConfigOverrides?: BundleConfigOverrides): Promise<BundleDefinition>;
3
3
  //# sourceMappingURL=amd-common.d.ts.map
@@ -1,14 +1,46 @@
1
- import { GraphDepth, getModuleGraphs, getSpecifier } from '@lwrjs/shared-utils';
1
+ import { GraphDepth, createAmdAlias, explodeSpecifier, getModuleGraphs, getSpecifier, getGroupName, isGroupie, getCacheKeyFromJson, } from '@lwrjs/shared-utils';
2
2
  import { rollup } from 'rollup';
3
3
  import replace from '@rollup/plugin-replace';
4
4
  import { bundleDefinitions } from './rollup-amd-bundler-plugin.js';
5
5
  import { overrideBundleConfig } from './bundle-common.js';
6
6
  const AMD_DEFINE = 'LWR.define';
7
- async function bundle(id, moduleGraphs, minify = false) {
7
+ const groupieCodeCache = new Map();
8
+ function includeIdFactory(graphSpecifier, external, exclude = [], requiredImports, groups) {
9
+ return (moduleRef) => {
10
+ // Do not bundle externals, including the loader module, which is auto bundled
11
+ // with the shim + loader combo
12
+ if (external[moduleRef.specifier] !== undefined) {
13
+ // Do not include externals in the required imports but also return false to indicate it should not be in the bundle
14
+ return false;
15
+ }
16
+ const moduleRefIsGroupie = isGroupie(moduleRef.specifier, groups);
17
+ const rootModuleIsGroupie = isGroupie(graphSpecifier, groups);
18
+ const moduleIsNotRoot = graphSpecifier !== moduleRef.specifier;
19
+ if (moduleRefIsGroupie) {
20
+ // If this is part of bundle group return false to indicate it should not be in the bundle
21
+ // but add it to the requriedImports so it shows up as a static dependency of the bundle.
22
+ // However, skip this if the requested specifier is also part of the same group.
23
+ if (moduleIsNotRoot && !rootModuleIsGroupie) {
24
+ requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
25
+ }
26
+ return false;
27
+ }
28
+ else if (exclude?.includes(moduleRef.specifier)) {
29
+ // If this is a bundle exclude return false to indicate it should not be in the bundle
30
+ // but add it to the requriedImports so it shows up as a static dependency of the bundle.
31
+ if (moduleIsNotRoot) {
32
+ requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
33
+ }
34
+ return false;
35
+ }
36
+ return true;
37
+ };
38
+ }
39
+ async function bundle(id, moduleGraphs, minify = false, unVersionedAliases = false) {
8
40
  const plugins = [bundleDefinitions({ moduleGraphs })];
9
41
  minify &&
10
42
  plugins.push(
11
- // terser(), // Do not minify until needed for client modules. Server/SSR modules do not need to be minifed.
43
+ // terser(), // Do not minify until needed for client modules. Server/SSR modules do not need to be minified.
12
44
  replace({
13
45
  'process.env.NODE_ENV': JSON.stringify('production'),
14
46
  preventAssignment: false,
@@ -19,40 +51,39 @@ async function bundle(id, moduleGraphs, minify = false) {
19
51
  exports: 'named',
20
52
  format: 'amd',
21
53
  });
22
- return output[0].code;
54
+ let code = output[0].code;
55
+ if (unVersionedAliases) {
56
+ const idObject = explodeSpecifier(id);
57
+ const specifier = idObject.specifier;
58
+ const aliasModule = createAmdAlias(specifier, id);
59
+ code += aliasModule;
60
+ }
61
+ return code;
23
62
  }
24
- export async function amdBundler(moduleId, moduleRegistry, minify = false, runtimeEnvironment, runtimeParams = {}, { bundleConfig }, bundleConfigOverrides) {
25
- const { exclude, external = {} } = overrideBundleConfig(bundleConfig, bundleConfigOverrides);
26
- const externalsArray = Object.keys(external);
27
- const requiredImports = new Map();
28
- const dynamicImports = new Map();
29
- const includedModules = [];
30
- const graphOptions = {
31
- includeLinkedDefinitions: true,
32
- depth: {
33
- static: GraphDepth.ALL,
34
- dynamic: 0,
35
- includeId: (moduleRef) => {
36
- // Do not bundle externals, including the loader module, which is auto bundled
37
- // with the shim + loader combo
38
- if (externalsArray.includes(moduleRef.specifier)) {
39
- // Do not include externals in the required imports but also return false to indicate it should not be in the bundle
40
- return false;
41
- }
42
- else if (exclude?.includes(moduleRef.specifier)) {
43
- // If this is a bundle exclude return false to indicate it should not be in the bundle
44
- // but add it to the requriedImports so it shows up as a static dependency of the bundle.
45
- requiredImports.set(`${moduleRef.specifier}_${moduleRef.version}`, moduleRef);
46
- return false;
63
+ async function getBundleCode(rootModule, moduleGraphs, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, unVersionedAliases, includeId, moduleRegistry, runtimeEnvironment, runtimeParams = {}, visitedSpecifiers) {
64
+ const modules = [rootModule, ...moduleGraphs.graphs[0].static];
65
+ const { moduleRecord } = await moduleRegistry.getModule(explodeSpecifier(rootModule));
66
+ // add static imports from the LinkedModuleDefinitions added during module linking
67
+ // they're not in the ModuleGraph imports b/c those are based on raw module source
68
+ if (moduleRecord.importMeta) {
69
+ // the only use case for this is "lwr/environment", so skip the logic when it's not needed
70
+ for (const specifier of modules) {
71
+ const linkedDefinition = moduleGraphs.linkedDefinitions[specifier];
72
+ const imports = linkedDefinition?.linkedModuleRecord.imports || [];
73
+ for (const imp of imports) {
74
+ const modId = explodeSpecifier(imp.specifier);
75
+ if (!modules.includes(imp.specifier) && includeId(modId)) {
76
+ modules.push(imp.specifier);
77
+ if (!moduleGraphs.linkedDefinitions[imp.specifier]) {
78
+ // eslint-disable-next-line no-await-in-loop
79
+ const missingLinkedModule = await moduleRegistry.getLinkedModule({ specifier: modId.specifier, version: modId.version }, runtimeEnvironment, runtimeParams);
80
+ moduleGraphs.linkedDefinitions[imp.specifier] = missingLinkedModule;
81
+ }
47
82
  }
48
- return true;
49
- },
50
- },
51
- };
52
- const moduleGraphs = await getModuleGraphs(moduleId.specifier, graphOptions, moduleRegistry, moduleRegistry, runtimeEnvironment, runtimeParams);
53
- const rootModule = moduleGraphs.graphs[0];
54
- const modules = [rootModule.specifier, ...moduleGraphs.graphs[0].static];
55
- const bundles = await Promise.all(modules
83
+ }
84
+ }
85
+ }
86
+ const bundles = (await Promise.all(modules
56
87
  .reduce((filteredModules, specifier) => {
57
88
  const linkedDefinition = moduleGraphs.linkedDefinitions[specifier];
58
89
  // skip modules that do not have a linked definition
@@ -75,12 +106,88 @@ export async function amdBundler(moduleId, moduleRegistry, minify = false, runti
75
106
  }, [])
76
107
  .map((linkedDefinition) => {
77
108
  const id = getSpecifier(linkedDefinition);
78
- if (id !== rootModule.specifier) {
109
+ if (visitedSpecifiers?.has(id)) {
110
+ return false;
111
+ }
112
+ else {
113
+ visitedSpecifiers?.set(id, true);
114
+ }
115
+ if (id !== rootModule) {
79
116
  includedModules.push(id);
80
117
  }
118
+ else {
119
+ // we need to still keep track of roots for bundle groups
120
+ bundleGroupsIncludedModules.push(id);
121
+ }
81
122
  // bundle all dependencies for the linked definition and convert to AMD
82
- return bundle(id, moduleGraphs, minify);
83
- }));
123
+ return bundle(id, moduleGraphs, minify, unVersionedAliases);
124
+ }))).filter((x) => typeof x === 'string');
125
+ return bundles;
126
+ }
127
+ export async function amdBundler(rootModuleId, moduleRegistry, minify = false, runtimeEnvironment, runtimeParams = {}, { bundleConfig }, bundleConfigOverrides) {
128
+ const { exclude, external = {}, groups = {} } = overrideBundleConfig(bundleConfig, bundleConfigOverrides);
129
+ // Note: the maps must be cleared each time we call getModuleGraph
130
+ const requiredImports = new Map();
131
+ const dynamicImports = new Map();
132
+ const groupName = getGroupName(rootModuleId.specifier, groups);
133
+ const groupies = groupName && groups[groupName];
134
+ // Note: in reality, bundleConfig cannot change at runtime, but
135
+ // use it as a cacheKey anyways in case we want to support it in the future
136
+ const cacheKey = getCacheKeyFromJson({ groupName, exclude, external });
137
+ const cachedGroupieCode = groupName && groupieCodeCache.get(cacheKey);
138
+ const getModuleGraphsWrapper = (graphSpecifier) => {
139
+ const graphOptions = {
140
+ includeLinkedDefinitions: true,
141
+ depth: {
142
+ static: GraphDepth.ALL,
143
+ dynamic: 0,
144
+ includeId: includeIdFactory(graphSpecifier, external, exclude, requiredImports, groups),
145
+ },
146
+ };
147
+ return getModuleGraphs(graphSpecifier, graphOptions, moduleRegistry, moduleRegistry, runtimeEnvironment, runtimeParams);
148
+ };
149
+ const moduleGraphs = await getModuleGraphsWrapper(rootModuleId.specifier);
150
+ const rootModule = moduleGraphs.graphs[0];
151
+ // we also need to get moduleGraphs for any group members this module belongs to
152
+ const groupModuleGraphsMap = new Map();
153
+ if (!cachedGroupieCode && groupies && groupies.length) {
154
+ for (const specifier of groupies) {
155
+ if (specifier !== rootModuleId.specifier) {
156
+ // eslint-disable-next-line no-await-in-loop
157
+ const groupieModuleGraph = await getModuleGraphsWrapper(specifier);
158
+ groupModuleGraphsMap.set(specifier, groupieModuleGraph);
159
+ }
160
+ }
161
+ }
162
+ let bundleCode, includedModules, bundleGroupsIncludedModules;
163
+ // we don't need to recompute the bundle code if it already exists for this group
164
+ const cachedBundleGroupCode = cachedGroupieCode;
165
+ const bundledSpecifiersMap = new Map();
166
+ if (!cachedBundleGroupCode) {
167
+ (includedModules = []), (bundleGroupsIncludedModules = []);
168
+ const bundles = await getBundleCode(rootModule.specifier, moduleGraphs, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, !!runtimeEnvironment.featureFlags?.EXPERIMENTAL_UNVERSIONED_ALIASES, includeIdFactory(rootModuleId.specifier, external, exclude, requiredImports, groups), moduleRegistry, runtimeEnvironment, runtimeParams, bundledSpecifiersMap);
169
+ if (groupName) {
170
+ // add groupies to bundles
171
+ for (const rawGroupieSpecifier of groupies) {
172
+ if (rawGroupieSpecifier !== rootModuleId.specifier) {
173
+ const groupieModuleGraph = groupModuleGraphsMap.get(rawGroupieSpecifier);
174
+ const groupieSpecifer = groupieModuleGraph.graphs[0].specifier;
175
+ // eslint-disable-next-line no-await-in-loop
176
+ const groupieBundles = await getBundleCode(groupieSpecifer, groupieModuleGraph, includedModules, bundleGroupsIncludedModules, dynamicImports, minify, !!runtimeEnvironment.featureFlags?.EXPERIMENTAL_UNVERSIONED_ALIASES, includeIdFactory(rawGroupieSpecifier, external, exclude, requiredImports, groups), moduleRegistry, runtimeEnvironment, runtimeParams, bundledSpecifiersMap);
177
+ bundles.push(...groupieBundles);
178
+ }
179
+ }
180
+ }
181
+ bundleCode = bundles.join('');
182
+ if (groupName) {
183
+ includedModules.push(...bundleGroupsIncludedModules);
184
+ groupieCodeCache.set(groupName, { code: bundleCode, includedModules });
185
+ }
186
+ }
187
+ else {
188
+ bundleCode = cachedBundleGroupCode.code;
189
+ includedModules = cachedBundleGroupCode.includedModules;
190
+ }
84
191
  const { id, name, namespace, version, specifier } = moduleGraphs.linkedDefinitions[rootModule.specifier];
85
192
  return {
86
193
  id,
@@ -88,7 +195,7 @@ export async function amdBundler(moduleId, moduleRegistry, minify = false, runti
88
195
  namespace,
89
196
  version,
90
197
  specifier,
91
- code: bundles.join(''),
198
+ code: bundleCode,
92
199
  config: { external, exclude },
93
200
  bundleRecord: {
94
201
  imports: Array.from(requiredImports.values()),
@@ -1,5 +1,5 @@
1
- import { Plugin } from 'rollup';
2
- import { FlattenedModuleGraphs } from '@lwrjs/types';
1
+ import type { Plugin } from 'rollup';
2
+ import type { FlattenedModuleGraphs } from '@lwrjs/types';
3
3
  export interface RollupBundlePluginOptions {
4
4
  moduleGraphs: FlattenedModuleGraphs;
5
5
  }
@@ -1,5 +1,5 @@
1
- import { LinkedModuleDefinition, RuntimeEnvironment, ModuleRegistry, RuntimeParams, BaseModuleReference, BaseDynamicModuleReference } from '@lwrjs/types';
2
- import { Plugin } from 'rollup';
1
+ import type { LinkedModuleDefinition, RuntimeEnvironment, ModuleRegistry, RuntimeParams, BaseModuleReference, BaseDynamicModuleReference } from '@lwrjs/types';
2
+ import type { Plugin } from 'rollup';
3
3
  export interface RollupBundlePluginOptions {
4
4
  rootModuleDef: LinkedModuleDefinition;
5
5
  runtimeEnvironment: RuntimeEnvironment;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.10.0-alpha.9",
7
+ "version": "0.10.0",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -37,7 +37,9 @@
37
37
  }
38
38
  },
39
39
  "scripts": {
40
- "build": "tsc -b"
40
+ "build": "tsc -b",
41
+ "clean": "rm -rf build",
42
+ "test": "jest"
41
43
  },
42
44
  "files": [
43
45
  "build/**/*.js",
@@ -45,19 +47,24 @@
45
47
  "build/**/*.d.ts"
46
48
  ],
47
49
  "dependencies": {
48
- "@lwc/features": "2.45.2",
49
- "@lwrjs/shared-utils": "0.10.0-alpha.9",
50
+ "@lwc/features": "~2.50.0",
51
+ "@lwrjs/shared-utils": "0.10.0",
50
52
  "@rollup/plugin-replace": "^2.4.2",
51
53
  "rollup": "^2.78.0"
52
54
  },
53
55
  "devDependencies": {
54
- "@lwrjs/types": "0.10.0-alpha.9"
56
+ "@lwrjs/types": "0.10.0",
57
+ "jest": "^26.6.3",
58
+ "ts-jest": "^26.5.6"
55
59
  },
56
60
  "optionalDependencies": {
57
61
  "esbuild": "^0.9.7"
58
62
  },
59
63
  "engines": {
60
- "node": ">=16.0.0 <20"
64
+ "node": ">=16.0.0"
61
65
  },
62
- "gitHead": "6da48f5164ac881396055096a6c1e3d0f8d981aa"
66
+ "volta": {
67
+ "extends": "../../../package.json"
68
+ },
69
+ "gitHead": "e6deaeef3db8aa079acefed508897eca19b3218a"
63
70
  }