@lwrjs/view-registry 0.9.0-alpha.27 → 0.9.0-alpha.29

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.
@@ -293,7 +293,8 @@ var LwrViewRegistry = class {
293
293
  moduleBundler,
294
294
  resourceRegistry,
295
295
  runtimeEnvironment,
296
- runtimeParams
296
+ runtimeParams,
297
+ bundleConfig: this.globalConfig.bundleConfig
297
298
  });
298
299
  return {
299
300
  renderedView: linkedView,
@@ -37,9 +37,20 @@ async function getHtmlResources(view, viewParams, resourceContext) {
37
37
  moduleRegistry,
38
38
  moduleBundler,
39
39
  resourceRegistry,
40
- viewMetadata
40
+ viewMetadata,
41
+ bundleConfig: {external = {}}
41
42
  } = resourceContext;
42
- const {id: appName, bootstrap: {services, module: bootstrapModule} = {services: []}} = view;
43
+ const isExternal = function(rawSpecifier) {
44
+ const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
45
+ return Object.keys(external).some((e) => specifier === e);
46
+ };
47
+ const {
48
+ id: appName,
49
+ bootstrap: {services, module: bootstrapModule, preloadModules = []} = {
50
+ services: [],
51
+ preloadModules: []
52
+ }
53
+ } = view;
43
54
  const {lwrVersion, format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
44
55
  const {customElements} = viewMetadata;
45
56
  const version = lwrVersion;
@@ -50,6 +61,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
50
61
  resourceType: import_identity.AppResourceEnum.MODULE
51
62
  };
52
63
  const bootstrapSpecifier = bootstrapModule || (0, import_identity.getAppSpecifier)(appIdentity);
64
+ const preloadModuleUris = new Set();
53
65
  const moduleResources = [];
54
66
  const requiredResources = [];
55
67
  const configResources = [];
@@ -60,7 +72,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
60
72
  const preloadAmdModules = [];
61
73
  const isSSR = view.bootstrap?.ssr;
62
74
  if (isAMD) {
63
- const shimBundle = !bundle ? "lwr-loader-shim-legacy.js" : debug || minify === false ? "lwr-loader-shim-legacy.bundle.js" : "lwr-loader-shim-legacy.bundle.min.js";
75
+ const shimBundle = debug || minify === false ? "lwr-loader-shim-legacy.bundle.js" : "lwr-loader-shim-legacy.bundle.min.js";
64
76
  const def = await resourceRegistry.getResource({specifier: shimBundle, version}, runtimeEnvironment, runtimeParams);
65
77
  if (!def) {
66
78
  throw Error("Failed to find definition of resource: " + shimBundle);
@@ -71,21 +83,33 @@ async function getHtmlResources(view, viewParams, resourceContext) {
71
83
  throw Error("Failed to find definition of resource: lwr-error-shim.js");
72
84
  }
73
85
  requiredResources.push(errorShimDef);
74
- if (!bundle) {
75
- requiredResources.push(await (0, import_utils.getModuleResource)({
76
- specifier: "lwr/loaderLegacy",
77
- version
78
- }, runtimeEnvironment, {
79
- isPreload: false,
80
- isSSR
81
- }, moduleRegistry, runtimeParams));
82
- }
83
86
  }
84
87
  const depth = isAMD ? {static: import_shared_utils.GraphDepth.ALL, dynamic: 1} : {static: import_shared_utils.GraphDepth.NONE, dynamic: 0};
85
88
  const bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams, visitedCache);
86
89
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
87
90
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
88
91
  moduleResources.push((0, import_utils.getModuleResourceByUri)(uri, runtimeEnvironment, {isPreload: false, isSSR}));
92
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
93
+ if (!isExternal(depSpecifier)) {
94
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
95
+ preloadAmdModules.push(depSpecifier);
96
+ }
97
+ }
98
+ for (let i = 0; i < preloadModules.length; i++) {
99
+ const specifier = preloadModules[i];
100
+ if (isExternal(specifier)) {
101
+ import_shared_utils.logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
102
+ } else {
103
+ const versionedModuleId = await (0, import_shared_utils.getVersionedModuleId)(specifier, moduleRegistry);
104
+ const versionedModuleSpecifier = (0, import_shared_utils.getSpecifier)({
105
+ specifier,
106
+ version: (0, import_shared_utils.normalizeVersionToUri)(versionedModuleId.version)
107
+ });
108
+ const uri2 = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] || await moduleRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams);
109
+ preloadModuleUris.add(uri2);
110
+ preloadAmdModules.push(versionedModuleSpecifier);
111
+ }
112
+ }
89
113
  if (isAMD) {
90
114
  requiredAmdModules.push(versionedSpecifier);
91
115
  imports[versionedSpecifier] = uri;
@@ -93,7 +117,6 @@ async function getHtmlResources(view, viewParams, resourceContext) {
93
117
  const uri2 = bootstrapModuleGraph.uriMap[staticDep];
94
118
  imports[staticDep] = uri2;
95
119
  if (services && services.length) {
96
- moduleResources.push((0, import_utils.getModuleResourceByUri)(uri2, runtimeEnvironment, {isPreload: true, isSSR}));
97
120
  requiredAmdModules.push(staticDep);
98
121
  }
99
122
  }
@@ -114,6 +137,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
114
137
  const specifier = graph.graphs[0].specifier;
115
138
  const uri2 = graph.uriMap[specifier];
116
139
  moduleResources.push((0, import_utils.getModuleResourceByUri)(uri2, runtimeEnvironment, {isPreload: true, isSSR}));
140
+ if (bundle) {
141
+ for (const depSpecifier of graph.graphs[0].static) {
142
+ if (!isExternal(depSpecifier)) {
143
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
144
+ preloadAmdModules.push(depSpecifier);
145
+ }
146
+ }
147
+ }
117
148
  rootComponents.push(specifier);
118
149
  imports[specifier] = uri2;
119
150
  if (isAMD) {
@@ -128,6 +159,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
128
159
  }
129
160
  }
