@openmrs/webpack-config 10.0.1-pre.5199 → 10.0.1-pre.5227
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.
- package/dist/index.js +58 -4
- package/package.json +4 -1
- package/src/index.ts +66 -3
package/dist/index.js
CHANGED
|
@@ -50,11 +50,44 @@ const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checke
|
|
|
50
50
|
// eslint-disable-next-line no-restricted-imports
|
|
51
51
|
const lodash_1 = require("lodash");
|
|
52
52
|
const semver_1 = require("semver");
|
|
53
|
-
const webpack_1 = require("webpack");
|
|
53
|
+
const webpack_1 = require("@module-federation/enhanced/webpack");
|
|
54
|
+
const webpack_2 = require("webpack");
|
|
54
55
|
const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
|
|
55
56
|
const webpack_stats_plugin_1 = require("webpack-stats-plugin");
|
|
56
57
|
const production = 'production';
|
|
57
|
-
|
|
58
|
+
// Read from our own pin rather than `@module-federation/enhanced/package.json`, which its `exports` map
|
|
59
|
+
// makes unreadable. `parse` rather than `coerce`, so that loosening the pin to a range disables the skew
|
|
60
|
+
// warning instead of misreporting it: `coerce` turns `2.x` and `^2` into 2.0, which would warn forever.
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
62
|
+
const moduleFederationPin = require('../package.json').dependencies['@module-federation/enhanced'];
|
|
63
|
+
const moduleFederationVersion = (0, semver_1.parse)(moduleFederationPin);
|
|
64
|
+
/**
|
|
65
|
+
* Prepended to this app's entry chunks. Without it, an app running under an app shell too old to
|
|
66
|
+
* publish the runtime globals fails with a `TypeError` from inside minified runtime code. All three
|
|
67
|
+
* globals are checked because `_OPENMRS_FEDERATION_ERROR_CODES` is what describes the failure, and a runtime
|
|
68
|
+
* minor differing from the app shell's warns. `@openmrs/rspack-config` has a copy of this; keep them in step.
|
|
69
|
+
*/
|
|
70
|
+
function buildFederationRuntimeGuard(appName, expectedMinor) {
|
|
71
|
+
const missingRuntime = "(function(){var g=typeof globalThis!=='undefined'?globalThis:self;" +
|
|
72
|
+
"if(typeof g._FEDERATION_RUNTIME_CORE==='undefined'||typeof g._OPENMRS_FEDERATION_SDK==='undefined'||typeof g._OPENMRS_FEDERATION_ERROR_CODES==='undefined'){" +
|
|
73
|
+
'throw new Error(' +
|
|
74
|
+
JSON.stringify(appName) +
|
|
75
|
+
" + ' cannot start: the OpenMRS app shell serving this page does not provide the Module Federation runtime. " +
|
|
76
|
+
'This app was built with newer OpenMRS tooling than the app shell, so either upgrade @openmrs/esm-app-shell, ' +
|
|
77
|
+
"or rebuild this app with tooling matching the app shell.');}";
|
|
78
|
+
// Skipped rather than always warning if the pin couldn't be coerced to a version.
|
|
79
|
+
const skew = expectedMinor
|
|
80
|
+
? 'var from=g._FEDERATION_RUNTIME_CORE_FROM;' +
|
|
81
|
+
'if(from&&from.version&&String(from.version).split(".").slice(0,2).join(".")!==' +
|
|
82
|
+
JSON.stringify(expectedMinor) +
|
|
83
|
+
'){console.warn(' +
|
|
84
|
+
JSON.stringify(appName) +
|
|
85
|
+
" + ' was built against Module Federation " +
|
|
86
|
+
expectedMinor +
|
|
87
|
+
".x but the app shell provides ' + from.version + '. Shared dependencies may not de-duplicate correctly.');}"
|
|
88
|
+
: '';
|
|
89
|
+
return missingRuntime + skew + '})();';
|
|
90
|
+
}
|
|
58
91
|
function getFrameworkVersion() {
|
|
59
92
|
try {
|
|
60
93
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -238,15 +271,23 @@ exports.default = (env, argv = {}) => {
|
|
|
238
271
|
new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
|
|
239
272
|
analyzerMode: env && env.analyze ? 'server' : 'disabled',
|
|
240
273
|
}),
|
|
241
|
-
new
|
|
274
|
+
new webpack_2.DefinePlugin({
|
|
242
275
|
'process.env.FRAMEWORK_VERSION': JSON.stringify(frameworkVersion),
|
|
243
276
|
}),
|
|
244
|
-
new ModuleFederationPlugin({
|
|
277
|
+
new webpack_1.ModuleFederationPlugin({
|
|
245
278
|
// Look in the `esm-dynamic-loading` framework package for an explanation of how modules
|
|
246
279
|
// get loaded into the application.
|
|
247
280
|
name,
|
|
248
281
|
library: { type: 'var', name: slugify(name) },
|
|
249
282
|
filename,
|
|
283
|
+
// Building on `@module-federation/enhanced` gives webpack remotes the MF 2.0 runtime, which they
|
|
284
|
+
// read from the globals the app shell publishes rather than embedding. See `@openmrs/rspack-config`.
|
|
285
|
+
experiments: {
|
|
286
|
+
externalRuntime: true,
|
|
287
|
+
},
|
|
288
|
+
// Nothing consumes an mf-manifest or federated types here, so skip both plugins.
|
|
289
|
+
manifest: false,
|
|
290
|
+
dts: false,
|
|
250
291
|
exposes: {
|
|
251
292
|
'./start': srcFile,
|
|
252
293
|
},
|
|
@@ -292,6 +333,19 @@ exports.default = (env, argv = {}) => {
|
|
|
292
333
|
},
|
|
293
334
|
],
|
|
294
335
|
}),
|
|
336
|
+
// The two runtime packages a remote can safely borrow from the app shell; see the
|
|
337
|
+
// `ExternalsPlugin` block in `@openmrs/rspack-config` for why only these two are shareable,
|
|
338
|
+
// what still ships per remote, and why this is a plugin rather than an `externals` entry.
|
|
339
|
+
new webpack_2.ExternalsPlugin('global', {
|
|
340
|
+
'@module-federation/sdk': '_OPENMRS_FEDERATION_SDK',
|
|
341
|
+
'@module-federation/error-codes': '_OPENMRS_FEDERATION_ERROR_CODES',
|
|
342
|
+
}),
|
|
343
|
+
new webpack_2.BannerPlugin({
|
|
344
|
+
raw: true,
|
|
345
|
+
entryOnly: true,
|
|
346
|
+
test: /\.[cm]?js$/,
|
|
347
|
+
banner: buildFederationRuntimeGuard(name, moduleFederationVersion ? `${moduleFederationVersion.major}.${moduleFederationVersion.minor}` : undefined),
|
|
348
|
+
}),
|
|
295
349
|
new webpack_stats_plugin_1.StatsWriterPlugin({
|
|
296
350
|
filename: `${filename}.buildmanifest.json`,
|
|
297
351
|
stats: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/webpack-config",
|
|
3
|
-
"version": "10.0.1-pre.
|
|
3
|
+
"version": "10.0.1-pre.5227",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"homepage": "https://github.com/openmrs/openmrs-esm-core#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@module-federation/enhanced": "2.8.1",
|
|
33
34
|
"@swc/core": "1.15.21",
|
|
34
35
|
"clean-webpack-plugin": "4.0.0",
|
|
35
36
|
"copy-webpack-plugin": "11.0.0",
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
"lodash": "4.17.21",
|
|
39
40
|
"sass-embedded": "1.89.2",
|
|
40
41
|
"sass-loader": "16.0.5",
|
|
42
|
+
"semver": "^7.7.3",
|
|
41
43
|
"style-loader": "3.3.4",
|
|
42
44
|
"swc-loader": "0.2.7",
|
|
43
45
|
"webpack": "5.105.3",
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
},
|
|
48
50
|
"devDependencies": {
|
|
49
51
|
"@types/lodash-es": "4.17.12",
|
|
52
|
+
"@types/semver": "^7.7.3",
|
|
50
53
|
"typescript": "^5.8.3"
|
|
51
54
|
},
|
|
52
55
|
"stableVersion": "10.0.0"
|
package/src/index.ts
CHANGED
|
@@ -43,10 +43,12 @@ import CopyWebpackPlugin from 'copy-webpack-plugin';
|
|
|
43
43
|
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
|
44
44
|
// eslint-disable-next-line no-restricted-imports
|
|
45
45
|
import { isArray, merge, mergeWith } from 'lodash';
|
|
46
|
-
import { inc } from 'semver';
|
|
46
|
+
import { inc, parse } from 'semver';
|
|
47
|
+
import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack';
|
|
47
48
|
import {
|
|
48
|
-
|
|
49
|
+
BannerPlugin,
|
|
49
50
|
DefinePlugin,
|
|
51
|
+
ExternalsPlugin,
|
|
50
52
|
type ModuleOptions,
|
|
51
53
|
type RuleSetRule,
|
|
52
54
|
type WebpackOptionsNormalized as WebpackConfiguration,
|
|
@@ -60,7 +62,44 @@ type OpenmrsWebpackConfig = Omit<Partial<WebpackConfiguration>, 'module' | 'outp
|
|
|
60
62
|
};
|
|
61
63
|
|
|
62
64
|
const production = 'production';
|
|
63
|
-
|
|
65
|
+
|
|
66
|
+
// Read from our own pin rather than `@module-federation/enhanced/package.json`, which its `exports` map
|
|
67
|
+
// makes unreadable. `parse` rather than `coerce`, so that loosening the pin to a range disables the skew
|
|
68
|
+
// warning instead of misreporting it: `coerce` turns `2.x` and `^2` into 2.0, which would warn forever.
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
70
|
+
const moduleFederationPin: string = require('../package.json').dependencies['@module-federation/enhanced'];
|
|
71
|
+
const moduleFederationVersion = parse(moduleFederationPin);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Prepended to this app's entry chunks. Without it, an app running under an app shell too old to
|
|
75
|
+
* publish the runtime globals fails with a `TypeError` from inside minified runtime code. All three
|
|
76
|
+
* globals are checked because `_OPENMRS_FEDERATION_ERROR_CODES` is what describes the failure, and a runtime
|
|
77
|
+
* minor differing from the app shell's warns. `@openmrs/rspack-config` has a copy of this; keep them in step.
|
|
78
|
+
*/
|
|
79
|
+
function buildFederationRuntimeGuard(appName: string, expectedMinor: string | undefined) {
|
|
80
|
+
const missingRuntime =
|
|
81
|
+
"(function(){var g=typeof globalThis!=='undefined'?globalThis:self;" +
|
|
82
|
+
"if(typeof g._FEDERATION_RUNTIME_CORE==='undefined'||typeof g._OPENMRS_FEDERATION_SDK==='undefined'||typeof g._OPENMRS_FEDERATION_ERROR_CODES==='undefined'){" +
|
|
83
|
+
'throw new Error(' +
|
|
84
|
+
JSON.stringify(appName) +
|
|
85
|
+
" + ' cannot start: the OpenMRS app shell serving this page does not provide the Module Federation runtime. " +
|
|
86
|
+
'This app was built with newer OpenMRS tooling than the app shell, so either upgrade @openmrs/esm-app-shell, ' +
|
|
87
|
+
"or rebuild this app with tooling matching the app shell.');}";
|
|
88
|
+
|
|
89
|
+
// Skipped rather than always warning if the pin couldn't be coerced to a version.
|
|
90
|
+
const skew = expectedMinor
|
|
91
|
+
? 'var from=g._FEDERATION_RUNTIME_CORE_FROM;' +
|
|
92
|
+
'if(from&&from.version&&String(from.version).split(".").slice(0,2).join(".")!==' +
|
|
93
|
+
JSON.stringify(expectedMinor) +
|
|
94
|
+
'){console.warn(' +
|
|
95
|
+
JSON.stringify(appName) +
|
|
96
|
+
" + ' was built against Module Federation " +
|
|
97
|
+
expectedMinor +
|
|
98
|
+
".x but the app shell provides ' + from.version + '. Shared dependencies may not de-duplicate correctly.');}"
|
|
99
|
+
: '';
|
|
100
|
+
|
|
101
|
+
return missingRuntime + skew + '})();';
|
|
102
|
+
}
|
|
64
103
|
|
|
65
104
|
function getFrameworkVersion() {
|
|
66
105
|
try {
|
|
@@ -297,6 +336,14 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
297
336
|
name,
|
|
298
337
|
library: { type: 'var', name: slugify(name) },
|
|
299
338
|
filename,
|
|
339
|
+
// Building on `@module-federation/enhanced` gives webpack remotes the MF 2.0 runtime, which they
|
|
340
|
+
// read from the globals the app shell publishes rather than embedding. See `@openmrs/rspack-config`.
|
|
341
|
+
experiments: {
|
|
342
|
+
externalRuntime: true,
|
|
343
|
+
},
|
|
344
|
+
// Nothing consumes an mf-manifest or federated types here, so skip both plugins.
|
|
345
|
+
manifest: false,
|
|
346
|
+
dts: false,
|
|
300
347
|
exposes: {
|
|
301
348
|
'./start': srcFile,
|
|
302
349
|
},
|
|
@@ -344,6 +391,22 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
344
391
|
},
|
|
345
392
|
],
|
|
346
393
|
}),
|
|
394
|
+
// The two runtime packages a remote can safely borrow from the app shell; see the
|
|
395
|
+
// `ExternalsPlugin` block in `@openmrs/rspack-config` for why only these two are shareable,
|
|
396
|
+
// what still ships per remote, and why this is a plugin rather than an `externals` entry.
|
|
397
|
+
new ExternalsPlugin('global', {
|
|
398
|
+
'@module-federation/sdk': '_OPENMRS_FEDERATION_SDK',
|
|
399
|
+
'@module-federation/error-codes': '_OPENMRS_FEDERATION_ERROR_CODES',
|
|
400
|
+
}),
|
|
401
|
+
new BannerPlugin({
|
|
402
|
+
raw: true,
|
|
403
|
+
entryOnly: true,
|
|
404
|
+
test: /\.[cm]?js$/,
|
|
405
|
+
banner: buildFederationRuntimeGuard(
|
|
406
|
+
name,
|
|
407
|
+
moduleFederationVersion ? `${moduleFederationVersion.major}.${moduleFederationVersion.minor}` : undefined,
|
|
408
|
+
),
|
|
409
|
+
}),
|
|
347
410
|
new StatsWriterPlugin({
|
|
348
411
|
filename: `${filename}.buildmanifest.json`,
|
|
349
412
|
stats: {
|