@openmrs/rspack-config 6.3.1-pre.2986
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/.turbo/turbo-build.log +0 -0
- package/dist/index.js +325 -0
- package/package.json +54 -0
- package/src/index.ts +360 -0
- package/tsconfig.json +15 -0
|
File without changes
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.optimizationConfig = exports.watchConfig = exports.assetRuleConfig = exports.scssRuleConfig = exports.cssRuleConfig = exports.scriptRuleConfig = exports.additionalConfig = exports.overrides = void 0;
|
|
27
|
+
/**
|
|
28
|
+
* This is the base webpack config for all OpenMRS 3.x modules.
|
|
29
|
+
*
|
|
30
|
+
* ## Usage
|
|
31
|
+
*
|
|
32
|
+
* You can use it as simply as
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* module.exports = require('openmrs/default-webpack-config');
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* or you can customize the configuration using merges and overrides
|
|
39
|
+
* like
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const config = require('openmrs/default-webpack-config');
|
|
43
|
+
* config.cssRuleConfig.rules = [myCustomRule];
|
|
44
|
+
* module.exports = config;
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ## Development
|
|
48
|
+
*
|
|
49
|
+
* Advice for working on this file:
|
|
50
|
+
*
|
|
51
|
+
* Don't use `yarn link` or symlinks to work on it.
|
|
52
|
+
*
|
|
53
|
+
* After you `yarn build --watch`, do something like
|
|
54
|
+
* `watch "cp -R dist /path/to/packages/esm-patient-chart-app/webpack"`
|
|
55
|
+
* and then change the webpack line from
|
|
56
|
+
* `module.exports = require('openmrs/default-webpack-config');`
|
|
57
|
+
* to
|
|
58
|
+
* `module.exports = require('./webpack');`
|
|
59
|
+
*
|
|
60
|
+
* This is because Webpack has unpredictable behavior when working with
|
|
61
|
+
* symlinked files, **even when using absolute paths**. You read that right.
|
|
62
|
+
* Telling Webpack to use `/a/b/c`? If the Webpack config is symlinked
|
|
63
|
+
* from `/d/e/`, then it *might* in *some cases* try to import `/d/e/c`.
|
|
64
|
+
*/
|
|
65
|
+
const fs_1 = require("fs");
|
|
66
|
+
const path_1 = require("path");
|
|
67
|
+
const clean_webpack_plugin_1 = require("clean-webpack-plugin");
|
|
68
|
+
const ts_checker_rspack_plugin_1 = require("ts-checker-rspack-plugin");
|
|
69
|
+
// eslint-disable-next-line no-restricted-imports
|
|
70
|
+
const lodash_1 = require("lodash");
|
|
71
|
+
const semver_1 = require("semver");
|
|
72
|
+
const core_1 = __importStar(require("@rspack/core"));
|
|
73
|
+
const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
|
|
74
|
+
const webpack_stats_plugin_1 = require("webpack-stats-plugin");
|
|
75
|
+
const production = 'production';
|
|
76
|
+
const { ModuleFederationPlugin } = core_1.container;
|
|
77
|
+
function getFrameworkVersion() {
|
|
78
|
+
try {
|
|
79
|
+
const { version } = require('@openmrs/esm-framework/package.json');
|
|
80
|
+
return `^${version}`;
|
|
81
|
+
}
|
|
82
|
+
catch (_a) {
|
|
83
|
+
return '5.x';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function makeIdent(name) {
|
|
87
|
+
if (name.includes('/')) {
|
|
88
|
+
name = name.slice(name.indexOf('/'));
|
|
89
|
+
}
|
|
90
|
+
if (name.endsWith('-app')) {
|
|
91
|
+
name = name.slice(0, -4);
|
|
92
|
+
}
|
|
93
|
+
return name;
|
|
94
|
+
}
|
|
95
|
+
function mergeFunction(objValue, srcValue) {
|
|
96
|
+
if ((0, lodash_1.isArray)(objValue)) {
|
|
97
|
+
return objValue.concat(srcValue);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function slugify(name) {
|
|
101
|
+
return name.replace(/[\/\-@]/g, '_');
|
|
102
|
+
}
|
|
103
|
+
function fileExistsSync(name) {
|
|
104
|
+
return (0, fs_1.existsSync)(name) && (0, fs_1.statSync)(name).isFile();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* This object will be merged into the webpack config.
|
|
108
|
+
* Array values will be concatenated with the existing array.
|
|
109
|
+
* Make sure to modify this object and not reassign it.
|
|
110
|
+
*/
|
|
111
|
+
exports.overrides = {};
|
|
112
|
+
/**
|
|
113
|
+
* The keys of this object will override the top-level keys
|
|
114
|
+
* of the webpack config.
|
|
115
|
+
* Make sure to modify this object and not reassign it.
|
|
116
|
+
*/
|
|
117
|
+
exports.additionalConfig = {};
|
|
118
|
+
/**
|
|
119
|
+
* This object will be merged into the webpack rule governing
|
|
120
|
+
* the loading of JS, JSX, TS, etc. files.
|
|
121
|
+
* Make sure to modify this object and not reassign it.
|
|
122
|
+
*/
|
|
123
|
+
exports.scriptRuleConfig = {};
|
|
124
|
+
/**
|
|
125
|
+
* This object will be merged into the webpack rule governing
|
|
126
|
+
* the loading of CSS files.
|
|
127
|
+
* Make sure to modify this object and not reassign it.
|
|
128
|
+
*/
|
|
129
|
+
exports.cssRuleConfig = {};
|
|
130
|
+
/**
|
|
131
|
+
* This object will be merged into the webpack rule governing
|
|
132
|
+
* the loading of SCSS files.
|
|
133
|
+
* Make sure to modify this object and not reassign it.
|
|
134
|
+
*/
|
|
135
|
+
exports.scssRuleConfig = {};
|
|
136
|
+
/**
|
|
137
|
+
* This object will be merged into the webpack rule governing
|
|
138
|
+
* the loading of static asset files.
|
|
139
|
+
* Make sure to modify this object and not reassign it.
|
|
140
|
+
*/
|
|
141
|
+
exports.assetRuleConfig = {};
|
|
142
|
+
/**
|
|
143
|
+
* This object will be merged into the webpack rule governing
|
|
144
|
+
* the watch options.
|
|
145
|
+
* Make sure to modify this object and not reassign it.
|
|
146
|
+
*/
|
|
147
|
+
exports.watchConfig = {};
|
|
148
|
+
/**
|
|
149
|
+
* This object will be merged with the webpack optimization
|
|
150
|
+
* object.
|
|
151
|
+
* Make sure to modify this object and not reassign it.
|
|
152
|
+
*/
|
|
153
|
+
exports.optimizationConfig = {};
|
|
154
|
+
exports.default = (env, argv = {}) => {
|
|
155
|
+
const root = process.cwd();
|
|
156
|
+
const { name, version, peerDependencies, browser, main, types } = require((0, path_1.resolve)(root, 'package.json'));
|
|
157
|
+
// this typing is provably incorrect, but actually works
|
|
158
|
+
const mode = (argv.mode || process.env.NODE_ENV || 'development');
|
|
159
|
+
const filename = (0, path_1.basename)(browser || main);
|
|
160
|
+
const outDir = (0, path_1.dirname)(browser || main);
|
|
161
|
+
const srcFile = (0, path_1.resolve)(root, browser ? main : types);
|
|
162
|
+
const ident = makeIdent(name);
|
|
163
|
+
const frameworkVersion = getFrameworkVersion();
|
|
164
|
+
const routes = (0, path_1.resolve)(root, 'src', 'routes.json');
|
|
165
|
+
const hasRoutesDefined = fileExistsSync(routes);
|
|
166
|
+
if (!hasRoutesDefined) {
|
|
167
|
+
console.error('This app does not define a routes.json. This file is required for this app to be used by the OpenMRS 3 App Shell.');
|
|
168
|
+
// key-smash error code
|
|
169
|
+
// so this (hopefully) doesn't interfere with Webpack-specific exit codes
|
|
170
|
+
process.exit(9819023573289);
|
|
171
|
+
}
|
|
172
|
+
const cssLoader = {
|
|
173
|
+
loader: require.resolve('css-loader'),
|
|
174
|
+
options: {
|
|
175
|
+
modules: {
|
|
176
|
+
localIdentName: `${ident}__[name]__[local]___[hash:base64:5]`,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
const baseConfig = Object.assign({
|
|
181
|
+
// The only `entry` in the application is the app shell. Everything else is
|
|
182
|
+
// a Webpack Module Federation "remote." This ensures that there is always
|
|
183
|
+
// only one container context--i.e., if we had an entry point per module,
|
|
184
|
+
// WMF could get confused and not resolve shared dependencies correctly.
|
|
185
|
+
output: {
|
|
186
|
+
publicPath: 'auto',
|
|
187
|
+
path: (0, path_1.resolve)(root, outDir),
|
|
188
|
+
hashFunction: 'xxhash64',
|
|
189
|
+
}, module: {
|
|
190
|
+
rules: [
|
|
191
|
+
(0, lodash_1.merge)({
|
|
192
|
+
test: /\.m?(js|ts|tsx)$/,
|
|
193
|
+
exclude: /node_modules(?![\/\\]@openmrs)/,
|
|
194
|
+
loader: 'builtin:swc-loader',
|
|
195
|
+
options: {
|
|
196
|
+
jsc: {
|
|
197
|
+
parser: {
|
|
198
|
+
syntax: 'typescript',
|
|
199
|
+
tsx: true,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
}, exports.scriptRuleConfig),
|
|
204
|
+
(0, lodash_1.merge)({
|
|
205
|
+
test: /\.css$/,
|
|
206
|
+
use: [require.resolve('style-loader'), cssLoader],
|
|
207
|
+
}, exports.cssRuleConfig),
|
|
208
|
+
(0, lodash_1.merge)({
|
|
209
|
+
test: /\.s[ac]ss$/i,
|
|
210
|
+
use: [
|
|
211
|
+
require.resolve('style-loader'),
|
|
212
|
+
cssLoader,
|
|
213
|
+
{
|
|
214
|
+
loader: require.resolve('sass-loader'),
|
|
215
|
+
options: {
|
|
216
|
+
api: 'modern-compiler',
|
|
217
|
+
implementation: require.resolve('sass-embedded'),
|
|
218
|
+
sassOptions: { quietDeps: true },
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
}, exports.scssRuleConfig),
|
|
223
|
+
(0, lodash_1.merge)({
|
|
224
|
+
test: /\.(png|jpe?g|gif|svg)$/i,
|
|
225
|
+
type: 'asset/resource',
|
|
226
|
+
}, exports.assetRuleConfig),
|
|
227
|
+
],
|
|
228
|
+
}, mode, devtool: mode === production ? 'hidden-nosources-source-map' : 'source-map', devServer: {
|
|
229
|
+
headers: {
|
|
230
|
+
'Access-Control-Allow-Origin': '*',
|
|
231
|
+
},
|
|
232
|
+
devMiddleware: {
|
|
233
|
+
writeToDisk: true,
|
|
234
|
+
},
|
|
235
|
+
static: [(0, path_1.resolve)(root, outDir)],
|
|
236
|
+
}, watchOptions: (0, lodash_1.merge)({
|
|
237
|
+
ignored: ['.git', 'test-results'],
|
|
238
|
+
}, exports.watchConfig), performance: {
|
|
239
|
+
hints: mode === production && 'warning',
|
|
240
|
+
}, optimization: (0, lodash_1.merge)({
|
|
241
|
+
// The defaults for both of these are 30; however, due to the modular nature of
|
|
242
|
+
// the frontend, we want each app to produce substantially
|
|
243
|
+
splitChunks: {
|
|
244
|
+
maxAsyncRequests: 3,
|
|
245
|
+
maxInitialRequests: 1,
|
|
246
|
+
},
|
|
247
|
+
minimizer: [new core_1.default.SwcJsMinimizerRspackPlugin(), new core_1.default.LightningCssMinimizerRspackPlugin()],
|
|
248
|
+
}, exports.optimizationConfig), plugins: [
|
|
249
|
+
new ts_checker_rspack_plugin_1.TsCheckerRspackPlugin(),
|
|
250
|
+
new clean_webpack_plugin_1.CleanWebpackPlugin(),
|
|
251
|
+
new webpack_bundle_analyzer_1.BundleAnalyzerPlugin({
|
|
252
|
+
analyzerMode: env && env.analyze ? 'server' : 'disabled',
|
|
253
|
+
}),
|
|
254
|
+
new core_1.DefinePlugin({
|
|
255
|
+
'process.env.FRAMEWORK_VERSION': JSON.stringify(frameworkVersion),
|
|
256
|
+
}),
|
|
257
|
+
new ModuleFederationPlugin({
|
|
258
|
+
// Look in the `esm-dynamic-loading` framework package for an explanation of how modules
|
|
259
|
+
// get loaded into the application.
|
|
260
|
+
name,
|
|
261
|
+
library: { type: 'var', name: slugify(name) },
|
|
262
|
+
filename,
|
|
263
|
+
exposes: {
|
|
264
|
+
'./start': srcFile,
|
|
265
|
+
},
|
|
266
|
+
shared: [...Object.keys(peerDependencies), '@openmrs/esm-framework/src/internal'].reduce((obj, depName) => {
|
|
267
|
+
var _a, _b;
|
|
268
|
+
if (depName === 'swr') {
|
|
269
|
+
// SWR is annoying with Module Federation
|
|
270
|
+
// See: https://github.com/webpack/webpack/issues/16125 and https://github.com/vercel/swr/issues/2356
|
|
271
|
+
obj['swr/_internal'] = {
|
|
272
|
+
requiredVersion: (_a = peerDependencies['swr']) !== null && _a !== void 0 ? _a : false,
|
|
273
|
+
strictVersion: false,
|
|
274
|
+
singleton: true,
|
|
275
|
+
import: 'swr/_internal',
|
|
276
|
+
shareKey: 'swr/_internal',
|
|
277
|
+
shareScope: 'default',
|
|
278
|
+
version: require('swr/package.json').version,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
obj[depName] = {
|
|
283
|
+
requiredVersion: (_b = peerDependencies[depName]) !== null && _b !== void 0 ? _b : false,
|
|
284
|
+
strictVersion: false,
|
|
285
|
+
singleton: true,
|
|
286
|
+
import: depName,
|
|
287
|
+
shareKey: depName,
|
|
288
|
+
shareScope: 'default',
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return obj;
|
|
292
|
+
}, {}),
|
|
293
|
+
}),
|
|
294
|
+
hasRoutesDefined &&
|
|
295
|
+
new core_1.CopyRspackPlugin({
|
|
296
|
+
patterns: [
|
|
297
|
+
{
|
|
298
|
+
from: routes,
|
|
299
|
+
transform: {
|
|
300
|
+
transformer: (content) => JSON.stringify(Object.assign({}, JSON.parse(content.toString()), {
|
|
301
|
+
version: mode === production ? version : (0, semver_1.inc)(version, 'prerelease', 'local'),
|
|
302
|
+
})),
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
}),
|
|
307
|
+
new webpack_stats_plugin_1.StatsWriterPlugin({
|
|
308
|
+
filename: `${filename}.buildmanifest.json`,
|
|
309
|
+
stats: {
|
|
310
|
+
all: false,
|
|
311
|
+
chunks: true,
|
|
312
|
+
},
|
|
313
|
+
}),
|
|
314
|
+
].filter(Boolean), resolve: {
|
|
315
|
+
extensions: ['.tsx', '.ts', '.jsx', '.js', '.scss', '.json'],
|
|
316
|
+
alias: {
|
|
317
|
+
'@openmrs/esm-framework': '@openmrs/esm-framework/src/internal',
|
|
318
|
+
'lodash.debounce': 'lodash-es/debounce',
|
|
319
|
+
'lodash.findlast': 'lodash-es/findLast',
|
|
320
|
+
'lodash.omit': 'lodash-es/omit',
|
|
321
|
+
'lodash.throttle': 'lodash-es/throttle',
|
|
322
|
+
},
|
|
323
|
+
} }, exports.overrides);
|
|
324
|
+
return (0, lodash_1.mergeWith)(baseConfig, exports.additionalConfig, mergeFunction);
|
|
325
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openmrs/rspack-config",
|
|
3
|
+
"version": "6.3.1-pre.2986",
|
|
4
|
+
"license": "MPL-2.0",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">= 12.0.0"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "jest --passWithNoTests --color",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"build:development": "tsc",
|
|
14
|
+
"lint": "eslint src --ext ts,tsx"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/openmrs/openmrs-esm-core.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/openmrs/openmrs-esm-core/issues"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"openmrs",
|
|
28
|
+
"microfrontends",
|
|
29
|
+
"webpack",
|
|
30
|
+
"config"
|
|
31
|
+
],
|
|
32
|
+
"homepage": "https://github.com/openmrs/openmrs-esm-core#readme",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@rspack/cli": "^1.3.11",
|
|
35
|
+
"@rspack/core": "^1.3.11",
|
|
36
|
+
"@swc/core": "^1.11.29",
|
|
37
|
+
"clean-webpack-plugin": "^4.0.0",
|
|
38
|
+
"copy-webpack-plugin": "^11.0.0",
|
|
39
|
+
"css-loader": "^5.2.7",
|
|
40
|
+
"lodash-es": "^4.17.21",
|
|
41
|
+
"sass-embedded": "^1.89.0",
|
|
42
|
+
"sass-loader": "^16.0.5",
|
|
43
|
+
"style-loader": "^3.3.4",
|
|
44
|
+
"swc-loader": "^0.2.6",
|
|
45
|
+
"ts-checker-rspack-plugin": "^1.1.1",
|
|
46
|
+
"webpack-bundle-analyzer": "^4.10.2",
|
|
47
|
+
"webpack-stats-plugin": "^1.1.3"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/lodash-es": "^4.17.12",
|
|
51
|
+
"typescript": "^4.7.0"
|
|
52
|
+
},
|
|
53
|
+
"stableVersion": "6.2.0"
|
|
54
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is the base webpack config for all OpenMRS 3.x modules.
|
|
3
|
+
*
|
|
4
|
+
* ## Usage
|
|
5
|
+
*
|
|
6
|
+
* You can use it as simply as
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* module.exports = require('openmrs/default-webpack-config');
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* or you can customize the configuration using merges and overrides
|
|
13
|
+
* like
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const config = require('openmrs/default-webpack-config');
|
|
17
|
+
* config.cssRuleConfig.rules = [myCustomRule];
|
|
18
|
+
* module.exports = config;
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## Development
|
|
22
|
+
*
|
|
23
|
+
* Advice for working on this file:
|
|
24
|
+
*
|
|
25
|
+
* Don't use `yarn link` or symlinks to work on it.
|
|
26
|
+
*
|
|
27
|
+
* After you `yarn build --watch`, do something like
|
|
28
|
+
* `watch "cp -R dist /path/to/packages/esm-patient-chart-app/webpack"`
|
|
29
|
+
* and then change the webpack line from
|
|
30
|
+
* `module.exports = require('openmrs/default-webpack-config');`
|
|
31
|
+
* to
|
|
32
|
+
* `module.exports = require('./webpack');`
|
|
33
|
+
*
|
|
34
|
+
* This is because Webpack has unpredictable behavior when working with
|
|
35
|
+
* symlinked files, **even when using absolute paths**. You read that right.
|
|
36
|
+
* Telling Webpack to use `/a/b/c`? If the Webpack config is symlinked
|
|
37
|
+
* from `/d/e/`, then it *might* in *some cases* try to import `/d/e/c`.
|
|
38
|
+
*/
|
|
39
|
+
import { existsSync, statSync } from 'fs';
|
|
40
|
+
import { basename, dirname, resolve } from 'path';
|
|
41
|
+
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
|
42
|
+
import { TsCheckerRspackPlugin } from 'ts-checker-rspack-plugin';
|
|
43
|
+
// eslint-disable-next-line no-restricted-imports
|
|
44
|
+
import { isArray, merge, mergeWith } from 'lodash';
|
|
45
|
+
import { inc } from 'semver';
|
|
46
|
+
import rspack, {
|
|
47
|
+
container,
|
|
48
|
+
CopyRspackPlugin,
|
|
49
|
+
DefinePlugin,
|
|
50
|
+
type ModuleOptions,
|
|
51
|
+
type RuleSetRule,
|
|
52
|
+
type RspackOptionsNormalized as RspackConfiguration,
|
|
53
|
+
} from '@rspack/core';
|
|
54
|
+
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
|
55
|
+
import { StatsWriterPlugin } from 'webpack-stats-plugin';
|
|
56
|
+
|
|
57
|
+
type OpenmrsRspackConfig = Omit<Partial<RspackConfiguration>, 'module'> & {
|
|
58
|
+
module: ModuleOptions;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const production = 'production';
|
|
62
|
+
const { ModuleFederationPlugin } = container;
|
|
63
|
+
|
|
64
|
+
function getFrameworkVersion() {
|
|
65
|
+
try {
|
|
66
|
+
const { version } = require('@openmrs/esm-framework/package.json');
|
|
67
|
+
return `^${version}`;
|
|
68
|
+
} catch {
|
|
69
|
+
return '5.x';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function makeIdent(name: string): string {
|
|
74
|
+
if (name.includes('/')) {
|
|
75
|
+
name = name.slice(name.indexOf('/'));
|
|
76
|
+
}
|
|
77
|
+
if (name.endsWith('-app')) {
|
|
78
|
+
name = name.slice(0, -4);
|
|
79
|
+
}
|
|
80
|
+
return name;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function mergeFunction(objValue: any, srcValue: any) {
|
|
84
|
+
if (isArray(objValue)) {
|
|
85
|
+
return objValue.concat(srcValue);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function slugify(name: string) {
|
|
90
|
+
return name.replace(/[\/\-@]/g, '_');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function fileExistsSync(name: string) {
|
|
94
|
+
return existsSync(name) && statSync(name).isFile();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* This object will be merged into the webpack config.
|
|
99
|
+
* Array values will be concatenated with the existing array.
|
|
100
|
+
* Make sure to modify this object and not reassign it.
|
|
101
|
+
*/
|
|
102
|
+
export const overrides: Partial<OpenmrsRspackConfig> = {};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The keys of this object will override the top-level keys
|
|
106
|
+
* of the webpack config.
|
|
107
|
+
* Make sure to modify this object and not reassign it.
|
|
108
|
+
*/
|
|
109
|
+
export const additionalConfig: Partial<OpenmrsRspackConfig> = {};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* This object will be merged into the webpack rule governing
|
|
113
|
+
* the loading of JS, JSX, TS, etc. files.
|
|
114
|
+
* Make sure to modify this object and not reassign it.
|
|
115
|
+
*/
|
|
116
|
+
export const scriptRuleConfig: Partial<RuleSetRule> = {};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* This object will be merged into the webpack rule governing
|
|
120
|
+
* the loading of CSS files.
|
|
121
|
+
* Make sure to modify this object and not reassign it.
|
|
122
|
+
*/
|
|
123
|
+
export const cssRuleConfig: Partial<RuleSetRule> = {};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* This object will be merged into the webpack rule governing
|
|
127
|
+
* the loading of SCSS files.
|
|
128
|
+
* Make sure to modify this object and not reassign it.
|
|
129
|
+
*/
|
|
130
|
+
export const scssRuleConfig: Partial<RuleSetRule> = {};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* This object will be merged into the webpack rule governing
|
|
134
|
+
* the loading of static asset files.
|
|
135
|
+
* Make sure to modify this object and not reassign it.
|
|
136
|
+
*/
|
|
137
|
+
export const assetRuleConfig: Partial<RuleSetRule> = {};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* This object will be merged into the webpack rule governing
|
|
141
|
+
* the watch options.
|
|
142
|
+
* Make sure to modify this object and not reassign it.
|
|
143
|
+
*/
|
|
144
|
+
export const watchConfig: Partial<OpenmrsRspackConfig['watchOptions']> = {};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* This object will be merged with the webpack optimization
|
|
148
|
+
* object.
|
|
149
|
+
* Make sure to modify this object and not reassign it.
|
|
150
|
+
*/
|
|
151
|
+
export const optimizationConfig: Partial<OpenmrsRspackConfig['optimization']> = {};
|
|
152
|
+
|
|
153
|
+
export default (env: Record<string, string>, argv: Record<string, string> = {}) => {
|
|
154
|
+
const root = process.cwd();
|
|
155
|
+
const { name, version, peerDependencies, browser, main, types } = require(resolve(root, 'package.json'));
|
|
156
|
+
// this typing is provably incorrect, but actually works
|
|
157
|
+
const mode = (argv.mode || process.env.NODE_ENV || 'development') as OpenmrsRspackConfig['mode'];
|
|
158
|
+
const filename = basename(browser || main);
|
|
159
|
+
const outDir = dirname(browser || main);
|
|
160
|
+
const srcFile = resolve(root, browser ? main : types);
|
|
161
|
+
const ident = makeIdent(name);
|
|
162
|
+
const frameworkVersion = getFrameworkVersion();
|
|
163
|
+
const routes = resolve(root, 'src', 'routes.json');
|
|
164
|
+
const hasRoutesDefined = fileExistsSync(routes);
|
|
165
|
+
|
|
166
|
+
if (!hasRoutesDefined) {
|
|
167
|
+
console.error(
|
|
168
|
+
'This app does not define a routes.json. This file is required for this app to be used by the OpenMRS 3 App Shell.',
|
|
169
|
+
);
|
|
170
|
+
// key-smash error code
|
|
171
|
+
// so this (hopefully) doesn't interfere with Webpack-specific exit codes
|
|
172
|
+
process.exit(9819023573289);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const cssLoader = {
|
|
176
|
+
loader: require.resolve('css-loader'),
|
|
177
|
+
options: {
|
|
178
|
+
modules: {
|
|
179
|
+
localIdentName: `${ident}__[name]__[local]___[hash:base64:5]`,
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const baseConfig: OpenmrsRspackConfig = {
|
|
185
|
+
// The only `entry` in the application is the app shell. Everything else is
|
|
186
|
+
// a Webpack Module Federation "remote." This ensures that there is always
|
|
187
|
+
// only one container context--i.e., if we had an entry point per module,
|
|
188
|
+
// WMF could get confused and not resolve shared dependencies correctly.
|
|
189
|
+
output: {
|
|
190
|
+
publicPath: 'auto',
|
|
191
|
+
path: resolve(root, outDir),
|
|
192
|
+
hashFunction: 'xxhash64',
|
|
193
|
+
},
|
|
194
|
+
module: {
|
|
195
|
+
rules: [
|
|
196
|
+
merge(
|
|
197
|
+
{
|
|
198
|
+
test: /\.m?(js|ts|tsx)$/,
|
|
199
|
+
exclude: /node_modules(?![\/\\]@openmrs)/,
|
|
200
|
+
loader: 'builtin:swc-loader',
|
|
201
|
+
options: {
|
|
202
|
+
jsc: {
|
|
203
|
+
parser: {
|
|
204
|
+
syntax: 'typescript',
|
|
205
|
+
tsx: true,
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
scriptRuleConfig,
|
|
211
|
+
),
|
|
212
|
+
merge(
|
|
213
|
+
{
|
|
214
|
+
test: /\.css$/,
|
|
215
|
+
use: [require.resolve('style-loader'), cssLoader],
|
|
216
|
+
},
|
|
217
|
+
cssRuleConfig,
|
|
218
|
+
),
|
|
219
|
+
merge(
|
|
220
|
+
{
|
|
221
|
+
test: /\.s[ac]ss$/i,
|
|
222
|
+
use: [
|
|
223
|
+
require.resolve('style-loader'),
|
|
224
|
+
cssLoader,
|
|
225
|
+
{
|
|
226
|
+
loader: require.resolve('sass-loader'),
|
|
227
|
+
options: {
|
|
228
|
+
api: 'modern-compiler',
|
|
229
|
+
implementation: require.resolve('sass-embedded'),
|
|
230
|
+
sassOptions: { quietDeps: true },
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
scssRuleConfig,
|
|
236
|
+
),
|
|
237
|
+
merge(
|
|
238
|
+
{
|
|
239
|
+
test: /\.(png|jpe?g|gif|svg)$/i,
|
|
240
|
+
type: 'asset/resource',
|
|
241
|
+
},
|
|
242
|
+
assetRuleConfig,
|
|
243
|
+
),
|
|
244
|
+
],
|
|
245
|
+
},
|
|
246
|
+
mode,
|
|
247
|
+
devtool: mode === production ? 'hidden-nosources-source-map' : 'source-map',
|
|
248
|
+
devServer: {
|
|
249
|
+
headers: {
|
|
250
|
+
'Access-Control-Allow-Origin': '*',
|
|
251
|
+
},
|
|
252
|
+
devMiddleware: {
|
|
253
|
+
writeToDisk: true,
|
|
254
|
+
},
|
|
255
|
+
static: [resolve(root, outDir)],
|
|
256
|
+
},
|
|
257
|
+
watchOptions: merge(
|
|
258
|
+
{
|
|
259
|
+
ignored: ['.git', 'test-results'],
|
|
260
|
+
},
|
|
261
|
+
watchConfig,
|
|
262
|
+
),
|
|
263
|
+
performance: {
|
|
264
|
+
hints: mode === production && 'warning',
|
|
265
|
+
},
|
|
266
|
+
optimization: merge(
|
|
267
|
+
{
|
|
268
|
+
// The defaults for both of these are 30; however, due to the modular nature of
|
|
269
|
+
// the frontend, we want each app to produce substantially
|
|
270
|
+
splitChunks: {
|
|
271
|
+
maxAsyncRequests: 3,
|
|
272
|
+
maxInitialRequests: 1,
|
|
273
|
+
},
|
|
274
|
+
minimizer: [new rspack.SwcJsMinimizerRspackPlugin(), new rspack.LightningCssMinimizerRspackPlugin()],
|
|
275
|
+
},
|
|
276
|
+
optimizationConfig,
|
|
277
|
+
),
|
|
278
|
+
plugins: [
|
|
279
|
+
new TsCheckerRspackPlugin(),
|
|
280
|
+
new CleanWebpackPlugin(),
|
|
281
|
+
new BundleAnalyzerPlugin({
|
|
282
|
+
analyzerMode: env && env.analyze ? 'server' : 'disabled',
|
|
283
|
+
}),
|
|
284
|
+
new DefinePlugin({
|
|
285
|
+
'process.env.FRAMEWORK_VERSION': JSON.stringify(frameworkVersion),
|
|
286
|
+
}),
|
|
287
|
+
new ModuleFederationPlugin({
|
|
288
|
+
// Look in the `esm-dynamic-loading` framework package for an explanation of how modules
|
|
289
|
+
// get loaded into the application.
|
|
290
|
+
name,
|
|
291
|
+
library: { type: 'var', name: slugify(name) },
|
|
292
|
+
filename,
|
|
293
|
+
exposes: {
|
|
294
|
+
'./start': srcFile,
|
|
295
|
+
},
|
|
296
|
+
shared: [...Object.keys(peerDependencies), '@openmrs/esm-framework/src/internal'].reduce((obj, depName) => {
|
|
297
|
+
if (depName === 'swr') {
|
|
298
|
+
// SWR is annoying with Module Federation
|
|
299
|
+
// See: https://github.com/webpack/webpack/issues/16125 and https://github.com/vercel/swr/issues/2356
|
|
300
|
+
obj['swr/_internal'] = {
|
|
301
|
+
requiredVersion: peerDependencies['swr'] ?? false,
|
|
302
|
+
strictVersion: false,
|
|
303
|
+
singleton: true,
|
|
304
|
+
import: 'swr/_internal',
|
|
305
|
+
shareKey: 'swr/_internal',
|
|
306
|
+
shareScope: 'default',
|
|
307
|
+
version: require('swr/package.json').version,
|
|
308
|
+
};
|
|
309
|
+
} else {
|
|
310
|
+
obj[depName] = {
|
|
311
|
+
requiredVersion: peerDependencies[depName] ?? false,
|
|
312
|
+
strictVersion: false,
|
|
313
|
+
singleton: true,
|
|
314
|
+
import: depName,
|
|
315
|
+
shareKey: depName,
|
|
316
|
+
shareScope: 'default',
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return obj;
|
|
321
|
+
}, {}),
|
|
322
|
+
}),
|
|
323
|
+
hasRoutesDefined &&
|
|
324
|
+
new CopyRspackPlugin({
|
|
325
|
+
patterns: [
|
|
326
|
+
{
|
|
327
|
+
from: routes,
|
|
328
|
+
transform: {
|
|
329
|
+
transformer: (content) =>
|
|
330
|
+
JSON.stringify(
|
|
331
|
+
Object.assign({}, JSON.parse(content.toString()), {
|
|
332
|
+
version: mode === production ? version : inc(version, 'prerelease', 'local'),
|
|
333
|
+
}),
|
|
334
|
+
),
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
}),
|
|
339
|
+
new StatsWriterPlugin({
|
|
340
|
+
filename: `${filename}.buildmanifest.json`,
|
|
341
|
+
stats: {
|
|
342
|
+
all: false,
|
|
343
|
+
chunks: true,
|
|
344
|
+
},
|
|
345
|
+
}),
|
|
346
|
+
].filter(Boolean),
|
|
347
|
+
resolve: {
|
|
348
|
+
extensions: ['.tsx', '.ts', '.jsx', '.js', '.scss', '.json'],
|
|
349
|
+
alias: {
|
|
350
|
+
'@openmrs/esm-framework': '@openmrs/esm-framework/src/internal',
|
|
351
|
+
'lodash.debounce': 'lodash-es/debounce',
|
|
352
|
+
'lodash.findlast': 'lodash-es/findLast',
|
|
353
|
+
'lodash.omit': 'lodash-es/omit',
|
|
354
|
+
'lodash.throttle': 'lodash-es/throttle',
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
...overrides,
|
|
358
|
+
};
|
|
359
|
+
return mergeWith(baseConfig, additionalConfig, mergeFunction);
|
|
360
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"esModuleInterop": true,
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"target": "es2015",
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"jsx": "react",
|
|
9
|
+
"strictNullChecks": true,
|
|
10
|
+
"moduleResolution": "node",
|
|
11
|
+
"outDir": "dist",
|
|
12
|
+
"lib": ["es5", "es2015", "es2015.promise", "es2016.array.include", "es2018"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"]
|
|
15
|
+
}
|