130
161
  }));
162
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
131
163
  configResources.unshift(await (0, import_utils2.getViewBootstrapConfigurationResource)({
132
164
  id: view.id,
133
165
  url: viewParams?.page?.url,
@@ -142,11 +174,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
142
174
  },
143
175
  rootComponents,
144
176
  ...isAMD && {requiredModules: requiredAmdModules},
145
- ...isAMD && {preloadModules: preloadAmdModules}
177
+ ...isAMD && {preloadModules: dedupedPreloadAmdModules}
146
178
  }, runtimeEnvironment, runtimeParams));
147
179
  if (!isAMD && hmrEnabled) {
148
180
  configResources.unshift(await (0, import_utils2.getViewHmrConfigurationResource)(view, viewMetadata));
149
181
  }
182
+ for (const preloadUri of preloadModuleUris) {
183
+ moduleResources.unshift((0, import_utils.getModuleResourceByUri)(preloadUri, runtimeEnvironment, {isPreload: true, isSSR}));
184
+ }
150
185
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(import_utils.generateHtmlTag));
151
186
  return {
152
187
  partial: htmlResources.join("\n"),
@@ -37,9 +37,20 @@ async function getHtmlResources(view, viewParams, resourceContext) {
37
37
  moduleRegistry,
38
38
  moduleBundler,
39
39
  resourceRegistry,
40
- viewMetadata
40
+ viewMetadata,
41
+ bundleConfig: {external = {}}
41
42
  } = resourceContext;
42
- const {id: appName, bootstrap: {services, module: bootstrapModule} = {services: []}} = view;
43
+ const isExternal = function(rawSpecifier) {
44
+ const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
45
+ return Object.keys(external).some((e) => specifier === e);
46
+ };
47
+ const {
48
+ id: appName,
49
+ bootstrap: {services, module: bootstrapModule, preloadModules = []} = {
50
+ services: [],
51
+ preloadModules: []
52
+ }
53
+ } = view;
43
54
  const {lwrVersion, format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
44
55
  const {customElements} = viewMetadata;
45
56
  const defRegistry = bundle ? moduleBundler : moduleRegistry;
@@ -51,6 +62,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
51
62
  resourceType: import_identity.AppResourceEnum.MODULE
52
63
  };
53
64
  const bootstrapSpecifier = bootstrapModule || (0, import_identity.getAppSpecifier)(appIdentity);
65
+ const preloadModuleUris = new Set();
54
66
  const moduleResources = [];
55
67
  const requiredResources = [];
56
68
  const configResources = [];
@@ -61,7 +73,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
61
73
  const preloadAmdModules = [];
62
74
  const isSSR = view.bootstrap?.ssr;
63
75
  if (isAMD) {
64
- const shimBundle = !bundle ? "lwr-loader-shim.js" : debug || minify === false ? "lwr-loader-shim.bundle.js" : "lwr-loader-shim.bundle.min.js";
76
+ const shimBundle = debug || minify === false ? "lwr-loader-shim.bundle.js" : "lwr-loader-shim.bundle.min.js";
65
77
  const def = await resourceRegistry.getResource({specifier: shimBundle, version}, runtimeEnvironment, runtimeParams);
66
78
  if (!def) {
67
79
  throw Error("Failed to find definition of resource: " + shimBundle);
@@ -72,20 +84,33 @@ async function getHtmlResources(view, viewParams, resourceContext) {
72
84
  throw Error("Failed to find definition of resource: lwr-error-shim.js");
73
85
  }
74
86
  requiredResources.push(errorShimDef);
75
- if (!bundle) {
76
- requiredResources.push(await (0, import_utils.getModuleResource)({
77
- specifier: "lwr/loader",
78
- version
79
- }, runtimeEnvironment, {
80
- isSSR
81
- }, moduleRegistry, runtimeParams));
82
- }
83
87
  }
84
88
  const depth = isAMD ? {static: import_shared_utils.GraphDepth.ALL, dynamic: 1} : {static: import_shared_utils.GraphDepth.NONE, dynamic: 1};
85
89
  const bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
86
90
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
87
91
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
88
92
  moduleResources.push((0, import_utils.getModuleResourceByUri)(uri, runtimeEnvironment, {isPreload: false, isSSR}));
93
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
94
+ if (!isExternal(depSpecifier)) {
95
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
96
+ preloadAmdModules.push(depSpecifier);
97
+ }
98
+ }
99
+ for (let i = 0; i < preloadModules.length; i++) {
100
+ const specifier = preloadModules[i];
101
+ if (isExternal(specifier)) {
102
+ import_shared_utils.logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
103
+ } else {
104
+ const versionedModuleId = await (0, import_shared_utils.getVersionedModuleId)(specifier, moduleRegistry);
105
+ const versionedModuleSpecifier = (0, import_shared_utils.getSpecifier)({
106
+ specifier,
107
+ version: (0, import_shared_utils.normalizeVersionToUri)(versionedModuleId.version)
108
+ });
109
+ const uri2 = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] || await moduleRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams);
110
+ preloadModuleUris.add(uri2);
111
+ preloadAmdModules.push(versionedModuleSpecifier);
112
+ }
113
+ }
89
114
  if (isAMD) {
90
115
  requiredAmdModules.push(versionedSpecifier);
91
116
  imports[versionedSpecifier] = uri;
@@ -93,7 +118,6 @@ async function getHtmlResources(view, viewParams, resourceContext) {
93
118
  const uri2 = bootstrapModuleGraph.uriMap[staticDep];
94
119
  imports[staticDep] = uri2;
95
120
  if (services && services.length) {
96
- moduleResources.push((0, import_utils.getModuleResourceByUri)(uri2, runtimeEnvironment, {isPreload: true, isSSR}));
97
121
  requiredAmdModules.push(staticDep);
98
122
  }
99
123
  }
@@ -115,6 +139,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
115
139
  const specifier = graph.graphs[0].specifier;
116
140
  const uri2 = graph.uriMap[specifier];
117
141
  moduleResources.push((0, import_utils.getModuleResourceByUri)(uri2, runtimeEnvironment, {isPreload: true, isSSR}));
142
+ if (bundle) {
143
+ for (const depSpecifier of graph.graphs[0].static) {
144
+ if (!isExternal(depSpecifier)) {
145
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
146
+ preloadAmdModules.push(depSpecifier);
147
+ }
148
+ }
149
+ }
118
150
  rootComponents.push(specifier);
119
151
  imports[specifier] = uri2;
120
152
  if (isAMD) {
@@ -130,6 +162,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
130
162
  }
131
163
  importMetadata = await (0, import_shared_utils.toImportMetadata)(graph, importMetadata, moduleRegistry, runtimeEnvironment, runtimeParams);
132
164
  }
