@openmrs/rspack-config 10.0.1-pre.5324 → 10.0.1-pre.5364
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 +87 -1
- package/package.json +3 -1
- package/src/index.ts +114 -0
package/dist/index.js
CHANGED
|
@@ -32,6 +32,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.optimizationConfig = exports.watchConfig = exports.assetRuleConfig = exports.scssRuleConfig = exports.cssRuleConfig = exports.scriptRuleConfig = exports.additionalConfig = exports.overrides = void 0;
|
|
37
40
|
/**
|
|
@@ -74,6 +77,9 @@ exports.optimizationConfig = exports.watchConfig = exports.assetRuleConfig = exp
|
|
|
74
77
|
*/
|
|
75
78
|
const fs_1 = require("fs");
|
|
76
79
|
const path_1 = require("path");
|
|
80
|
+
const browserslist_1 = __importDefault(require("browserslist"));
|
|
81
|
+
const node_1 = require("browserslist/node");
|
|
82
|
+
const browserslist_config_openmrs_1 = __importDefault(require("browserslist-config-openmrs"));
|
|
77
83
|
const clean_webpack_plugin_1 = require("clean-webpack-plugin");
|
|
78
84
|
const ts_checker_rspack_plugin_1 = require("ts-checker-rspack-plugin");
|
|
79
85
|
// eslint-disable-next-line no-restricted-imports
|
|
@@ -127,6 +133,79 @@ function getFrameworkVersion() {
|
|
|
127
133
|
return '5.x';
|
|
128
134
|
}
|
|
129
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* The browserslist queries swc compiles this module against, falling back to OpenMRS's shared config
|
|
138
|
+
* when the module declares none, so that frontend RFC 0003 stays the single source of truth. Given no
|
|
139
|
+
* target at all swc down-levels to ES5, and every supported browser pays for transform helpers it
|
|
140
|
+
* doesn't need.
|
|
141
|
+
*
|
|
142
|
+
* `@openmrs/webpack-config` has a copy of this; keep them in step. `browser-targets.test.ts` compares
|
|
143
|
+
* what the two hand their loaders and fails if they drift.
|
|
144
|
+
*
|
|
145
|
+
* @param root The directory of the module being built
|
|
146
|
+
*/
|
|
147
|
+
function browserslistQueries(root) {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
const warnings = [];
|
|
150
|
+
// deliberately unguarded
|
|
151
|
+
const loaded = browserslist_1.default.loadConfig({ path: root });
|
|
152
|
+
const configured = loaded === undefined ? [] : Array.isArray(loaded) ? loaded : [loaded];
|
|
153
|
+
if (loaded !== undefined && configured.length === 0) {
|
|
154
|
+
// warn when a browserlist config is empty
|
|
155
|
+
warnings.push(`This module declares a browserslist config, but it resolves to no queries for the ` +
|
|
156
|
+
`${(_b = (_a = process.env.BROWSERSLIST_ENV) !== null && _a !== void 0 ? _a : process.env.NODE_ENV) !== null && _b !== void 0 ? _b : production} environment. ` +
|
|
157
|
+
`Targeting ${browserslist_config_openmrs_1.default.join(', ')} instead.`);
|
|
158
|
+
}
|
|
159
|
+
const expanded = expandBrowserslistExtends(configured.length > 0 ? configured : browserslist_config_openmrs_1.default, root, warnings);
|
|
160
|
+
return { queries: expanded.length > 0 ? expanded : browserslist_config_openmrs_1.default, warnings };
|
|
161
|
+
}
|
|
162
|
+
function expandBrowserslistExtends(queries, root, warnings, seen = new Set()) {
|
|
163
|
+
// Split on commas because a browserslist config may be a single string of them
|
|
164
|
+
return queries.flatMap((query) => query
|
|
165
|
+
.split(',')
|
|
166
|
+
.flatMap((part) => {
|
|
167
|
+
const extended = /^extends\s+(.+)$/i.exec(part.trim());
|
|
168
|
+
if (!extended) {
|
|
169
|
+
return [part.trim()];
|
|
170
|
+
}
|
|
171
|
+
const name = extended[1].trim();
|
|
172
|
+
if (seen.has(name)) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
seen.add(name);
|
|
176
|
+
try {
|
|
177
|
+
// browserslist's own loader, rather than a bare `require` so we handle the same syntax
|
|
178
|
+
const resolved = (0, node_1.loadQueries)({ path: root }, name);
|
|
179
|
+
return expandBrowserslistExtends(Array.isArray(resolved) ? resolved : [resolved], root, warnings, seen);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// Only browserslist's own verdict on a named config is survivable: not installed, or refused
|
|
183
|
+
// for its name.
|
|
184
|
+
const notInstalled = (err === null || err === void 0 ? void 0 : err.code) === 'MODULE_NOT_FOUND';
|
|
185
|
+
const refused = (err === null || err === void 0 ? void 0 : err.browserslist) === true;
|
|
186
|
+
if (!notInstalled && !refused) {
|
|
187
|
+
throw err;
|
|
188
|
+
}
|
|
189
|
+
warnings.push(`Could not load the browserslist config "${name}" (${err.message}). ` +
|
|
190
|
+
`Targeting ${browserslist_config_openmrs_1.default.join(', ')} instead.`);
|
|
191
|
+
return browserslist_config_openmrs_1.default;
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
.filter((part) => part.length > 0));
|
|
195
|
+
}
|
|
196
|
+
/** Reports how a module's browsers were worked out, where a developer will actually see it. */
|
|
197
|
+
class BrowserslistWarningsPlugin {
|
|
198
|
+
constructor(messages) {
|
|
199
|
+
this.messages = messages;
|
|
200
|
+
}
|
|
201
|
+
apply(compiler) {
|
|
202
|
+
compiler.hooks.thisCompilation.tap('OpenmrsBrowserslistWarnings', (compilation) => {
|
|
203
|
+
for (const message of this.messages) {
|
|
204
|
+
compilation.warnings.push(new core_1.default.WebpackError(message));
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
130
209
|
function makeIdent(name) {
|
|
131
210
|
if (name.includes('/')) {
|
|
132
211
|
name = name.slice(name.indexOf('/'));
|
|
@@ -207,6 +286,7 @@ exports.default = (env, argv = {}) => {
|
|
|
207
286
|
const outDir = (0, path_1.dirname)(browser || main);
|
|
208
287
|
const srcFile = (0, path_1.resolve)(root, browser ? main : types);
|
|
209
288
|
const ident = makeIdent(name);
|
|
289
|
+
const { queries: browserTargets, warnings: browserslistWarnings } = browserslistQueries(root);
|
|
210
290
|
const frameworkVersion = getFrameworkVersion();
|
|
211
291
|
const routes = (0, path_1.resolve)(root, 'src', 'routes.json');
|
|
212
292
|
const hasRoutesDefined = fileExistsSync(routes);
|
|
@@ -240,6 +320,9 @@ exports.default = (env, argv = {}) => {
|
|
|
240
320
|
exclude: /node_modules/,
|
|
241
321
|
loader: 'builtin:swc-loader',
|
|
242
322
|
options: {
|
|
323
|
+
env: {
|
|
324
|
+
targets: browserTargets,
|
|
325
|
+
},
|
|
243
326
|
jsc: {
|
|
244
327
|
parser: {
|
|
245
328
|
syntax: 'typescript',
|
|
@@ -276,7 +359,9 @@ exports.default = (env, argv = {}) => {
|
|
|
276
359
|
type: 'asset/source',
|
|
277
360
|
},
|
|
278
361
|
],
|
|
279
|
-
}, mode,
|
|
362
|
+
}, mode,
|
|
363
|
+
// governs rspack's own runtime and chunk-loading glue
|
|
364
|
+
target: ['web', `browserslist:${browserTargets.join(', ')}`], devtool: mode === production ? 'hidden-nosources-source-map' : 'source-map', devServer: {
|
|
280
365
|
headers: {
|
|
281
366
|
'Access-Control-Allow-Origin': '*',
|
|
282
367
|
},
|
|
@@ -294,6 +379,7 @@ exports.default = (env, argv = {}) => {
|
|
|
294
379
|
},
|
|
295
380
|
minimizer: [new core_1.default.SwcJsMinimizerRspackPlugin(), new core_1.default.LightningCssMinimizerRspackPlugin()],
|
|
296
381
|
}, exports.optimizationConfig), plugins: [
|
|
382
|
+
browserslistWarnings.length > 0 && new BrowserslistWarningsPlugin(browserslistWarnings),
|
|
297
383
|
new ts_checker_rspack_plugin_1.TsCheckerRspackPlugin(),
|
|
298
384
|
new clean_webpack_plugin_1.CleanWebpackPlugin(),
|
|
299
385
|
new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/rspack-config",
|
|
3
|
-
"version": "10.0.1-pre.
|
|
3
|
+
"version": "10.0.1-pre.5364",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
"@rspack/cli": "1.7.9",
|
|
36
36
|
"@rspack/core": "1.7.9",
|
|
37
37
|
"@swc/core": "1.15.21",
|
|
38
|
+
"browserslist": "4.28.9",
|
|
39
|
+
"browserslist-config-openmrs": "^1.0.1",
|
|
38
40
|
"clean-webpack-plugin": "4.0.0",
|
|
39
41
|
"copy-webpack-plugin": "11.0.0",
|
|
40
42
|
"css-loader": "5.2.7",
|
package/src/index.ts
CHANGED
|
@@ -38,6 +38,9 @@
|
|
|
38
38
|
*/
|
|
39
39
|
import { existsSync, statSync } from 'fs';
|
|
40
40
|
import { basename, dirname, resolve } from 'path';
|
|
41
|
+
import browserslist from 'browserslist';
|
|
42
|
+
import { loadQueries } from 'browserslist/node';
|
|
43
|
+
import defaultBrowserslistQueries from 'browserslist-config-openmrs';
|
|
41
44
|
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
|
42
45
|
import { TsCheckerRspackPlugin } from 'ts-checker-rspack-plugin';
|
|
43
46
|
// eslint-disable-next-line no-restricted-imports
|
|
@@ -45,6 +48,7 @@ import { isArray, merge, mergeWith } from 'lodash';
|
|
|
45
48
|
import { inc, parse } from 'semver';
|
|
46
49
|
import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';
|
|
47
50
|
import rspack, {
|
|
51
|
+
type Compiler,
|
|
48
52
|
CopyRspackPlugin,
|
|
49
53
|
DefinePlugin,
|
|
50
54
|
type ModuleOptions,
|
|
@@ -108,6 +112,109 @@ function getFrameworkVersion() {
|
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
|
|
115
|
+
/** What a module's browsers resolved to, plus anything worth telling the developer about getting there. */
|
|
116
|
+
type BrowserPolicy = { queries: Array<string>; warnings: Array<string> };
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The browserslist queries swc compiles this module against, falling back to OpenMRS's shared config
|
|
120
|
+
* when the module declares none, so that frontend RFC 0003 stays the single source of truth. Given no
|
|
121
|
+
* target at all swc down-levels to ES5, and every supported browser pays for transform helpers it
|
|
122
|
+
* doesn't need.
|
|
123
|
+
*
|
|
124
|
+
* `@openmrs/webpack-config` has a copy of this; keep them in step. `browser-targets.test.ts` compares
|
|
125
|
+
* what the two hand their loaders and fails if they drift.
|
|
126
|
+
*
|
|
127
|
+
* @param root The directory of the module being built
|
|
128
|
+
*/
|
|
129
|
+
function browserslistQueries(root: string): BrowserPolicy {
|
|
130
|
+
const warnings: Array<string> = [];
|
|
131
|
+
// deliberately unguarded
|
|
132
|
+
const loaded = browserslist.loadConfig({ path: root });
|
|
133
|
+
const configured = loaded === undefined ? [] : Array.isArray(loaded) ? loaded : [loaded];
|
|
134
|
+
|
|
135
|
+
if (loaded !== undefined && configured.length === 0) {
|
|
136
|
+
// warn when a browserlist config is empty
|
|
137
|
+
warnings.push(
|
|
138
|
+
`This module declares a browserslist config, but it resolves to no queries for the ` +
|
|
139
|
+
`${process.env.BROWSERSLIST_ENV ?? process.env.NODE_ENV ?? production} environment. ` +
|
|
140
|
+
`Targeting ${defaultBrowserslistQueries.join(', ')} instead.`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const expanded = expandBrowserslistExtends(
|
|
145
|
+
configured.length > 0 ? configured : defaultBrowserslistQueries,
|
|
146
|
+
root,
|
|
147
|
+
warnings,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
return { queries: expanded.length > 0 ? expanded : defaultBrowserslistQueries, warnings };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function expandBrowserslistExtends(
|
|
154
|
+
queries: Array<string>,
|
|
155
|
+
root: string,
|
|
156
|
+
warnings: Array<string>,
|
|
157
|
+
seen = new Set<string>(),
|
|
158
|
+
): Array<string> {
|
|
159
|
+
// Split on commas because a browserslist config may be a single string of them
|
|
160
|
+
return queries.flatMap((query) =>
|
|
161
|
+
query
|
|
162
|
+
.split(',')
|
|
163
|
+
.flatMap((part) => {
|
|
164
|
+
const extended = /^extends\s+(.+)$/i.exec(part.trim());
|
|
165
|
+
|
|
166
|
+
if (!extended) {
|
|
167
|
+
return [part.trim()];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const name = extended[1].trim();
|
|
171
|
+
|
|
172
|
+
if (seen.has(name)) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
seen.add(name);
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
// browserslist's own loader, rather than a bare `require` so we handle the same syntax
|
|
180
|
+
const resolved = loadQueries({ path: root }, name);
|
|
181
|
+
|
|
182
|
+
return expandBrowserslistExtends(Array.isArray(resolved) ? resolved : [resolved], root, warnings, seen);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
// Only browserslist's own verdict on a named config is survivable: not installed, or refused
|
|
185
|
+
// for its name.
|
|
186
|
+
const notInstalled = (err as { code?: string })?.code === 'MODULE_NOT_FOUND';
|
|
187
|
+
const refused = (err as { browserslist?: boolean })?.browserslist === true;
|
|
188
|
+
|
|
189
|
+
if (!notInstalled && !refused) {
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
warnings.push(
|
|
194
|
+
`Could not load the browserslist config "${name}" (${(err as Error).message}). ` +
|
|
195
|
+
`Targeting ${defaultBrowserslistQueries.join(', ')} instead.`,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
return defaultBrowserslistQueries;
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
.filter((part) => part.length > 0),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Reports how a module's browsers were worked out, where a developer will actually see it. */
|
|
206
|
+
class BrowserslistWarningsPlugin {
|
|
207
|
+
constructor(private readonly messages: Array<string>) {}
|
|
208
|
+
|
|
209
|
+
apply(compiler: Compiler) {
|
|
210
|
+
compiler.hooks.thisCompilation.tap('OpenmrsBrowserslistWarnings', (compilation) => {
|
|
211
|
+
for (const message of this.messages) {
|
|
212
|
+
compilation.warnings.push(new rspack.WebpackError(message));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
111
218
|
function makeIdent(name: string): string {
|
|
112
219
|
if (name.includes('/')) {
|
|
113
220
|
name = name.slice(name.indexOf('/'));
|
|
@@ -200,6 +307,7 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
200
307
|
const outDir = dirname(browser || main);
|
|
201
308
|
const srcFile = resolve(root, browser ? main : types);
|
|
202
309
|
const ident = makeIdent(name);
|
|
310
|
+
const { queries: browserTargets, warnings: browserslistWarnings } = browserslistQueries(root);
|
|
203
311
|
const frameworkVersion = getFrameworkVersion();
|
|
204
312
|
const routes = resolve(root, 'src', 'routes.json');
|
|
205
313
|
const hasRoutesDefined = fileExistsSync(routes);
|
|
@@ -240,6 +348,9 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
240
348
|
exclude: /node_modules/,
|
|
241
349
|
loader: 'builtin:swc-loader',
|
|
242
350
|
options: {
|
|
351
|
+
env: {
|
|
352
|
+
targets: browserTargets,
|
|
353
|
+
},
|
|
243
354
|
jsc: {
|
|
244
355
|
parser: {
|
|
245
356
|
syntax: 'typescript',
|
|
@@ -289,6 +400,8 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
289
400
|
],
|
|
290
401
|
},
|
|
291
402
|
mode,
|
|
403
|
+
// governs rspack's own runtime and chunk-loading glue
|
|
404
|
+
target: ['web', `browserslist:${browserTargets.join(', ')}`],
|
|
292
405
|
devtool: mode === production ? 'hidden-nosources-source-map' : 'source-map',
|
|
293
406
|
devServer: {
|
|
294
407
|
headers: {
|
|
@@ -318,6 +431,7 @@ export default (env: Record<string, string>, argv: Record<string, string> = {})
|
|
|
318
431
|
optimizationConfig,
|
|
319
432
|
),
|
|
320
433
|
plugins: [
|
|
434
|
+
browserslistWarnings.length > 0 && new BrowserslistWarningsPlugin(browserslistWarnings),
|
|
321
435
|
new TsCheckerRspackPlugin(),
|
|
322
436
|
new CleanWebpackPlugin(),
|
|
323
437
|
new BundleAnalyzerPlugin({
|