@salesforce/pwa-kit-dev 3.8.0-preview.0-basepath → 3.8.0-preview.1-basepath

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.
Files changed (60) hide show
  1. package/configs/babel/babel-config.js +33 -0
  2. package/configs/eslint/README.md +21 -0
  3. package/configs/eslint/eslint-config.js +11 -0
  4. package/configs/eslint/index.js +11 -0
  5. package/configs/eslint/no-react.js +18 -0
  6. package/configs/eslint/partials/base.js +38 -0
  7. package/configs/eslint/partials/jest.js +24 -0
  8. package/configs/eslint/partials/react.js +29 -0
  9. package/configs/eslint/partials/typescript-permit-any.js +31 -0
  10. package/configs/eslint/partials/typescript.js +17 -0
  11. package/configs/eslint/recommended.js +20 -0
  12. package/configs/eslint/safe-types.js +20 -0
  13. package/configs/jest/jest-babel-transform.js +19 -0
  14. package/configs/jest/jest.config.js +40 -0
  15. package/configs/jest/mocks/fileMock.js +9 -0
  16. package/configs/jest/mocks/styleMock.js +9 -0
  17. package/configs/jest/mocks/svgMock.js +11 -0
  18. package/configs/webpack/config-names.js +19 -0
  19. package/configs/webpack/config.js +406 -0
  20. package/configs/webpack/overrides-plugin.js +168 -0
  21. package/configs/webpack/overrides-plugin.test.js +388 -0
  22. package/configs/webpack/plugins.js +86 -0
  23. package/configs/webpack/test/overrides/exists.js +7 -0
  24. package/configs/webpack/test/overrides/newExtension.js +7 -0
  25. package/configs/webpack/test/overrides/path/data.js +7 -0
  26. package/configs/webpack/test/overrides/path/index.js +7 -0
  27. package/configs/webpack/test/overrides/path/index.mock.js +7 -0
  28. package/configs/webpack/test/overrides/path/nested/icon.svg +0 -0
  29. package/configs/webpack/test/package.json +13 -0
  30. package/configs/webpack/utils.js +23 -0
  31. package/package.json +5 -4
  32. package/ssr/server/build-dev-server.js +468 -0
  33. package/ssr/server/build-dev-server.test.js +661 -0
  34. package/ssr/server/loading-screen/css/main.css +272 -0
  35. package/ssr/server/loading-screen/css/normalize.css +349 -0
  36. package/ssr/server/loading-screen/img/cloud-1.svg +1 -0
  37. package/ssr/server/loading-screen/img/cloud-2.svg +1 -0
  38. package/ssr/server/loading-screen/img/cloud-3.svg +1 -0
  39. package/ssr/server/loading-screen/img/cloud.svg +1 -0
  40. package/ssr/server/loading-screen/img/codey-arm.svg +1 -0
  41. package/ssr/server/loading-screen/img/codey-bear.svg +1 -0
  42. package/ssr/server/loading-screen/img/codey-bg.svg +1 -0
  43. package/ssr/server/loading-screen/img/codey-cloud.svg +1 -0
  44. package/ssr/server/loading-screen/img/codey-search.svg +1 -0
  45. package/ssr/server/loading-screen/img/codey.svg +1 -0
  46. package/ssr/server/loading-screen/img/codeyCarry.svg +1 -0
  47. package/ssr/server/loading-screen/img/devDocumentation.svg +1 -0
  48. package/ssr/server/loading-screen/img/devGithub.svg +1 -0
  49. package/ssr/server/loading-screen/img/devTrailhead.svg +1 -0
  50. package/ssr/server/loading-screen/img/logo.svg +1 -0
  51. package/ssr/server/loading-screen/img/slds_spinner_brand_9EA9F1.gif +0 -0
  52. package/ssr/server/loading-screen/index.html +129 -0
  53. package/ssr/server/test_fixtures/app/main.js +6 -0
  54. package/ssr/server/test_fixtures/app/static/favicon.ico +0 -0
  55. package/ssr/server/test_fixtures/localhost.pem +45 -0
  56. package/utils/mocks/dependency-tree-mock-data.js +127 -0
  57. package/utils/script-utils.js +497 -0
  58. package/utils/script-utils.test.js +496 -0
  59. package/utils/test-fixtures/minimal-built-app/ssr.js +9 -0
  60. package/utils/test-fixtures/minimal-built-app/static/favicon.ico +0 -0