165
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
133
166
  configResources.unshift(await (0, import_utils2.getViewBootstrapConfigurationResource)({
134
167
  id: view.id,
135
168
  url: viewParams?.page?.url,
@@ -142,11 +175,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
142
175
  index: importMetadata?.index,
143
176
  rootComponents,
144
177
  ...isAMD && {requiredModules: requiredAmdModules},
145
- ...isAMD && {preloadModules: preloadAmdModules}
178
+ ...isAMD && {preloadModules: dedupedPreloadAmdModules}
146
179
  }, runtimeEnvironment, runtimeParams));
147
180
  if (!isAMD && hmrEnabled) {
148
181
  configResources.unshift(await (0, import_utils2.getViewHmrConfigurationResource)(view, viewMetadata));
149
182
  }
183
+ for (const preloadUri of preloadModuleUris) {
184
+ moduleResources.unshift((0, import_utils.getModuleResourceByUri)(preloadUri, runtimeEnvironment, {isPreload: true, isSSR}));
185
+ }
150
186
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(import_utils.generateHtmlTag));
151
187
  const mapping = (0, import_shared_utils.getMappingUriPrefix)(runtimeEnvironment, runtimeParams);
152
188
  const endpoints = {
package/build/es/index.js CHANGED
@@ -316,6 +316,7 @@ export class LwrViewRegistry {
316
316
  resourceRegistry,
317
317
  runtimeEnvironment,
318
318
  runtimeParams,
319
+ bundleConfig: this.globalConfig.bundleConfig,
319
320
  });
