@salesforce/pwa-kit-dev 3.9.0-nightly-20241206124802 → 4.0.0-extensibility-preview.0
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/bin/pwa-kit-dev.js +50 -24
- package/configs/babel/babel-config.js +10 -5
- package/configs/jest/jest-babel-transform.js +1 -1
- package/configs/jest/jest.config.js +4 -2
- package/configs/webpack/config.js +78 -89
- package/configs/webpack/utils.js +38 -2
- package/configs/webpack/utils.test.js +62 -0
- package/package.json +12 -10
- package/ssr/server/build-dev-server.js +2 -1
- package/ssr/server/build-dev-server.test.js +106 -2
- package/ssr/server/test_fixtures/node_modules/another-extension/src/setup-server.js +21 -0
- package/ssr/server/test_fixtures/node_modules/extension-with-bad-setup-server/src/setup-server.js +17 -0
- package/ssr/server/test_fixtures/node_modules/extension-with-setup-server-no-default-export/src/setup-server.js +17 -0
- package/{configs/webpack/test/overrides/path/data.js → ssr/server/test_fixtures/node_modules/extension-without-setup-server/src/random-file.js} +2 -2
- package/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js +23 -0
- package/ssr/server/test_fixtures/node_modules/ts-extension/src/setup-server.ts +23 -0
- package/utils/logger-instance.js +19 -0
- package/utils/script-utils.js +8 -8
- package/utils/script-utils.test.js +9 -9
- package/configs/webpack/overrides-plugin.js +0 -168
- package/configs/webpack/overrides-plugin.test.js +0 -388
- package/configs/webpack/test/overrides/exists.js +0 -7
- package/configs/webpack/test/overrides/newExtension.js +0 -7
- package/configs/webpack/test/overrides/path/index.js +0 -7
- package/configs/webpack/test/overrides/path/index.mock.js +0 -7
- package/configs/webpack/test/overrides/path/nested/icon.svg +0 -0
- package/configs/webpack/test/package.json +0 -13
package/bin/pwa-kit-dev.js
CHANGED
|
@@ -14,6 +14,13 @@ const program = require('commander')
|
|
|
14
14
|
const validator = require('validator')
|
|
15
15
|
const {execSync: _execSync} = require('child_process')
|
|
16
16
|
const {getConfig} = require('@salesforce/pwa-kit-runtime/utils/ssr-config')
|
|
17
|
+
const {
|
|
18
|
+
buildBabelExtensibilityArgs
|
|
19
|
+
} = require('@salesforce/pwa-kit-extension-sdk/configs/babel/utils')
|
|
20
|
+
const {
|
|
21
|
+
getConfiguredExtensions,
|
|
22
|
+
validateExtensionDependencies
|
|
23
|
+
} = require('@salesforce/pwa-kit-extension-sdk/shared/utils')
|
|
17
24
|
|
|
18
25
|
// Scripts in ./bin have never gone through babel, so we
|
|
19
26
|
// don't have a good pattern for mixing compiled/un-compiled
|
|
@@ -59,17 +66,24 @@ const getProjectName = async () => {
|
|
|
59
66
|
return projectPkg.name
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
const getAppEntrypoint =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const projectPkg = await scriptUtils.getProjectPkg()
|
|
67
|
-
const {overridesDir} = projectPkg?.ccExtensibility ?? {}
|
|
68
|
-
if (!overridesDir || typeof overridesDir !== 'string') return null
|
|
69
|
+
const getAppEntrypoint = () => {
|
|
70
|
+
return p.join(process.cwd(), 'app', 'ssr.js')
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
/**
|
|
74
|
+
* For some commands, we like to validate the configuration first before proceeding with the rest of the command.
|
|
75
|
+
* Currently, we're only validating the app extensions, but we plan to validate other parts of the config in the future.
|
|
76
|
+
*/
|
|
77
|
+
const validateAppConfiguration = () => {
|
|
78
|
+
const extensions = getConfiguredExtensions(getConfig())
|
|
79
|
+
if (extensions.length > 0) {
|
|
80
|
+
info('Validating app extensions...')
|
|
81
|
+
const {success, errors} = validateExtensionDependencies(extensions)
|
|
82
|
+
if (!success) {
|
|
83
|
+
errors.forEach((e) => error(e.message))
|
|
84
|
+
throw new Error('Please double-check your configuration.')
|
|
85
|
+
}
|
|
86
|
+
}
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
const main = async () => {
|
|
@@ -238,6 +252,9 @@ const main = async () => {
|
|
|
238
252
|
).default('--extensions ".js,.jsx,.ts,.tsx"')
|
|
239
253
|
)
|
|
240
254
|
.action(async ({inspect, noHMR, babelArgs}) => {
|
|
255
|
+
validateAppConfiguration()
|
|
256
|
+
|
|
257
|
+
info('Starting server...')
|
|
241
258
|
// We use @babel/node instead of node because we want to support ES6 import syntax
|
|
242
259
|
const babelNode = p.join(
|
|
243
260
|
require.resolve('webpack'),
|
|
@@ -248,18 +265,17 @@ const main = async () => {
|
|
|
248
265
|
'babel-node'
|
|
249
266
|
)
|
|
250
267
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
...(noHMR ? {HMR: 'false'} : {})
|
|
268
|
+
execSync(
|
|
269
|
+
`"${babelNode}" ${inspect ? '--inspect' : ''} ${buildBabelExtensibilityArgs(
|
|
270
|
+
getConfig()
|
|
271
|
+
)} ${babelArgs} "${getAppEntrypoint()}"`,
|
|
272
|
+
{
|
|
273
|
+
env: {
|
|
274
|
+
...process.env,
|
|
275
|
+
...(noHMR ? {HMR: 'false'} : {})
|
|
276
|
+
}
|
|
261
277
|
}
|
|
262
|
-
|
|
278
|
+
)
|
|
263
279
|
})
|
|
264
280
|
|
|
265
281
|
program
|
|
@@ -274,6 +290,9 @@ const main = async () => {
|
|
|
274
290
|
)
|
|
275
291
|
.description(`build your app for production`)
|
|
276
292
|
.action(async ({buildDirectory}) => {
|
|
293
|
+
validateAppConfiguration()
|
|
294
|
+
|
|
295
|
+
info('Building...')
|
|
277
296
|
const webpack = p.join(require.resolve('webpack'), '..', '..', '..', '.bin', 'webpack')
|
|
278
297
|
const projectWebpack = p.join(process.cwd(), 'webpack.config.js')
|
|
279
298
|
const webpackConf = fse.pathExistsSync(projectWebpack)
|
|
@@ -309,6 +328,8 @@ const main = async () => {
|
|
|
309
328
|
'// This file is required by Managed Runtime for historical reasons.\n'
|
|
310
329
|
)
|
|
311
330
|
}
|
|
331
|
+
|
|
332
|
+
success(`Build directory is at ${buildDirectory}`)
|
|
312
333
|
})
|
|
313
334
|
|
|
314
335
|
managedRuntimeCommand('push')
|
|
@@ -424,7 +445,9 @@ const main = async () => {
|
|
|
424
445
|
.action(async (path, {fix}) => {
|
|
425
446
|
const eslint = p.join(require.resolve('eslint'), '..', '..', '..', '.bin', 'eslint')
|
|
426
447
|
execSync(
|
|
427
|
-
|
|
448
|
+
`"${eslint}" --resolve-plugins-relative-to "${pkgRoot}"${
|
|
449
|
+
fix ? ' --fix' : ''
|
|
450
|
+
} "${path}"`
|
|
428
451
|
)
|
|
429
452
|
})
|
|
430
453
|
|
|
@@ -434,16 +457,19 @@ const main = async () => {
|
|
|
434
457
|
.argument('<path>', 'path or glob to format')
|
|
435
458
|
.action(async (path) => {
|
|
436
459
|
const prettier = p.join(require.resolve('prettier'), '..', '..', '.bin', 'prettier')
|
|
437
|
-
execSync(
|
|
460
|
+
execSync(`"${prettier}" --write "${path}"`)
|
|
438
461
|
})
|
|
439
462
|
|
|
440
463
|
program
|
|
441
464
|
.command('test')
|
|
465
|
+
.allowUnknownOption()
|
|
442
466
|
.description('test the project')
|
|
443
467
|
.action(async (_, {args}) => {
|
|
444
468
|
const jest = p.join(require.resolve('jest'), '..', '..', '..', '.bin', 'jest')
|
|
445
469
|
execSync(
|
|
446
|
-
|
|
470
|
+
`"${jest}" --passWithNoTests --maxWorkers=2${
|
|
471
|
+
args.length ? ' ' + args.join(' ') : ''
|
|
472
|
+
}`
|
|
447
473
|
)
|
|
448
474
|
})
|
|
449
475
|
|
|
@@ -4,30 +4,35 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
var _utils = require("@salesforce/pwa-kit-extension-sdk/shared/utils");
|
|
8
|
+
var _ssrConfig = require("@salesforce/pwa-kit-runtime/utils/ssr-config");
|
|
7
9
|
/*
|
|
8
10
|
* Copyright (c) 2021, salesforce.com, inc.
|
|
9
11
|
* All rights reserved.
|
|
10
12
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
11
13
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
12
14
|
*/
|
|
13
|
-
|
|
15
|
+
// PWA-Kit Imports
|
|
16
|
+
var _default = exports.default = {
|
|
14
17
|
sourceType: 'unambiguous',
|
|
15
18
|
presets: [[require('@babel/preset-env'), {
|
|
16
19
|
targets: {
|
|
17
20
|
node: 18
|
|
18
21
|
}
|
|
19
22
|
}], require('@babel/preset-typescript'), require('@babel/preset-react')],
|
|
20
|
-
plugins: [require('@
|
|
23
|
+
plugins: [[require('@salesforce/pwa-kit-extension-sdk/configs/babel/plugin-application-extensions'), {
|
|
24
|
+
target: 'node',
|
|
25
|
+
configured: (0, _utils.getConfiguredExtensions)((0, _ssrConfig.getConfig)())
|
|
26
|
+
}], require('@babel/plugin-transform-async-to-generator'), require('@babel/plugin-proposal-object-rest-spread'), require('@babel/plugin-transform-object-assign'), [require('@babel/plugin-transform-runtime'), {
|
|
21
27
|
regenerator: true
|
|
22
28
|
}], require('@babel/plugin-syntax-dynamic-import'), require('@loadable/babel-plugin'), require('@babel/plugin-proposal-optional-chaining'), [require('babel-plugin-formatjs'), {
|
|
23
29
|
idInterpolationPattern: '[sha512:contenthash:base64:6]',
|
|
24
30
|
ast: true
|
|
25
|
-
}], require('@babel/plugin-transform-async-generator-functions')],
|
|
31
|
+
}], require('@babel/plugin-transform-async-generator-functions')].filter(Boolean),
|
|
26
32
|
env: {
|
|
27
33
|
test: {
|
|
28
34
|
presets: [require('@babel/preset-env'), require('@babel/preset-react')],
|
|
29
35
|
plugins: [require('babel-plugin-dynamic-import-node-babel-7')]
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
|
-
};
|
|
33
|
-
var _default = exports.default = config;
|
|
38
|
+
};
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
/* eslint-env node */
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
16
|
-
const babelJest = require('babel-jest');
|
|
16
|
+
const babelJest = require('babel-jest').default;
|
|
17
17
|
module.exports = babelJest.createTransformer({
|
|
18
18
|
rootMode: 'upward'
|
|
19
19
|
});
|
|
@@ -13,16 +13,18 @@ module.exports = {
|
|
|
13
13
|
testURL: 'http://localhost/',
|
|
14
14
|
verbose: true,
|
|
15
15
|
collectCoverage: true,
|
|
16
|
+
coveragePathIgnorePatterns: ['app/application-extensions', '/node_modules/'],
|
|
16
17
|
// We need access to jsdom globally in tests.
|
|
17
18
|
// jsdom isn't accessible so we need to use this
|
|
18
19
|
// 3rd party test environment wrapper. When we
|
|
19
20
|
// upgrade to jest 28, we can revert back to jsdom.
|
|
20
21
|
testEnvironment: 'jest-environment-jsdom-global',
|
|
21
|
-
testPathIgnorePatterns: ['node_modules', 'build'],
|
|
22
|
+
testPathIgnorePatterns: ['node_modules', 'build', 'app/application-extensions'],
|
|
22
23
|
moduleNameMapper: {
|
|
23
24
|
'\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': _path.default.join(__dirname, 'mocks', 'fileMock.js'),
|
|
24
25
|
'\\.(svg)$': _path.default.join(__dirname, 'mocks', 'svgMock.js'),
|
|
25
|
-
'\\.(css|less)$': _path.default.join(__dirname, 'mocks', 'styleMock.js')
|
|
26
|
+
'\\.(css|less)$': _path.default.join(__dirname, 'mocks', 'styleMock.js'),
|
|
27
|
+
'tsx/cjs/api': '<rootDir>/node_modules/tsx/dist/cjs/api/index.cjs'
|
|
26
28
|
},
|
|
27
29
|
globals: {
|
|
28
30
|
DEBUG: true,
|
|
@@ -3,37 +3,39 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
var
|
|
6
|
+
exports.SUPPORTED_FILE_EXTENSIONS = exports.EXTENIONS_NAMESPACE = exports.DEPS_TO_DEDUPE = void 0;
|
|
7
|
+
var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");
|
|
8
|
+
var _path = require("path");
|
|
8
9
|
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
9
10
|
var _webpack = _interopRequireDefault(require("webpack"));
|
|
10
|
-
var _webpackNotifier = _interopRequireDefault(require("webpack-notifier"));
|
|
11
11
|
var _copyWebpackPlugin = _interopRequireDefault(require("copy-webpack-plugin"));
|
|
12
|
-
var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");
|
|
13
12
|
var _webpackPlugin = _interopRequireDefault(require("@loadable/webpack-plugin"));
|
|
14
13
|
var _reactRefreshWebpackPlugin = _interopRequireDefault(require("@pmmmwh/react-refresh-webpack-plugin"));
|
|
15
14
|
var _speedMeasureWebpackPlugin = _interopRequireDefault(require("speed-measure-webpack-plugin"));
|
|
16
|
-
var
|
|
15
|
+
var _webpackNotifier = _interopRequireDefault(require("webpack-notifier"));
|
|
16
|
+
var _applicationExtensionsConfigPlugin = _interopRequireDefault(require("@salesforce/pwa-kit-extension-sdk/configs/webpack/application-extensions-config-plugin"));
|
|
17
17
|
var _plugins = require("./plugins");
|
|
18
18
|
var _configNames = require("./config-names");
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* All rights reserved.
|
|
23
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
24
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
25
|
-
*/
|
|
26
|
-
/* eslint-env node */
|
|
27
|
-
// For more information on these settings, see https://webpack.js.org/configuration
|
|
19
|
+
var _webpack2 = require("@salesforce/pwa-kit-extension-sdk/configs/webpack");
|
|
20
|
+
var _ssrConfig = require("@salesforce/pwa-kit-runtime/utils/ssr-config");
|
|
21
|
+
var _utils = require("@salesforce/pwa-kit-extension-sdk/shared/utils");
|
|
28
22
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
|
-
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); }
|
|
30
|
-
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; }
|
|
31
23
|
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); }
|
|
32
24
|
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; }
|
|
33
25
|
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; }
|
|
34
26
|
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; }
|
|
35
27
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
36
|
-
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); }
|
|
28
|
+
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); } /*
|
|
29
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
30
|
+
* All rights reserved.
|
|
31
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
32
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
33
|
+
*/ /* eslint-env node */ // For more information on these settings, see https://webpack.js.org/configuration
|
|
34
|
+
// Third-Party Plugins
|
|
35
|
+
// PWA-Kit Plugins
|
|
36
|
+
// Local Plugins
|
|
37
|
+
// Constants
|
|
38
|
+
// Utilities
|
|
37
39
|
const projectDir = process.cwd();
|
|
38
40
|
const pkg = _fsExtra.default.readJsonSync((0, _path.resolve)(projectDir, 'package.json'));
|
|
39
41
|
const buildDir = process.env.PWA_KIT_BUILD_DIR ? (0, _path.resolve)(process.env.PWA_KIT_BUILD_DIR) : (0, _path.resolve)(projectDir, 'build');
|
|
@@ -45,16 +47,11 @@ const INSPECT = process.execArgv.some(arg => /^--inspect(?:-brk)?(?:$|=)/.test(a
|
|
|
45
47
|
const DEBUG = mode !== production && process.env.DEBUG === 'true';
|
|
46
48
|
const CI = process.env.CI;
|
|
47
49
|
const disableHMR = process.env.HMR === 'false';
|
|
50
|
+
const EXTENIONS_NAMESPACE = exports.EXTENIONS_NAMESPACE = '__extensions';
|
|
48
51
|
if ([production, development].indexOf(mode) < 0) {
|
|
49
52
|
throw new Error(`Invalid mode "${mode}"`);
|
|
50
53
|
}
|
|
51
|
-
|
|
52
|
-
// for API convenience, add the leading slash if missing
|
|
53
|
-
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, '/') : '';
|
|
54
|
-
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(/^\//, '');
|
|
55
|
-
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;
|
|
56
|
-
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('/', '\\');
|
|
57
|
-
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;
|
|
54
|
+
const SUPPORTED_FILE_EXTENSIONS = exports.SUPPORTED_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.json'];
|
|
58
55
|
|
|
59
56
|
// TODO: can these be handled in package.json as peerDependencies?
|
|
60
57
|
// https://salesforce-internal.slack.com/archives/C0DKK1FJS/p1672939909212589
|
|
@@ -62,13 +59,6 @@ const EXT_EXTENDABLE = exports.EXT_EXTENDABLE = pkg === null || pkg === void 0 ?
|
|
|
62
59
|
// due to to how the sdks work and the potential of these npm deps coming
|
|
63
60
|
// from multiple places, we need to force them to one place where they're found
|
|
64
61
|
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'];
|
|
65
|
-
if (EXT_EXTENDABLE && EXT_EXTENDS) {
|
|
66
|
-
const extendsAsArr = Array.isArray(EXT_EXTENDS) ? EXT_EXTENDS : [EXT_EXTENDS];
|
|
67
|
-
const conflicts = extendsAsArr.filter(x => EXT_EXTENDABLE === null || EXT_EXTENDABLE === void 0 ? void 0 : EXT_EXTENDABLE.includes(x));
|
|
68
|
-
if (conflicts !== null && conflicts !== void 0 && conflicts.length) {
|
|
69
|
-
throw new Error(`Dependencies in 'extendable' and 'extends' cannot overlap, fix these: ${conflicts.join(', ')}"`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
62
|
const getBundleAnalyzerPlugin = (name = 'report', pluginOptions) => new _webpackBundleAnalyzer.BundleAnalyzerPlugin(_objectSpread({
|
|
73
63
|
analyzerMode: 'static',
|
|
74
64
|
defaultSizes: 'gzip',
|
|
@@ -79,18 +69,16 @@ const getBundleAnalyzerPlugin = (name = 'report', pluginOptions) => new _webpack
|
|
|
79
69
|
statsFilename: `${name}-analyzer-stats.json`
|
|
80
70
|
}, pluginOptions));
|
|
81
71
|
const entryPointExists = segments => {
|
|
82
|
-
for (let ext of
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
if (_fsExtra.default.existsSync(primary) || override && _fsExtra.default.existsSync(override)) {
|
|
72
|
+
for (let ext of SUPPORTED_FILE_EXTENSIONS) {
|
|
73
|
+
const p = (0, _path.resolve)(projectDir, ...segments) + ext;
|
|
74
|
+
if (_fsExtra.default.existsSync(p)) {
|
|
86
75
|
return true;
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
return false;
|
|
90
79
|
};
|
|
91
|
-
const getAppEntryPoint = () =>
|
|
92
|
-
|
|
93
|
-
};
|
|
80
|
+
const getAppEntryPoint = () => './app/main';
|
|
81
|
+
const getServerEntryPoint = () => './app/ssr.js';
|
|
94
82
|
const getPublicPathEntryPoint = () => {
|
|
95
83
|
return (0, _path.resolve)(projectDir, 'node_modules', '@salesforce', 'pwa-kit-dev', 'ssr', 'server', 'public-path');
|
|
96
84
|
};
|
|
@@ -148,34 +136,35 @@ const baseConfig = target => {
|
|
|
148
136
|
publicPath: '',
|
|
149
137
|
path: buildDir
|
|
150
138
|
},
|
|
151
|
-
resolve: _objectSpread(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
overridesDir: EXT_OVERRIDES_DIR,
|
|
155
|
-
projectDir: process.cwd()
|
|
156
|
-
})]
|
|
157
|
-
} : {}), {}, {
|
|
158
|
-
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
|
|
159
|
-
alias: _objectSpread(_objectSpread(_objectSpread({}, _extends(...DEPS_TO_DEDUPE.map(dep => ({
|
|
139
|
+
resolve: _objectSpread({
|
|
140
|
+
extensions: SUPPORTED_FILE_EXTENSIONS,
|
|
141
|
+
alias: _objectSpread(_objectSpread({}, _extends(...DEPS_TO_DEDUPE.map(dep => ({
|
|
160
142
|
[dep]: findDepInStack(dep)
|
|
161
|
-
})))),
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
[item]: _path.default.resolve(projectDir)
|
|
167
|
-
}))) : {})
|
|
143
|
+
})))), {}, {
|
|
144
|
+
// TODO: This alias is temporary. When we investigate turning the retail template into an application extension
|
|
145
|
+
// we'll have to decide if we want to continue using an alias, or change back to using relative paths.
|
|
146
|
+
'@salesforce/retail-react-app': projectDir
|
|
147
|
+
}, (0, _utils.buildAliases)(Object.keys((pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies) || {}).filter(dependency => dependency.match(_utils.nameRegex))))
|
|
168
148
|
}, target === 'web' ? {
|
|
169
149
|
fallback: {
|
|
170
150
|
crypto: false
|
|
171
151
|
}
|
|
172
152
|
} : {}),
|
|
173
|
-
|
|
153
|
+
resolveLoader: {
|
|
154
|
+
alias: {
|
|
155
|
+
overridable: findDepInStack('@salesforce/pwa-kit-extension-sdk/configs/webpack/overrides-resolver-loader.js')
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
plugins: [new _applicationExtensionsConfigPlugin.default({
|
|
159
|
+
extensions: (0, _utils.getConfiguredExtensions)((0, _ssrConfig.getConfig)())
|
|
160
|
+
}), new _webpack.default.DefinePlugin({
|
|
174
161
|
DEBUG,
|
|
175
162
|
NODE_ENV: `'${process.env.NODE_ENV}'`,
|
|
176
163
|
WEBPACK_TARGET: `'${target}'`,
|
|
177
164
|
['global.GENTLY']: false
|
|
178
|
-
}),
|
|
165
|
+
}),
|
|
166
|
+
// new SharedStatePlugin(),
|
|
167
|
+
mode === development && new _webpack.default.NoEmitOnErrorsPlugin(), (0, _plugins.sdkReplacementPlugin)(),
|
|
179
168
|
// Don't chunk if it's a node target – faster Lambda startup.
|
|
180
169
|
target === 'node' && new _webpack.default.optimize.LimitChunkCountPlugin({
|
|
181
170
|
maxChunks: 1
|
|
@@ -199,7 +188,17 @@ const baseConfig = target => {
|
|
|
199
188
|
use: {
|
|
200
189
|
loader: findDepInStack('source-map-loader')
|
|
201
190
|
}
|
|
202
|
-
}
|
|
191
|
+
}, (0, _webpack2.ruleForApplicationExtensibility)({
|
|
192
|
+
loaderOptions: {
|
|
193
|
+
configured: (0, _utils.getConfiguredExtensions)((0, _ssrConfig.getConfig)()),
|
|
194
|
+
target: 'web'
|
|
195
|
+
}
|
|
196
|
+
}), (0, _webpack2.ruleForApplicationExtensibility)({
|
|
197
|
+
loaderOptions: {
|
|
198
|
+
configured: (0, _utils.getConfiguredExtensions)((0, _ssrConfig.getConfig)()),
|
|
199
|
+
target: 'node'
|
|
200
|
+
}
|
|
201
|
+
})].filter(Boolean)
|
|
203
202
|
}
|
|
204
203
|
});
|
|
205
204
|
}
|
|
@@ -226,20 +225,7 @@ const withChunking = config => {
|
|
|
226
225
|
splitChunks: {
|
|
227
226
|
cacheGroups: {
|
|
228
227
|
vendor: {
|
|
229
|
-
|
|
230
|
-
// 1. The package is in node_modules
|
|
231
|
-
// 2. The package is one of the monorepo packages.
|
|
232
|
-
// This is for local development to ensure the bundle
|
|
233
|
-
// composition is the same as a production build
|
|
234
|
-
// 3. If extending another template, don't include the
|
|
235
|
-
// baseline route files in vendor.js
|
|
236
|
-
test: module => {
|
|
237
|
-
var _module$context, _module$context2, _module$context2$matc;
|
|
238
|
-
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}`)) {
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
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)/);
|
|
242
|
-
},
|
|
228
|
+
test: /(node_modules)|(packages\/.*\/dist)/,
|
|
243
229
|
name: 'vendor',
|
|
244
230
|
chunks: 'all'
|
|
245
231
|
}
|
|
@@ -250,22 +236,23 @@ const withChunking = config => {
|
|
|
250
236
|
};
|
|
251
237
|
const staticFolderCopyPlugin = new _copyWebpackPlugin.default({
|
|
252
238
|
patterns: [{
|
|
253
|
-
from:
|
|
254
|
-
to:
|
|
255
|
-
|
|
256
|
-
|
|
239
|
+
from: 'app/static/',
|
|
240
|
+
to: 'static/'
|
|
241
|
+
}, ...(0, _utils.getConfiguredExtensions)((0, _ssrConfig.getConfig)()).map(extension => {
|
|
242
|
+
const packageName = extension[0];
|
|
243
|
+
return {
|
|
244
|
+
from: `${projectDir}/node_modules/${packageName}/static`,
|
|
245
|
+
to: `static/${EXTENIONS_NAMESPACE}/${packageName}`,
|
|
246
|
+
// Add exclude for readme file.
|
|
247
|
+
noErrorOnMissing: true
|
|
248
|
+
};
|
|
249
|
+
})]
|
|
257
250
|
});
|
|
258
251
|
const ruleForBabelLoader = babelPlugins => {
|
|
259
|
-
return
|
|
252
|
+
return {
|
|
260
253
|
id: 'babel-loader',
|
|
261
|
-
test: /(\.js(x?)|\.ts(x?))
|
|
262
|
-
|
|
263
|
-
// TODO: handle for array here when that's supported
|
|
264
|
-
{
|
|
265
|
-
exclude: new RegExp(`${_path.default.sep}node_modules(?!${_path.default.sep}${_path.default.sep === '/' ? EXT_EXTENDS : EXT_EXTENDS_WIN})`)
|
|
266
|
-
} : {
|
|
267
|
-
exclude: /node_modules/
|
|
268
|
-
}), {}, {
|
|
254
|
+
test: /(\.js(x?)|\.ts(x?))$/,
|
|
255
|
+
// NOTE: Because our extensions are just folders containing source code, we need to ensure that the babel-loader processes them.
|
|
269
256
|
use: [{
|
|
270
257
|
loader: findDepInStack('babel-loader'),
|
|
271
258
|
options: _objectSpread({
|
|
@@ -275,7 +262,7 @@ const ruleForBabelLoader = babelPlugins => {
|
|
|
275
262
|
plugins: babelPlugins
|
|
276
263
|
} : {})
|
|
277
264
|
}]
|
|
278
|
-
}
|
|
265
|
+
};
|
|
279
266
|
};
|
|
280
267
|
const findAndReplace = (array = [], findFn = () => {}, replacement) => {
|
|
281
268
|
const clone = array.slice(0);
|
|
@@ -292,6 +279,9 @@ const enableReactRefresh = config => {
|
|
|
292
279
|
}
|
|
293
280
|
const newRule = ruleForBabelLoader([require.resolve('react-refresh/babel')]);
|
|
294
281
|
const rules = findAndReplace(config.module.rules, rule => rule.id === 'babel-loader', newRule);
|
|
282
|
+
|
|
283
|
+
// NOTE: This ensures that files processed with the override-loader do not get processed again for hmr.
|
|
284
|
+
rules[0].exclude = resource => resource.includes('?noHMR=true');
|
|
295
285
|
return _objectSpread(_objectSpread({}, config), {}, {
|
|
296
286
|
module: _objectSpread(_objectSpread({}, config.module), {}, {
|
|
297
287
|
rules
|
|
@@ -330,7 +320,7 @@ const optional = (name, path) => {
|
|
|
330
320
|
const clientOptional = baseConfig('web').extend(config => {
|
|
331
321
|
return _objectSpread(_objectSpread({}, config), {}, {
|
|
332
322
|
name: _configNames.CLIENT_OPTIONAL,
|
|
333
|
-
entry: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, optional('loader', (0, _path.resolve)(projectDir,
|
|
323
|
+
entry: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, optional('loader', (0, _path.resolve)(projectDir, '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'))),
|
|
334
324
|
// use source map to make debugging easier
|
|
335
325
|
devtool: mode === development ? 'source-map' : false,
|
|
336
326
|
plugins: [...config.plugins, analyzeBundle && getBundleAnalyzerPlugin(_configNames.CLIENT_OPTIONAL)].filter(Boolean)
|
|
@@ -369,7 +359,7 @@ const ssr = (() => {
|
|
|
369
359
|
} : {}), {}, {
|
|
370
360
|
// Must *not* be named "server". See - https://www.npmjs.com/package/webpack-hot-server-middleware#usage
|
|
371
361
|
name: _configNames.SSR,
|
|
372
|
-
entry:
|
|
362
|
+
entry: getServerEntryPoint(),
|
|
373
363
|
output: {
|
|
374
364
|
path: buildDir,
|
|
375
365
|
filename: 'ssr.js',
|
|
@@ -385,8 +375,7 @@ const ssr = (() => {
|
|
|
385
375
|
const requestProcessor = entryPointExists(['app', 'request-processor']) && baseConfig('node').extend(config => {
|
|
386
376
|
return _objectSpread(_objectSpread({}, config), {}, {
|
|
387
377
|
name: _configNames.REQUEST_PROCESSOR,
|
|
388
|
-
|
|
389
|
-
entry: `.${EXT_OVERRIDES_DIR}/app/request-processor.js`,
|
|
378
|
+
entry: './app/request-processor.js',
|
|
390
379
|
output: {
|
|
391
380
|
path: buildDir,
|
|
392
381
|
filename: 'request-processor.js',
|
package/configs/webpack/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.makeRegExp = void 0;
|
|
6
|
+
exports.makeRegExp = exports.kebabToUpperCamelCase = exports.kebabToLowerCamelCase = void 0;
|
|
7
7
|
var _path = _interopRequireDefault(require("path"));
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
/*
|
|
@@ -20,4 +20,40 @@ const makeRegExp = (str, sep = _path.default.sep) => {
|
|
|
20
20
|
}
|
|
21
21
|
return new RegExp(str);
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Converts a kebab-case string to UpperCamelCase (PascalCase).
|
|
26
|
+
*
|
|
27
|
+
* @param {string} str - The kebab-case string to be converted.
|
|
28
|
+
* @returns {string} The converted UpperCamelCase string.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Returns 'HelloWorld'
|
|
32
|
+
* kebabToUpperCamelCase('hello-world')
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Returns 'FooBarBaz'
|
|
36
|
+
* kebabToUpperCamelCase('foo-bar-baz')
|
|
37
|
+
*/
|
|
38
|
+
exports.makeRegExp = makeRegExp;
|
|
39
|
+
const kebabToUpperCamelCase = str => str.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join('');
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Converts a kebab-case string to lowerCamelCase.
|
|
43
|
+
*
|
|
44
|
+
* The first word in the resulting string will be in lower case, and each subsequent word will start with an uppercase letter.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} str - The kebab-case string to be converted.
|
|
47
|
+
* @returns {string} The converted lowerCamelCase string.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Returns 'helloWorld'
|
|
51
|
+
* kebabToLowerCamelCase('hello-world')
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Returns 'fooBarBaz'
|
|
55
|
+
* kebabToLowerCamelCase('foo-bar-baz')
|
|
56
|
+
*/
|
|
57
|
+
exports.kebabToUpperCamelCase = kebabToUpperCamelCase;
|
|
58
|
+
const kebabToLowerCamelCase = str => str.split('-').map((word, index) => index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join('');
|
|
59
|
+
exports.kebabToLowerCamelCase = kebabToLowerCamelCase;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _utils = require("./utils");
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
8
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
describe('kebabToLowerCamelCase', () => {
|
|
12
|
+
test('converts a simple kebab-case string to lowerCamelCase', () => {
|
|
13
|
+
expect((0, _utils.kebabToLowerCamelCase)('hello-world')).toBe('helloWorld');
|
|
14
|
+
});
|
|
15
|
+
test('converts a multi-word kebab-case string to lowerCamelCase', () => {
|
|
16
|
+
expect((0, _utils.kebabToLowerCamelCase)('foo-bar-baz')).toBe('fooBarBaz');
|
|
17
|
+
});
|
|
18
|
+
test('handles a single word without hyphens', () => {
|
|
19
|
+
expect((0, _utils.kebabToLowerCamelCase)('hello')).toBe('hello');
|
|
20
|
+
});
|
|
21
|
+
test('handles an empty string', () => {
|
|
22
|
+
expect((0, _utils.kebabToLowerCamelCase)('')).toBe('');
|
|
23
|
+
});
|
|
24
|
+
test('converts strings with multiple consecutive hyphens', () => {
|
|
25
|
+
expect((0, _utils.kebabToLowerCamelCase)('foo--bar--baz')).toBe('fooBarBaz');
|
|
26
|
+
});
|
|
27
|
+
test('converts strings with uppercase characters correctly', () => {
|
|
28
|
+
expect((0, _utils.kebabToLowerCamelCase)('HELLO-WORLD')).toBe('helloWorld');
|
|
29
|
+
});
|
|
30
|
+
test('converts strings with mixed case correctly', () => {
|
|
31
|
+
expect((0, _utils.kebabToLowerCamelCase)('fOo-BaR-bAz')).toBe('fooBarBaz');
|
|
32
|
+
});
|
|
33
|
+
test('handles strings that start or end with hyphens', () => {
|
|
34
|
+
expect((0, _utils.kebabToLowerCamelCase)('-foo-bar-')).toBe('FooBar');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('kebabToUpperCamelCase', () => {
|
|
38
|
+
test('converts a simple kebab-case string to UpperCamelCase', () => {
|
|
39
|
+
expect((0, _utils.kebabToUpperCamelCase)('hello-world')).toBe('HelloWorld');
|
|
40
|
+
});
|
|
41
|
+
test('converts a multi-word kebab-case string to UpperCamelCase', () => {
|
|
42
|
+
expect((0, _utils.kebabToUpperCamelCase)('foo-bar-baz')).toBe('FooBarBaz');
|
|
43
|
+
});
|
|
44
|
+
test('handles a single word without hyphens', () => {
|
|
45
|
+
expect((0, _utils.kebabToUpperCamelCase)('hello')).toBe('Hello');
|
|
46
|
+
});
|
|
47
|
+
test('handles an empty string', () => {
|
|
48
|
+
expect((0, _utils.kebabToUpperCamelCase)('')).toBe('');
|
|
49
|
+
});
|
|
50
|
+
test('converts strings with multiple consecutive hyphens', () => {
|
|
51
|
+
expect((0, _utils.kebabToUpperCamelCase)('foo--bar--baz')).toBe('FooBarBaz');
|
|
52
|
+
});
|
|
53
|
+
test('converts strings with uppercase characters correctly', () => {
|
|
54
|
+
expect((0, _utils.kebabToUpperCamelCase)('HELLO-WORLD')).toBe('HelloWorld');
|
|
55
|
+
});
|
|
56
|
+
test('converts strings with mixed case correctly', () => {
|
|
57
|
+
expect((0, _utils.kebabToUpperCamelCase)('fOo-BaR-bAz')).toBe('FooBarBaz');
|
|
58
|
+
});
|
|
59
|
+
test('handles strings that start or end with hyphens', () => {
|
|
60
|
+
expect((0, _utils.kebabToUpperCamelCase)('-foo-bar-')).toBe('FooBar');
|
|
61
|
+
});
|
|
62
|
+
});
|