@@ -0,0 +1,406 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.EXT_OVERRIDES_DIR_NO_SLASH = exports.EXT_OVERRIDES_DIR = exports.EXT_EXTENDS_WIN = exports.EXT_EXTENDS = exports.EXT_EXTENDABLE = exports.DEPS_TO_DEDUPE = void 0;
7
+ var _path = _interopRequireWildcard(require("path"));
8
+ var _fsExtra = _interopRequireDefault(require("fs-extra"));
9
+ var _webpack = _interopRequireDefault(require("webpack"));
10
+ var _webpackNotifier = _interopRequireDefault(require("webpack-notifier"));
11
+ var _copyWebpackPlugin = _interopRequireDefault(require("copy-webpack-plugin"));
12
+ var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");
13
+ var _webpackPlugin = _interopRequireDefault(require("@loadable/webpack-plugin"));
14
+ var _reactRefreshWebpackPlugin = _interopRequireDefault(require("@pmmmwh/react-refresh-webpack-plugin"));
15
+ var _speedMeasureWebpackPlugin = _interopRequireDefault(require("speed-measure-webpack-plugin"));
16
+ var _ssrPaths = require("@salesforce/pwa-kit-runtime/utils/ssr-paths");
17
+ var _overridesPlugin = _interopRequireDefault(require("./overrides-plugin"));
18
+ var _plugins = require("./plugins");
19
+ var _configNames = require("./config-names");
20
+ var _pkg$ccExtensibility, _pkg$ccExtensibility2, _pkg$ccExtensibility3, _pkg$ccExtensibility4, _pkg$ccExtensibility5, _pkg$ccExtensibility6, _pkg$ccExtensibility7, _pkg$ccExtensibility8, _pkg$ccExtensibility9, _pkg$ccExtensibility10, _pkg$ccExtensibility11, _pkg$ccExtensibility12;
21
+ /*
22
+ * Copyright (c) 2021, salesforce.com, inc.
23
+ * All rights reserved.
24
+ * SPDX-License-Identifier: BSD-3-Clause
25
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
26
+ */
27
+ /* eslint-env node */
28
+ // For more information on these settings, see https://webpack.js.org/configuration
29
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
30
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
31
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
32
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
33
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
34
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
35
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
36
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
37
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
38
+ const projectDir = process.cwd();
39
+ const pkg = _fsExtra.default.readJsonSync((0, _path.resolve)(projectDir, 'package.json'));
40
+ const buildDir = process.env.PWA_KIT_BUILD_DIR ? (0, _path.resolve)(process.env.PWA_KIT_BUILD_DIR) : (0, _path.resolve)(projectDir, 'build');
41
+ const production = 'production';
42
+ const development = 'development';
43
+ const analyzeBundle = process.env.MOBIFY_ANALYZE === 'true';
44
+ const mode = process.env.NODE_ENV === production ? production : development;
45
+ const INSPECT = process.execArgv.some(arg => /^--inspect(?:-brk)?(?:$|=)/.test(arg));
46
+ const DEBUG = mode !== production && process.env.DEBUG === 'true';
47
+ const CI = process.env.CI;
48
+ const disableHMR = process.env.HMR === 'false';
49
+ if ([production, development].indexOf(mode) < 0) {
50
+ throw new Error(`Invalid mode "${mode}"`);
51
+ }
52
+
53
+ // for API convenience, add the leading slash if missing
54
+ const EXT_OVERRIDES_DIR = exports.EXT_OVERRIDES_DIR = typeof (pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility = pkg.ccExtensibility) === null || _pkg$ccExtensibility === void 0 ? void 0 : _pkg$ccExtensibility.overridesDir) === 'string' && !(pkg !== null && pkg !== void 0 && (_pkg$ccExtensibility2 = pkg.ccExtensibility) !== null && _pkg$ccExtensibility2 !== void 0 && (_pkg$ccExtensibility3 = _pkg$ccExtensibility2.overridesDir) !== null && _pkg$ccExtensibility3 !== void 0 && _pkg$ccExtensibility3.match(/(^\/|^\\)/)) ? '/' + (pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility4 = pkg.ccExtensibility) === null || _pkg$ccExtensibility4 === void 0 ? void 0 : (_pkg$ccExtensibility5 = _pkg$ccExtensibility4.overridesDir) === null || _pkg$ccExtensibility5 === void 0 ? void 0 : _pkg$ccExtensibility5.replace(/\\/g, '/')) : pkg !== null && pkg !== void 0 && (_pkg$ccExtensibility6 = pkg.ccExtensibility) !== null && _pkg$ccExtensibility6 !== void 0 && _pkg$ccExtensibility6.overridesDir ? pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility7 = pkg.ccExtensibility) === null || _pkg$ccExtensibility7 === void 0 ? void 0 : (_pkg$ccExtensibility8 = _pkg$ccExtensibility7.overridesDir) === null || _pkg$ccExtensibility8 === void 0 ? void 0 : _pkg$ccExtensibility8.replace(/\\/g, '/') : '';
55
+ const EXT_OVERRIDES_DIR_NO_SLASH = exports.EXT_OVERRIDES_DIR_NO_SLASH = EXT_OVERRIDES_DIR === null || EXT_OVERRIDES_DIR === void 0 ? void 0 : EXT_OVERRIDES_DIR.replace(/^\//, '');
56
+ const EXT_EXTENDS = exports.EXT_EXTENDS = pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility9 = pkg.ccExtensibility) === null || _pkg$ccExtensibility9 === void 0 ? void 0 : _pkg$ccExtensibility9.extends;
57
+ const EXT_EXTENDS_WIN = exports.EXT_EXTENDS_WIN = pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility10 = pkg.ccExtensibility) === null || _pkg$ccExtensibility10 === void 0 ? void 0 : (_pkg$ccExtensibility11 = _pkg$ccExtensibility10.extends) === null || _pkg$ccExtensibility11 === void 0 ? void 0 : _pkg$ccExtensibility11.replace('/', '\\');
58
+ const EXT_EXTENDABLE = exports.EXT_EXTENDABLE = pkg === null || pkg === void 0 ? void 0 : (_pkg$ccExtensibility12 = pkg.ccExtensibility) === null || _pkg$ccExtensibility12 === void 0 ? void 0 : _pkg$ccExtensibility12.extendable;
59
+
60
+ // TODO: can these be handled in package.json as peerDependencies?
61
+ // https://salesforce-internal.slack.com/archives/C0DKK1FJS/p1672939909212589
62
+
63
+ // due to to how the sdks work and the potential of these npm deps coming
64
+ // from multiple places, we need to force them to one place where they're found
65
+ const DEPS_TO_DEDUPE = exports.DEPS_TO_DEDUPE = ['babel-runtime', '@tanstack/react-query', '@loadable/component', '@loadable/server', '@loadable/webpack-plugin', 'svg-sprite-loader', 'react', 'react-router-dom', 'react-dom', 'react-helmet', 'webpack-hot-middleware', 'react-intl', '@chakra-ui/icons', '@chakra-ui/react', '@chakra-ui/skip-nav', '@emotion/react'];
66
+ if (EXT_EXTENDABLE && EXT_EXTENDS) {
67
+ const extendsAsArr = Array.isArray(EXT_EXTENDS) ? EXT_EXTENDS : [EXT_EXTENDS];
68
+ const conflicts = extendsAsArr.filter(x => EXT_EXTENDABLE === null || EXT_EXTENDABLE === void 0 ? void 0 : EXT_EXTENDABLE.includes(x));
69
+ if (conflicts !== null && conflicts !== void 0 && conflicts.length) {
70
+ throw new Error(`Dependencies in 'extendable' and 'extends' cannot overlap, fix these: ${conflicts.join(', ')}"`);
71
+ }
72
+ }
73
+ const getBundleAnalyzerPlugin = (name = 'report', pluginOptions) => new _webpackBundleAnalyzer.BundleAnalyzerPlugin(_objectSpread({
74
+ analyzerMode: 'static',
75
+ defaultSizes: 'gzip',
76
+ openAnalyzer: CI !== 'true',
77
+ generateStatsFile: true,
78
+ reportFilename: `${name}.html`,
79
+ reportTitle: `${name} bundle analysis result`,
80
+ statsFilename: `${name}-analyzer-stats.json`
81
+ }, pluginOptions));
82
+ const entryPointExists = segments => {
83
+ for (let ext of ['.js', '.jsx', '.ts', '.tsx']) {
84
+ const primary = (0, _path.resolve)(projectDir, ...segments) + ext;
85
+ const override = EXT_OVERRIDES_DIR ? (0, _path.resolve)(projectDir, EXT_OVERRIDES_DIR_NO_SLASH, ...segments) + ext : null;
86
+ if (_fsExtra.default.existsSync(primary) || override && _fsExtra.default.existsSync(override)) {
87
+ return true;
88
+ }
89
+ }
90
+ return false;
91
+ };
92
+ const getAppEntryPoint = () => {
93
+ return (0, _path.resolve)('./', EXT_OVERRIDES_DIR_NO_SLASH, 'app', 'main');
94
+ };
95
+ const findDepInStack = pkg => {
96
+ // Look for the SDK node_modules in two places because in CI,
97
+ // pwa-kit-dev is published under a 'dist' directory, which
98
+ // changes this file's location relative to the package root.
99
+ const candidates = [(0, _path.resolve)(projectDir, 'node_modules', pkg), (0, _path.resolve)(__dirname, '..', '..', 'node_modules', pkg), (0, _path.resolve)(__dirname, '..', '..', '..', 'node_modules', pkg)];
100
+ let candidate;
101
+ for (candidate of candidates) {
102
+ if (_fsExtra.default.existsSync(candidate)) {
103
+ return candidate;
104
+ }
105
+ }
106
+ return candidate;
107
+ };
108
+ const baseConfig = target => {
109
+ if (!['web', 'node'].includes(target)) {
110
+ throw Error(`The value "${target}" is not a supported webpack target`);
111
+ }
112
+ class Builder {
113
+ constructor() {
114
+ this.config = _objectSpread(_objectSpread({
115
+ watchOptions: {
116
+ aggregateTimeout: 1000
117
+ },
118
+ target,
119
+ mode
120
+ }, target === 'node' ? {
121
+ ignoreWarnings: [
122
+ // These can be ignored fairly safely for node targets, where
123
+ // bundle size is not super critical. Express generates this warning,
124
+ // because it uses dynamic require() calls, which cause Webpack to
125
+ // bundle the whole library.
126
+ /Critical dependency: the request of a dependency is an expression/]
127
+ } : {}), {}, {
128
+ infrastructureLogging: {
129
+ level: 'error'
130
+ },
131
+ stats: {
132
+ all: false,
133
+ modules: false,
134
+ errors: true,
135
+ warnings: true,
136
+ moduleTrace: true,
137
+ errorDetails: true,
138
+ colors: true,
139
+ assets: false,
140
+ excludeAssets: [/.*img\/.*/, /.*svg\/.*/, /.*json\/.*/, /.*static\/.*/]
141
+ },
142
+ optimization: {
143
+ minimize: mode === production
144
+ },
145
+ output: {
146
+ publicPath: '',
147
+ path: buildDir
148
+ },
149
+ resolve: _objectSpread(_objectSpread({}, EXT_EXTENDS && EXT_OVERRIDES_DIR ? {
150
+ plugins: [new _overridesPlugin.default({
151
+ extends: [EXT_EXTENDS],
152
+ overridesDir: EXT_OVERRIDES_DIR,
153
+ projectDir: process.cwd()
154
+ })]
155
+ } : {}), {}, {
156
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
157
+ alias: _objectSpread(_objectSpread(_objectSpread({}, _extends(...DEPS_TO_DEDUPE.map(dep => ({
158
+ [dep]: findDepInStack(dep)
159
+ })))), EXT_OVERRIDES_DIR && EXT_EXTENDS ? _extends(
160
+ // NOTE: when an array of `extends` dirs are accepted, don't coerce here
161
+ ...[EXT_EXTENDS].map(extendTarget => ({
162
+ [extendTarget]: _path.default.resolve(projectDir, 'node_modules', ...extendTarget.split('/'))
163
+ }))) : {}), EXT_EXTENDABLE ? _extends(...[EXT_EXTENDABLE].map(item => ({
164
+ [item]: _path.default.resolve(projectDir)
165
+ }))) : {})
166
+ }, target === 'web' ? {
167
+ fallback: {
168
+ crypto: false
169
+ }
170
+ } : {}),
171
+ plugins: [new _webpack.default.DefinePlugin({
172
+ DEBUG,
173
+ NODE_ENV: `'${process.env.NODE_ENV}'`,
174
+ WEBPACK_TARGET: `'${target}'`,
175
+ ['global.GENTLY']: false
176
+ }), mode === development && new _webpack.default.NoEmitOnErrorsPlugin(), (0, _plugins.sdkReplacementPlugin)(),
177
+ // Don't chunk if it's a node target – faster Lambda startup.
178
+ target === 'node' && new _webpack.default.optimize.LimitChunkCountPlugin({
179
+ maxChunks: 1
180
+ })].filter(Boolean),
181
+ module: {
182
+ rules: [ruleForBabelLoader(), target === 'node' && {
183
+ test: /\.svg$/,
184
+ loader: findDepInStack('svg-sprite-loader')
185
+ }, target === 'web' && {
186
+ test: /\.svg$/,
187
+ loader: findDepInStack('ignore-loader')
188
+ }, {
189
+ test: /\.html$/,
190
+ exclude: /node_modules/,
191
+ use: {
192
+ loader: findDepInStack('html-loader')
193
+ }
194
+ }, {
195
+ test: /\.js$/,
196
+ enforce: 'pre',
197
+ use: {
198
+ loader: findDepInStack('source-map-loader')
199
+ }
200
+ }].filter(Boolean)
201
+ }
202
+ });
203
+ }
204
+ extend(callback) {
205
+ this.config = callback(this.config);
206
+ return this;
207
+ }
208
+ build() {
209
+ // Clean up temporary properties, to be compatible with the config schema
210
+ this.config.module.rules.filter(rule => rule.id).forEach(rule => delete rule.id);
211
+ return this.config;
212
+ }
213
+ }
214
+ return new Builder();
215
+ };
216
+ const withChunking = config => {
217
+ return _objectSpread(_objectSpread({}, config), {}, {
218
+ output: _objectSpread(_objectSpread({}, config.output), {}, {
219
+ filename: '[name].js',
220
+ chunkFilename: '[name].js' // Support chunking with @loadable/components
221
+ }),
222
+ optimization: {
223
+ minimize: mode === production,
224
+ splitChunks: {
225
+ cacheGroups: {
226
+ vendor: {
227
+ // Three scenarios that we'd like to chunk vendor.js:
228
+ // 1. The package is in node_modules
229
+ // 2. The package is one of the monorepo packages.
230
+ // This is for local development to ensure the bundle
231
+ // composition is the same as a production build
232
+ // 3. If extending another template, don't include the
233
+ // baseline route files in vendor.js
234
+ test: module => {
235
+ var _module$context, _module$context2, _module$context2$matc;
236
+ if (EXT_EXTENDS && EXT_OVERRIDES_DIR && module !== null && module !== void 0 && (_module$context = module.context) !== null && _module$context !== void 0 && _module$context.includes(`${_path.default.sep}${_path.default.sep === '/' ? EXT_EXTENDS : EXT_EXTENDS_WIN}${_path.default.sep}`)) {
237
+ return false;
238
+ }
239
+ return module === null || module === void 0 ? void 0 : (_module$context2 = module.context) === null || _module$context2 === void 0 ? void 0 : (_module$context2$matc = _module$context2.match) === null || _module$context2$matc === void 0 ? void 0 : _module$context2$matc.call(_module$context2, /(node_modules)|(packages\/(.*)dist)/);
240
+ },
241
+ name: 'vendor',
242
+ chunks: 'all'
243
+ }
244
+ }
245
+ }
246
+ }
247
+ });
248
+ };
249
+ const staticFolderCopyPlugin = new _copyWebpackPlugin.default({
250
+ patterns: [{
251
+ from: _path.default.resolve(`${EXT_OVERRIDES_DIR ? EXT_OVERRIDES_DIR_NO_SLASH + '/' : ''}app/static`).replace(/\\/g, '/'),
252
+ to: `static/`,
253
+ noErrorOnMissing: true
254
+ }]
255
+ });
256
+ const ruleForBabelLoader = babelPlugins => {
257
+ return _objectSpread(_objectSpread({
258
+ id: 'babel-loader',
259
+ test: /(\.js(x?)|\.ts(x?))$/
260
+ }, EXT_OVERRIDES_DIR && EXT_EXTENDS ?
261
+ // TODO: handle for array here when that's supported
262
+ {
263
+ exclude: new RegExp(`${_path.default.sep}node_modules(?!${_path.default.sep}${_path.default.sep === '/' ? EXT_EXTENDS : EXT_EXTENDS_WIN})`)
264
+ } : {
265
+ exclude: /node_modules/
266
+ }), {}, {
267
+ use: [{
268
+ loader: findDepInStack('babel-loader'),
269
+ options: _objectSpread({
270
+ rootMode: 'upward',
271
+ cacheDirectory: true
272
+ }, babelPlugins ? {
273
+ plugins: babelPlugins
274
+ } : {})
275
+ }]
276
+ });
277
+ };
278
+ const findAndReplace = (array = [], findFn = () => {}, replacement) => {
279
+ const clone = array.slice(0);
280
+ const index = clone.findIndex(findFn);
281
+ if (index === -1) {
282
+ return array;
283
+ }
284
+ clone.splice(index, 1, replacement);
285
+ return clone;
286
+ };
287
+ const enableReactRefresh = config => {
288
+ if (mode !== development || disableHMR) {
289
+ return config;
290
+ }
291
+ const newRule = ruleForBabelLoader([require.resolve('react-refresh/babel')]);
292
+ const rules = findAndReplace(config.module.rules, rule => rule.id === 'babel-loader', newRule);
293
+ const hmrBasePath = `${(0, _ssrPaths.getBundlePath)()}/development/`;
294
+ return _objectSpread(_objectSpread({}, config), {}, {
295
+ module: _objectSpread(_objectSpread({}, config.module), {}, {
296
+ rules
297
+ }),
298
+ entry: _objectSpread(_objectSpread({}, config.entry), {}, {
299
+ main: ['webpack-hot-middleware/client?path=/__mrt/hmr', getAppEntryPoint()]
300
+ }),
301
+ output: _objectSpread(_objectSpread({}, config.output), {}, {
302
+ publicPath: hmrBasePath
303
+ }),
304
+ plugins: [...config.plugins, new _webpack.default.HotModuleReplacementPlugin(), new _reactRefreshWebpackPlugin.default({
305
+ overlay: false
306
+ })]
307
+ });
308
+ };
309
+ const client = entryPointExists(['app', 'main']) && baseConfig('web').extend(withChunking).extend(config => {
310
+ return _objectSpread(_objectSpread({}, config), {}, {
311
+ // Must be named "client". See - https://www.npmjs.com/package/webpack-hot-server-middleware#usage
312
+ name: _configNames.CLIENT,
313
+ // use source map to make debugging easier
314
+ devtool: mode === development ? 'source-map' : false,
315
+ entry: {
316
+ main: getAppEntryPoint()
317
+ },
318
+ plugins: [...config.plugins, new _webpackPlugin.default({
319
+ writeToDisk: true
320
+ }), analyzeBundle && getBundleAnalyzerPlugin(_configNames.CLIENT)].filter(Boolean),
321
+ // Hide the performance hints, since we already have a similar `bundlesize` check in `template-retail-react-app` package
322
+ performance: {
323
+ hints: false
324
+ }
325
+ });
326
+ }).extend(enableReactRefresh).build();
327
+ const optional = (name, path) => {
328
+ return _fsExtra.default.existsSync(path) ? {
329
+ [name]: path
330
+ } : {};
331
+ };
332
+ const clientOptional = baseConfig('web').extend(config => {
333
+ return _objectSpread(_objectSpread({}, config), {}, {
334
+ name: _configNames.CLIENT_OPTIONAL,
335
+ entry: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, optional('loader', (0, _path.resolve)(projectDir, EXT_OVERRIDES_DIR, 'app', 'loader.js'))), optional('worker', (0, _path.resolve)(projectDir, 'worker', 'main.js'))), optional('core-polyfill', (0, _path.resolve)(projectDir, 'node_modules', 'core-js'))), optional('fetch-polyfill', (0, _path.resolve)(projectDir, 'node_modules', 'whatwg-fetch'))),
336
+ // use source map to make debugging easier
337
+ devtool: mode === development ? 'source-map' : false,
338
+ plugins: [...config.plugins, analyzeBundle && getBundleAnalyzerPlugin(_configNames.CLIENT_OPTIONAL)].filter(Boolean)
339
+ });
340
+ }).build();
341
+ const renderer = _fsExtra.default.existsSync((0, _path.resolve)(projectDir, 'node_modules', '@salesforce', 'pwa-kit-react-sdk')) && baseConfig('node').extend(config => {
342
+ return _objectSpread(_objectSpread({}, config), {}, {
343
+ // Must be named "server". See - https://www.npmjs.com/package/webpack-hot-server-middleware#usage
344
+ name: _configNames.SERVER,
345
+ entry: '@salesforce/pwa-kit-react-sdk/ssr/server/react-rendering.js',
346
+ // use eval-source-map for server-side debugging
347
+ devtool: mode === development && INSPECT ? 'eval-source-map' : false,
348
+ output: {
349
+ path: buildDir,
350
+ // We want to split the build on local development to reduce memory usage.
351
+ // It is required to have a single entry point for the remote server.
352
+ // See pwa-kit-runtime/ssr/server/build-remote-server.js render method.
353
+ filename: mode === development ? '[name]-server.js' : 'server-renderer.js',
354
+ libraryTarget: 'commonjs2'
355
+ },
356
+ plugins: [...config.plugins, staticFolderCopyPlugin,
357
+ // Keep this on the slowest-to-build item - the server-side bundle.
358
+ new _webpackNotifier.default({
359
+ title: `PWA Kit Project: ${pkg.name}`,
360
+ excludeWarnings: true,
361
+ skipFirstNotification: true
362
+ }), analyzeBundle && getBundleAnalyzerPlugin('server-renderer')].filter(Boolean)
363
+ });
364
+ }).build();
365
+ const ssr = (() => {
366
+ // Only compile the ssr file when we're building for prod.
367
+ if (mode === production) {
368
+ return baseConfig('node').extend(config => {
369
+ return _objectSpread(_objectSpread(_objectSpread({}, config), process.env.PWA_KIT_SSR_SOURCE_MAP === 'true' ? {
370
+ devtool: 'source-map'
371
+ } : {}), {}, {
372
+ // Must *not* be named "server". See - https://www.npmjs.com/package/webpack-hot-server-middleware#usage
373
+ name: _configNames.SSR,
374
+ entry: `.${EXT_OVERRIDES_DIR}/app/ssr.js`,
375
+ output: {
376
+ path: buildDir,
377
+ filename: 'ssr.js',
378
+ libraryTarget: 'commonjs2'
379
+ },
380
+ plugins: [...config.plugins, staticFolderCopyPlugin, analyzeBundle && getBundleAnalyzerPlugin(_configNames.SSR)].filter(Boolean)
381
+ });
382
+ }).build();
383
+ } else {
384
+ return undefined;
385
+ }
386
+ })();
387
+ const requestProcessor = entryPointExists(['app', 'request-processor']) && baseConfig('node').extend(config => {
388
+ return _objectSpread(_objectSpread({}, config), {}, {
389
+ name: _configNames.REQUEST_PROCESSOR,
390
+ // entry: './app/request-processor.js',
391
+ entry: `.${EXT_OVERRIDES_DIR}/app/request-processor.js`,
392
+ output: {
393
+ path: buildDir,
394
+ filename: 'request-processor.js',
395
+ libraryTarget: 'commonjs2'
396
+ },
397
+ // use eval-source-map for server-side debugging
398
+ devtool: mode === development && INSPECT ? 'eval-source-map' : false,
399
+ plugins: [...config.plugins, analyzeBundle && getBundleAnalyzerPlugin(_configNames.REQUEST_PROCESSOR)].filter(Boolean)
400
+ });
401
+ }).build();
402
+ module.exports = [client, ssr, renderer, clientOptional, requestProcessor].filter(Boolean).map(config => {
403
+ return new _speedMeasureWebpackPlugin.default({
404
+ disable: !process.env.MEASURE
405
+ }).wrap(config);
406
+ });
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _path = _interopRequireDefault(require("path"));
8
+ var _glob = _interopRequireDefault(require("glob"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ /*
11
+ * Copyright (c) 2023, Salesforce, Inc.
12
+ * All rights reserved.
13
+ * SPDX-License-Identifier: BSD-3-Clause
14
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
15
+ */
16
+
17
+ /**
18
+ * @class OverridesResolverPlugin
19
+ *
20
+ * This plugin provides the "Overrides" behavior of the Template Extensibility feature,
21
+ * allowing third party implementations that depend on an npm module for the base implementation
22
+ * and then overriding only specific files
23
+ */
24
+ class OverridesResolverPlugin {
25
+ /**
26
+ *
27
+ * @param options
28
+ * @param {string} options.overridesDir path to application base
29
+ * @param {string[]} options.overrides paths to overrides
30
+ * @param {string} options.projectDir path to project directory
31
+ */
32
+ constructor(options) {
33
+ var _options$overridesDir, _options$projectDir, _this$pkg, _this$pkg$ccExtensibi, _this$pkg$ccExtensibi2, _this$pkg$ccExtensibi3, _this$pkg2, _this$pkg2$ccExtensib;
34
+ // always coerce to posix fs paths, as glob sync and es6 imports don't use windows paths
35
+ this.overridesDir = ((_options$overridesDir = options.overridesDir) === null || _options$overridesDir === void 0 ? void 0 : _options$overridesDir.replace(/\\/g, '/')) || '';
36
+ this.extends = options.extends || [];
37
+ // always coerce to posix fs paths, as glob sync and es6 imports don't use windows paths
38
+ this.projectDir = (_options$projectDir = options.projectDir) === null || _options$projectDir === void 0 ? void 0 : _options$projectDir.replace(/\\/g, '/');
39
+ this._allSearchDirs = [this.projectDir + this.overridesDir, ...this.extends];
40
+ this.pkg = require(_path.default.resolve(this.projectDir, 'package.json'));
41
+ this.extendsHashMap = new Map();
42
+
43
+ // everything except directories
44
+ // NOTE that the glob library expects posix so we replace windows file paths here
45
+ const globPattern = `${(_this$pkg = this.pkg) === null || _this$pkg === void 0 ? void 0 : (_this$pkg$ccExtensibi = _this$pkg.ccExtensibility) === null || _this$pkg$ccExtensibi === void 0 ? void 0 : (_this$pkg$ccExtensibi2 = _this$pkg$ccExtensibi.overridesDir) === null || _this$pkg$ccExtensibi2 === void 0 ? void 0 : (_this$pkg$ccExtensibi3 = _this$pkg$ccExtensibi2.replace(/\\/g, '/')) === null || _this$pkg$ccExtensibi3 === void 0 ? void 0 : _this$pkg$ccExtensibi3.replace(/^\//, '')}/**/*.*`;
46
+ const overridesFsRead = _glob.default.sync(globPattern);
47
+ const overrideReplace = ((_this$pkg2 = this.pkg) === null || _this$pkg2 === void 0 ? void 0 : (_this$pkg2$ccExtensib = _this$pkg2.ccExtensibility) === null || _this$pkg2$ccExtensib === void 0 ? void 0 : _this$pkg2$ccExtensib.overridesDir) + '/';
48
+
49
+ // For each filepath in the overrides directory:
50
+ // Split it in one of two ways:
51
+ // If the filepath is like /pages/home/index.js,
52
+ // split on index and 'key' is /pages/home/
53
+ // If the filepath is like /pages/home/data.js,
54
+ // split on the . and 'key' is /pages/home/data
55
+ // The negative lookaheads ensure the split occurs on the last occurence of .
56
+ // This avoids collisions when both index.js and index.test.js are
57
+ // present in the same directory
58
+ overridesFsRead.forEach(item => {
59
+ const end = item.substring(item.lastIndexOf('/index'));
60
+ const [key, ...rest] = item.split(/(index(?!(\.[^.]*\.))|\.(?!([^.]*\.)))/);
61
+ this.extendsHashMap.set(key.replace(overrideReplace, '').replace(/\/$/, ''), [end, rest.filter(Boolean)]);
62
+ });
63
+ }
64
+ /**
65
+ * This takes an import with the overrides dir / extends package removed and finds
66
+ * the corresponding path from overridesFsRead
67
+ *
68
+ * Ie. Given an import @salesforce/retail-react-app/app/components/header,
69
+ * requestPath is app/components/header
70
+ *
71
+ * @param requestPath - relative import path
72
+ * @param dirs - this._allSearchDirs
73
+ */
74
+ findFileFromMap(requestPath, dirs) {
75
+ const fileExt = _path.default.extname(requestPath);
76
+ for (const dir of dirs) {
77
+ let base = _path.default.join(dir, requestPath);
78
+ if (fileExt) {
79
+ const noExtPath = requestPath.replace(fileExt, '');
80
+ if (this.extendsHashMap.has(noExtPath)) {
81
+ return base;
82
+ }
83
+ } else {
84
+ if (this.extendsHashMap.has(requestPath)) {
85
+ const end = this.extendsHashMap.get(requestPath)[1];
86
+ const isRequestingIndex = end[0] === 'index';
87
+ let result = (base === null || base === void 0 ? void 0 : base.replace(/$\//, '')) + end.join('');
88
+ if (isRequestingIndex) {
89
+ result = _path.default.join(base, this.extendsHashMap.get(requestPath)[1].join(''));
90
+ }
91
+ return result;
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ /*
98
+ Given an import request, this function removes the override dir
99
+ or the package name defined in extends.
100
+ For example:
101
+ import * from 'src/configs/webpack/test/overrides/path/data.js resolves to
102
+ path/data.js
103
+ import * from '@salesforce/retail-react-app/app/component/header resolves to
104
+ app/component/header
105
+ TODO: This function is only called if isFromExtends is true. In other words,
106
+ this function is only called if the import request contains a package in extends
107
+ We can probably simplify this function or rename it
108
+ */
109
+ toOverrideRelative(filepath) {
110
+ const override = this._allSearchDirs.find(dir => {
111
+ return filepath.indexOf(dir) === 0;
112
+ });
113
+ return filepath.substring((override === null || override === void 0 ? void 0 : override.length) + 1);
114
+ }
115
+
116
+ /*
117
+ Helper function that returns true only if the import request points to a package in 'extends'
118
+ and the issuer path (the file making the import request) is not located in the overrides dir.
119
+ If true, we re-route the import request to the overrides dir.
120
+ If false, the import request proceeds to the base package in node_modules
121
+ For example, given an import request to a package defined in 'extends'
122
+ (ie. @salesforce/retail-react-app):
123
+ This will return true if the issuer is a file in a base template
124
+ This will return false if the issuer is a file in the overrides dir
125
+ This allow the base template to import from overrides and allows the overrides to import from
126
+ the base template using the same syntax (ie. import from @salesforce/retail-react-app/...)
127
+ */
128
+ isFromExtends(request, filepath) {
129
+ var _this$extends, _this$extends$, _this$extends$$starts;
130
+ const pkgName = request.split(/(\/|\\)/).filter(item => !item.match(/(\/|\\)/)).slice(0, (_this$extends = this.extends) !== null && _this$extends !== void 0 && (_this$extends$ = _this$extends[0]) !== null && _this$extends$ !== void 0 && (_this$extends$$starts = _this$extends$.startsWith) !== null && _this$extends$$starts !== void 0 && _this$extends$$starts.call(_this$extends$, '@') ? 2 : 1).join('/');
131
+
132
+ // we split by path delimeters (OS agnostic), filter out
133
+ // separators, then spread both to form a normalized
134
+ // '/base', 'path', 'to', 'dir' when both halves are joined
135
+ const issuerPath = _path.default.join(...this.projectDir.split(_path.default.sep).filter(item => !item.match(/(\/|\\)/)), ...this.overridesDir.replace(/^(\/|\\)/, '').split('/').filter(item => !item.match(/(\/|\\)/)));
136
+ return (
137
+ // request includes extends
138
+ this.extends.includes(pkgName) &&
139
+ //
140
+ // this is very important, to avoid circular imports, check that the
141
+ // `issuer` (requesting context) isn't the overrides directory
142
+
143
+ // request is not issued from overrides
144
+ !filepath.includes(issuerPath)
145
+ );
146
+ }
147
+ handleHook(requestContext, resolveContext, callback, resolver) {
148
+ let targetFile;
149
+ let overrideRelative;
150
+ if (this.isFromExtends(requestContext.request, requestContext.path)) {
151
+ overrideRelative = this.toOverrideRelative(requestContext.request).replace(/$\//, '');
152
+ targetFile = this.findFileFromMap(overrideRelative, this._allSearchDirs);
153
+ }
154
+ if (targetFile) {
155
+ const target = resolver.ensureHook('resolved');
156
+ requestContext.path = _path.default.sep === '/' ? targetFile : targetFile.replace('/', _path.default.sep);
157
+ resolver.doResolve(target, requestContext, `${this.constructor.name} found base override file`, resolveContext, callback);
158
+ } else {
159
+ return callback();
160
+ }
161
+ }
162
+ apply(resolver) {
163
+ resolver.getHook('resolve').tapAsync('FeatureResolverPlugin', (requestContext, resolveContext, callback) => {
164
+ this.handleHook(requestContext, resolveContext, callback, resolver);
165
+ });
166
+ }
167
+ }
168
+ var _default = exports.default = OverridesResolverPlugin;