320
321
  return {
321
322
  // ...viewDefinition,
@@ -1,4 +1,4 @@
1
- import { ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ViewParams, ModuleBundler } from '@lwrjs/types';
1
+ import { BundleConfig, ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ViewParams, ModuleBundler } from '@lwrjs/types';
2
2
  export interface LwrResourcesLinkedContext extends ResourceContext {
3
3
  lwrResourcesId: string;
4
4
  }
@@ -9,6 +9,7 @@ interface ResourceContext {
9
9
  moduleRegistry: ModuleRegistry;
10
10
  moduleBundler: ModuleBundler;
11
11
  resourceRegistry: ResourceRegistry;
12
+ bundleConfig: BundleConfig;
12
13
  }
13
14
  export declare function getHtmlResources(view: View, viewParams: ViewParams, resourceContext: ResourceContext): Promise<{
14
15
  partial: string;
@@ -1,10 +1,17 @@
1
- import { kebabCaseToModuleSpecifier, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, getVersionedModuleId, explodeSpecifier, getSpecifier, normalizeVersionToUri, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
4
  import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
- const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services, module: bootstrapModule } = { services: [] } } = view;
6
+ const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, bundleConfig: { external = {} }, } = resourceContext;
7
+ const isExternal = function (rawSpecifier) {
8
+ const { specifier } = explodeSpecifier(rawSpecifier);
9
+ return Object.keys(external).some((e) => specifier === e);
10
+ };
11
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
12
+ services: [],
13
+ preloadModules: [],
14
+ }, } = view;
8
15
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
16
  const { customElements } = viewMetadata;
10
17
  const version = lwrVersion;
@@ -21,6 +28,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
21
28
  /*
22
29
  Internal module and module dependency related resources used by the view to render view related components.
23
30
  */
31
+ const preloadModuleUris = new Set();
24
32
  const moduleResources = [];
25
33
  /*
26
34
  External resources that the view depends. These resources include ones that an ViewDefinition client are required to load
@@ -39,18 +47,17 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
39
47
  const rootComponents = [];
40
48
  // Collection of modules specifiers that MUST be loaded in the view
41
49
  const requiredAmdModules = [];
42
- // Collection of modules that will be loaded in the view
50
+ // Collection of modules that will be preloaded. For AMD, it will be part of
51
+ // the preloadModules client bootstrap config
43
52
  const preloadAmdModules = [];
44
53
  // Determine if server side rendering view modules
45
54
  const isSSR = view.bootstrap?.ssr;
46
55
  // ------ AMD Required module resources
47
56
  if (isAMD) {
48
57
  // Keep shim format in sync with view_bootstrap.ts
49
- const shimBundle = !bundle
50
- ? 'lwr-loader-shim-legacy.js'
51
- : debug || minify === false
52
- ? 'lwr-loader-shim-legacy.bundle.js'
53
- : 'lwr-loader-shim-legacy.bundle.min.js';
58
+ const shimBundle = debug || minify === false
59
+ ? 'lwr-loader-shim-legacy.bundle.js'
60
+ : 'lwr-loader-shim-legacy.bundle.min.js';
54
61
  const def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
55
62
  if (!def) {
56
63
  throw Error('Failed to find definition of resource: ' + shimBundle);
@@ -62,17 +69,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
62
69
  throw Error('Failed to find definition of resource: lwr-error-shim.js');
63
70
  }
64
71
  requiredResources.push(errorShimDef);
65
- // Add loader, if not already bundled with the shim
66
- if (!bundle) {
67
- // needed because we're resolving against fully-linked modules
68
- requiredResources.push(await getModuleResource({
69
- specifier: 'lwr/loaderLegacy',
70
- version,
71
- }, runtimeEnvironment, {
72
- isPreload: false,
73
- isSSR,
74
- }, moduleRegistry, runtimeParams));
75
- }
76
72
  }
77
73
  // ------- Application Bootstrap module
78
74
  // Traversal of the Bootstrap Module Graph is done to get all the URLS for discoverable static dependencies.
@@ -86,6 +82,35 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
86
82
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
87
83
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
88
84
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
85
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
86
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
87
+ if (!isExternal(depSpecifier)) {
88
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
89
+ // in AMD, we also need to tell the loader it's being preloaded
90
+ preloadAmdModules.push(depSpecifier);
91
+ }
92
+ }
93
+ // PRELOAD configured preloadModules as preloaded script resources
94
+ for (let i = 0; i < preloadModules.length; i++) {
95
+ const specifier = preloadModules[i];
96
+ if (isExternal(specifier)) {
97
+ logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
98
+ }
99
+ else {
100
+ // eslint-disable-next-line no-await-in-loop
101
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry);
102
+ const versionedModuleSpecifier = getSpecifier({
103
+ specifier,
104
+ version: normalizeVersionToUri(versionedModuleId.version),
105
+ });
106
+ const uri = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] ||
107
+ // eslint-disable-next-line no-await-in-loop
108
+ (await moduleRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams));
109
+ preloadModuleUris.add(uri);
110
+ // in AMD, we also need to tell the loader it's being preloaded
111
+ preloadAmdModules.push(versionedModuleSpecifier);
112
+ }
113
+ }
89
114
  if (isAMD) {
90
115
  // ADD bootstrap module as required
91
116
  requiredAmdModules.push(versionedSpecifier);
@@ -98,8 +123,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
98
123
  imports[staticDep] = uri;
99
124
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
100
125
  if (services && services.length) {
101
- // get the graphs for the bs static deps
102
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
103
126
  requiredAmdModules.push(staticDep);
104
127
  }
105
128
  }
@@ -121,10 +144,20 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
121
144
  const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
122
145
  // add to the viewRecord
123
146
  customElementsRecords.push({ elementName: element, flatGraph: graph });
124
- // PRELOAD custom element static deps as link resource
147
+ // PRELOAD the custom element module as a link resource
125
148
  const specifier = graph.graphs[0].specifier;
126
149
  const uri = graph.uriMap[specifier];
127
150
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
151
+ // PRELOAD custom element static deps as link resources when bundling is ON
152
+ if (bundle) {
153
+ for (const depSpecifier of graph.graphs[0].static) {
154
+ if (!isExternal(depSpecifier)) {
155
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
156
+ // in AMD, we also need to tell the loader it's being preloaded
157
+ preloadAmdModules.push(depSpecifier);
158
+ }
159
+ }
160
+ }
128
161
  // ADD register custom elements as a uri addressable rootComponents
129
162
  rootComponents.push(specifier);
130
163
  imports[specifier] = uri;
@@ -142,6 +175,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
142
175
  }
143
176
  }
144
177
  }));
178
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
145
179
  // ADD configuration of the bootstrapModule
146
180
  configResources.unshift(await getViewBootstrapConfigurationResource({
147
181
  id: view.id,
@@ -157,11 +191,15 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
157
191
  },
158
192
  rootComponents,
159
193
  ...(isAMD && { requiredModules: requiredAmdModules }),
160
- ...(isAMD && { preloadModules: preloadAmdModules }),
194
+ ...(isAMD && { preloadModules: dedupedPreloadAmdModules }),
161
195
  }, runtimeEnvironment, runtimeParams));
162
196
  if (!isAMD && hmrEnabled) {
163
197
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
164
198
  }
199
+ // PRELOAD script resources for preload module URIs at the top (ie: bootstrap and root component static dependencies)
200
+ for (const preloadUri of preloadModuleUris) {
201
+ moduleResources.unshift(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
202
+ }
165
203
  // generate html partial
166
204
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
167
205
  return {
@@ -1,4 +1,4 @@
1
- import { ModuleRegistry, LinkedViewDefinition, RenderedViewMetadata, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
1
+ import { ModuleRegistry, LinkedViewDefinition, RenderedViewMetadata, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams, BundleConfig } from '@lwrjs/types';
2
2
  export interface LwrResourcesLinkedContext extends ResourceContext {
3
3
  lwrResourcesId: string;
4
4
  }
@@ -9,6 +9,7 @@ interface ResourceContext {
9
9
  moduleRegistry: ModuleRegistry;
10
10
  moduleBundler: ModuleBundler;
11
11
  resourceRegistry: ResourceRegistry;
12
+ bundleConfig: BundleConfig;
12
13
  }
13
14
  declare type LinkedResourcesViewDefinition = Pick<LinkedViewDefinition, 'renderedView' | 'viewRecord'>;
14
15
  export declare function linkLwrResources(source: string, view: View, viewParams: ViewParams, cxt: LwrResourcesLinkedContext): Promise<LinkedResourcesViewDefinition>;
@@ -1,4 +1,4 @@
1
- import { ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
1
+ import { BundleConfig, ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
2
2
  export interface LwrResourcesLinkedContext extends ResourceContext {
3
3
  lwrResourcesId: string;
4
4
  }
@@ -9,6 +9,7 @@ interface ResourceContext {
9
9
  moduleRegistry: ModuleRegistry;
10
10
  moduleBundler: ModuleBundler;
11
11
  resourceRegistry: ResourceRegistry;
12
+ bundleConfig: BundleConfig;
12
13
  }
13
14
  export declare function getHtmlResources(view: View, viewParams: ViewParams, resourceContext: ResourceContext): Promise<{
14
15
  partial: string;
@@ -1,10 +1,17 @@
1
- import { kebabCaseToModuleSpecifier, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, getVersionedModuleId, explodeSpecifier, getSpecifier, normalizeVersionToUri, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
4
  import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
- const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services, module: bootstrapModule } = { services: [] } } = view;
6
+ const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, bundleConfig: { external = {} }, } = resourceContext;
7
+ const isExternal = function (rawSpecifier) {
8
+ const { specifier } = explodeSpecifier(rawSpecifier);
9
+ return Object.keys(external).some((e) => specifier === e);
10
+ };
11
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
12
+ services: [],
13
+ preloadModules: [],
14
+ }, } = view;
8
15
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
16
  const { customElements } = viewMetadata;
10
17
  const defRegistry = bundle ? moduleBundler : moduleRegistry;
@@ -22,6 +29,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
22
29
  /*
23
30
  Internal module and module dependency related resources used by the view to render view related components.
24
31
  */
32
+ const preloadModuleUris = new Set();
25
33
  const moduleResources = [];
26
34
  /*
27
35
  External resources that the view depends. These resources include ones that an ViewDefinition client are required to load
@@ -40,18 +48,15 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
40
48
  const rootComponents = [];
41
49
  // Collection of modules specifiers that MUST be loaded in the view
42
50
  const requiredAmdModules = [];
43
- // Collection of modules that will be loaded in the view
51
+ // Collection of modules that will be preloaded. For AMD, it will be part of
52
+ // the preloadModules client bootstrap config
44
53
  const preloadAmdModules = [];
45
54
  // Determine if server side rendering view modules
46
55
  const isSSR = view.bootstrap?.ssr;
47
56
  // ------ AMD Required module resources
48
57
  if (isAMD) {
49
58
  // Keep shim format in sync with legacy_view_bootstrap.ts
50
- const shimBundle = !bundle
51
- ? 'lwr-loader-shim.js'
52
- : debug || minify === false
53
- ? 'lwr-loader-shim.bundle.js'
54
- : 'lwr-loader-shim.bundle.min.js';
59
+ const shimBundle = debug || minify === false ? 'lwr-loader-shim.bundle.js' : 'lwr-loader-shim.bundle.min.js';
55
60
  const def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
56
61
  if (!def) {
57
62
  throw Error('Failed to find definition of resource: ' + shimBundle);
@@ -63,16 +68,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
63
68
  throw Error('Failed to find definition of resource: lwr-error-shim.js');
64
69
  }
65
70
  requiredResources.push(errorShimDef);
66
- // Add loader, if not already bundled with the shim
67
- if (!bundle) {
68
- // needed because we're resolving against fully-linked modules
69
- requiredResources.push(await getModuleResource({
70
- specifier: 'lwr/loader',
71
- version,
72
- }, runtimeEnvironment, {
73
- isSSR,
74
- }, moduleRegistry, runtimeParams));
75
- }
76
71
  }
77
72
  // ------- Application Bootstrap module
78
73
  // Traversal of the Bootstrap Module Graph is done to get all the URLS for discoverable static dependencies.
@@ -85,6 +80,35 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
85
80
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
86
81
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
87
82
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
83
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
84
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
85
+ if (!isExternal(depSpecifier)) {
86
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
87
+ // in AMD, we also need to tell the loader it's being preloaded
88
+ preloadAmdModules.push(depSpecifier);
89
+ }
90
+ }
91
+ // PRELOAD configured preloadModules as preloaded script resources
92
+ for (let i = 0; i < preloadModules.length; i++) {
93
+ const specifier = preloadModules[i];
94
+ if (isExternal(specifier)) {
95
+ logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
96
+ }
97
+ else {
98
+ // eslint-disable-next-line no-await-in-loop
99
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry);
100
+ const versionedModuleSpecifier = getSpecifier({
101
+ specifier,
102
+ version: normalizeVersionToUri(versionedModuleId.version),
103
+ });
104
+ const uri = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] ||
105
+ // eslint-disable-next-line no-await-in-loop
106
+ (await moduleRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams));
107
+ preloadModuleUris.add(uri);
108
+ // in AMD, we also need to tell the loader it's being preloaded
109
+ preloadAmdModules.push(versionedModuleSpecifier);
110
+ }
111
+ }
88
112
  if (isAMD) {
89
113
  // ADD bootstrap module as required
90
114
  requiredAmdModules.push(versionedSpecifier);
@@ -97,8 +121,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
97
121
  imports[staticDep] = uri;
98
122
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
99
123
  if (services && services.length) {
100
- // get the graphs for the bs static deps
101
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
102
124
  requiredAmdModules.push(staticDep);
103
125
  }
104
126
  }
@@ -122,10 +144,20 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
122
144
  const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
123
145
  // add to the viewRecord
124
146
  customElementsRecords.push({ elementName: element, flatGraph: graph });
125
- // PRELOAD custom element static deps as link resource
147
+ // PRELOAD the custom element module as a link resource
126
148
  const specifier = graph.graphs[0].specifier;
127
149
  const uri = graph.uriMap[specifier];
128
150
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
151
+ // PRELOAD custom element static deps as link resources when bundling is ON
152
+ if (bundle) {
153
+ for (const depSpecifier of graph.graphs[0].static) {
154
+ if (!isExternal(depSpecifier)) {
155
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
156
+ // in AMD, we also need to tell the loader it's being preloaded
157
+ preloadAmdModules.push(depSpecifier);
158
+ }
159
+ }
160
+ }
129
161
  // ADD register custom elements as a uri addressable rootComponents
130
162
  rootComponents.push(specifier);
131
163
  imports[specifier] = uri;
@@ -145,6 +177,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
145
177
  // eslint-disable-next-line no-await-in-loop
146
178
  importMetadata = await toImportMetadata(graph, importMetadata, moduleRegistry, runtimeEnvironment, runtimeParams);
147
179
  }
180
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
148
181
  // ADD configuration of the bootstrapModule
149
182
  configResources.unshift(await getViewBootstrapConfigurationResource({
150
183
  id: view.id,
@@ -158,11 +191,15 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
158
191
  index: importMetadata?.index,
159
192
  rootComponents,
160
193
  ...(isAMD && { requiredModules: requiredAmdModules }),
161
- ...(isAMD && { preloadModules: preloadAmdModules }),
194
+ ...(isAMD && { preloadModules: dedupedPreloadAmdModules }),
162
195
  }, runtimeEnvironment, runtimeParams));
163
196
  if (!isAMD && hmrEnabled) {
164
197
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
165
198
  }
199
+ // PRELOAD script resources for preload module URIs at the top (ie: bootstrap and root component static dependencies)
200
+ for (const preloadUri of preloadModuleUris) {
201
+ moduleResources.unshift(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
202
+ }
166
203
  // generate html partial
167
204
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
168
205
  const mapping = getMappingUriPrefix(runtimeEnvironment, runtimeParams);
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.9.0-alpha.27",
7
+ "version": "0.9.0-alpha.29",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -30,15 +30,15 @@
30
30
  "build/**/*.d.ts"
31
31
  ],
32
32
  "dependencies": {
33
- "@lwrjs/app-service": "0.9.0-alpha.27",
34
- "@lwrjs/diagnostics": "0.9.0-alpha.27",
35
- "@lwrjs/shared-utils": "0.9.0-alpha.27"
33
+ "@lwrjs/app-service": "0.9.0-alpha.29",
34
+ "@lwrjs/diagnostics": "0.9.0-alpha.29",
35
+ "@lwrjs/shared-utils": "0.9.0-alpha.29"
36
36
  },
37
37
  "devDependencies": {
38
- "@lwrjs/types": "0.9.0-alpha.27"
38
+ "@lwrjs/types": "0.9.0-alpha.29"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=16.0.0 <20"
42
42
  },
43
- "gitHead": "a7fcd8493b8a3286197e829b28b54670e7d4e97c"
43
+ "gitHead": "2845ec6a71910e27e54139135caf87a63f609222"
44
44
  }