@elliemae/pui-cli 6.0.0-beta.5 → 6.0.0-beta.50

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 (45) hide show
  1. package/lib/cli-commands/pack.js +1 -1
  2. package/lib/cli-commands/test.js +1 -12
  3. package/lib/cli-commands/tsc.js +103 -0
  4. package/lib/cli-commands/utils.js +9 -4
  5. package/lib/cli-commands/vitest.js +66 -0
  6. package/lib/cli.js +2 -0
  7. package/lib/lint/eslint/common.js +16 -8
  8. package/lib/lint/eslint/typescript/common.js +6 -1
  9. package/lib/lint/eslint/typescript/non-react.js +1 -1
  10. package/lib/lint/eslint/typescript/react.js +6 -1
  11. package/lib/lint/lint-staged.config.js +8 -1
  12. package/lib/lint/stylelint.config.js +0 -1
  13. package/lib/pui-config/index.js +18 -0
  14. package/lib/server/index.js +5 -9
  15. package/lib/server/middlewares/addDevMiddlewares.js +2 -2
  16. package/lib/server/middlewares/addProdMiddlewares.js +10 -3
  17. package/lib/testing/jest.config.js +26 -7
  18. package/lib/testing/mocks/matchMedia.js +12 -6
  19. package/lib/testing/mocks/pui-app-loader.js +1 -3
  20. package/lib/testing/mocks/pui-diagnostics.js +27 -35
  21. package/lib/testing/mocks/pui-user-monitoring.js +3 -5
  22. package/lib/testing/mocks/retry-axios.js +3 -5
  23. package/lib/testing/mocks/svg.js +5 -3
  24. package/lib/testing/resolver.js +47 -0
  25. package/lib/testing/setup-react-env.js +3 -0
  26. package/lib/testing/setup-tests.js +28 -4
  27. package/lib/testing/vitest.config.ts +16 -0
  28. package/lib/testing/vitest.setup.ts +0 -0
  29. package/lib/transpile/.swcrc +11 -0
  30. package/lib/transpile/esbuild.js +63 -0
  31. package/lib/transpile/react-shim.js +2 -0
  32. package/lib/transpile/swcrc.config.js +13 -0
  33. package/lib/typescript/tsc-files/index.js +66 -0
  34. package/lib/typescript/tsc-files/utils.js +16 -0
  35. package/lib/webpack/helpers.js +37 -3
  36. package/lib/webpack/webpack.base.babel.js +38 -93
  37. package/lib/webpack/webpack.dev.babel.js +6 -3
  38. package/lib/webpack/webpack.lib.base.babel.js +25 -64
  39. package/lib/webpack/webpack.lib.dev.babel.js +1 -2
  40. package/lib/webpack/webpack.lib.prod.babel.js +6 -11
  41. package/lib/webpack/webpack.prod.babel.js +30 -24
  42. package/lib/webpack/webpack.storybook.js +18 -103
  43. package/package.json +119 -108
  44. package/lib/esbuild.js +0 -39
  45. package/lib/testing/setup-styled-components-tests.js +0 -1
@@ -0,0 +1,47 @@
1
+ const resolutions = [
2
+ {
3
+ matcher: /\.jsx?$/i,
4
+ extensions: ['.tsx', '.ts'],
5
+ },
6
+ {
7
+ matcher: /\.mjs$/i,
8
+ extensions: ['.mts'],
9
+ },
10
+ {
11
+ matcher: /\.cjs$/i,
12
+ extensions: ['.cts'],
13
+ },
14
+ ];
15
+
16
+ const resolveConfig = {
17
+ conditionNames: ['import', 'node', 'default'],
18
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.node'],
19
+ modules: ['node_modules', 'app', 'lib'],
20
+ };
21
+
22
+ const importResolver = require('enhanced-resolve').create.sync(resolveConfig);
23
+ const requireResolver = require('enhanced-resolve').create.sync({
24
+ ...resolveConfig,
25
+ conditionNames: ['require', 'node', 'default'],
26
+ });
27
+
28
+ module.exports = (request, options) => {
29
+ let resolver = requireResolver;
30
+ if (options.conditions?.includes('import')) {
31
+ resolver = importResolver;
32
+ }
33
+ const resolution = resolutions.find(({ matcher }) => matcher.test(request));
34
+ if (resolution) {
35
+ // eslint-disable-next-line no-restricted-syntax
36
+ for (const extension of resolution.extensions) {
37
+ try {
38
+ return resolver(
39
+ options.basedir,
40
+ request.replace(resolution.matcher, extension),
41
+ );
42
+ // eslint-disable-next-line no-empty
43
+ } catch {}
44
+ }
45
+ }
46
+ return resolver(options.basedir, request);
47
+ };
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ import 'jest-styled-components';
3
+ global.React = React;
@@ -3,12 +3,36 @@
3
3
  import 'core-js/stable';
4
4
  import 'regenerator-runtime/runtime';
5
5
  import '@testing-library/jest-dom/extend-expect';
6
- import { toHaveNoViolations } from 'jest-axe';
6
+ import jestAxe from 'jest-axe';
7
7
  import ResizeObserver from 'resize-observer-polyfill';
8
- import addMatchMedia from './mocks/matchMedia';
9
- import { logger } from './mocks/pui-diagnostics';
8
+ import addMatchMedia from './mocks/matchMedia.js';
9
+ import { logger } from './mocks/pui-diagnostics.js';
10
10
 
11
- if (expect) expect.extend(toHaveNoViolations);
11
+ // eslint-disable-next-line no-console
12
+ const originalError = console.error;
13
+ // eslint-disable-next-line no-console
14
+ console.error = (...args) => {
15
+ const ignoreList = [
16
+ `Warning: Can't perform a React state update on an unmounted component`,
17
+ `Warning: Function components cannot be given refs`,
18
+ `Warning: Failed %s type:`,
19
+ `Warning: Invalid DOM property`,
20
+ `Warning: Each child in a list should have a unique`,
21
+ 'Warning: Received `%s` for a non-boolean attribute',
22
+ 'Warning: <%s /> is using incorrect casing.',
23
+ 'Warning: The tag <%s> is unrecognized in this browser',
24
+ 'Warning: Invalid arguments supplied to oneOf',
25
+ ];
26
+ if (
27
+ ignoreList.find(
28
+ (ignoreMsg) => !!args.find((arg) => arg?.includes?.(ignoreMsg)),
29
+ )
30
+ )
31
+ return false;
32
+ return originalError(...args);
33
+ };
34
+
35
+ if (expect) expect.extend(jestAxe.toHaveNoViolations);
12
36
  jest.setTimeout(60000);
13
37
 
14
38
  const addElementToBody = (element) => {
@@ -0,0 +1,16 @@
1
+ /// <reference types="vitest" />
2
+ import { defineConfig } from 'vite';
3
+ import path from 'path';
4
+
5
+ export default defineConfig({
6
+ test: {
7
+ global: true,
8
+ root: process.cwd(),
9
+ exclude: ['node_modules', 'dist', '.idea', '.git', '.cache', 'e2e'],
10
+ setupFiles: [path.resolve(__dirname, './vitest.setup.ts')],
11
+ coverage: {
12
+ reportsDirectory: './reports/coverage',
13
+ },
14
+ environment: 'happy-dom',
15
+ },
16
+ });
File without changes
@@ -0,0 +1,11 @@
1
+ {
2
+ "jsc": {
3
+ "parser": {
4
+ "syntax": "typescript",
5
+ "jsx": true,
6
+ "tsx": true,
7
+ "dynamicImport": true
8
+ },
9
+ "target": "es2020"
10
+ }
11
+ }
@@ -0,0 +1,63 @@
1
+ const esbuild = require('esbuild');
2
+ const fg = require('fast-glob');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { getPUIConfig } = require('../pui-config');
6
+ // const browserslistToEsbuild = require('browserslist-to-esbuild');
7
+
8
+ const { esBuild } = getPUIConfig();
9
+
10
+ const commonConfig = {
11
+ bundle: false,
12
+ target: esBuild.target, // browserslistToEsbuild(),
13
+ loader: { '.js': 'jsx' },
14
+ mainFields: ['module', 'browser', 'main'],
15
+ inject: [path.resolve(__dirname, './react-shim.js')],
16
+ };
17
+
18
+ const distFolder = 'dist';
19
+
20
+ const copyFiles = async ({ srcdir, outdir }) => {
21
+ const files = await fg([
22
+ `${srcdir}/**/*.*`,
23
+ `!${srcdir}/**/*.{js,jsx,ts,tsx,cjs,mjs}`,
24
+ ]);
25
+ files.forEach((srcFilePath) => {
26
+ const destFilePath = srcFilePath.replace(srcdir, outdir);
27
+ fs.copyFileSync(srcFilePath, destFilePath);
28
+ });
29
+ };
30
+
31
+ const build = async ({ srcPath, commonJS }) => {
32
+ const inputFiles = [
33
+ `${srcPath}/**/*.{js,jsx,ts,tsx}`,
34
+ `!${srcPath}/**/*.test.{js,jsx,ts,tsx}`,
35
+ `!${srcPath}/**/*.stories.{js,jsx,ts,tsx}`,
36
+ `!${srcPath}/**/*.endpoint.{js,jsx,ts,tsx}`,
37
+ ];
38
+ if (commonJS) {
39
+ const outdir = `${distFolder}/cjs`;
40
+ const commonJSEntryPoints = await fg(inputFiles);
41
+ await esbuild.build({
42
+ entryPoints: commonJSEntryPoints,
43
+ ...commonConfig,
44
+ outdir,
45
+ format: 'cjs',
46
+ });
47
+ await copyFiles({ srcdir: srcPath, outdir });
48
+ } else {
49
+ const outdir = `${distFolder}/es`;
50
+ const entryPoints = await fg(
51
+ inputFiles.concat([`!${srcPath}/**/cjs/**/*.{js,jsx,ts,tsx}`]),
52
+ );
53
+ await esbuild.build({
54
+ entryPoints,
55
+ ...commonConfig,
56
+ outdir,
57
+ format: 'esm',
58
+ });
59
+ await copyFiles({ srcdir: srcPath, outdir });
60
+ }
61
+ };
62
+
63
+ exports.esBuild = build;
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export { React };
@@ -0,0 +1,13 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { merge } = require('lodash');
4
+
5
+ let projectConfig = {};
6
+ const projectPath = path.join(process.cwd(), '.swcrc');
7
+ if (fs.existsSync(projectPath)) {
8
+ projectConfig = JSON.parse(fs.readFileSync(projectPath, 'utf-8'));
9
+ }
10
+ const localConfig = JSON.parse(
11
+ fs.readFileSync(path.join(__dirname, '.swcrc'), 'utf-8'),
12
+ );
13
+ module.exports = merge(localConfig, projectConfig);
@@ -0,0 +1,66 @@
1
+ const execa = require('execa');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const { randomChars, resolveFromRoot } = require('./utils');
6
+
7
+ const args = process.argv.slice(2);
8
+ const argsProjectIndex = args.findIndex((arg) =>
9
+ ['-p', '--project'].includes(arg),
10
+ );
11
+ const argsProjectValue =
12
+ argsProjectIndex !== -1 ? args[argsProjectIndex + 1] : undefined;
13
+
14
+ const files = args.filter((file) => /\.(ts|tsx)$/.test(file));
15
+ if (files.length === 0) {
16
+ process.exit(0);
17
+ }
18
+
19
+ const remainingArgsToForward = args
20
+ .slice()
21
+ .filter((arg) => !files.includes(arg));
22
+
23
+ if (argsProjectIndex !== -1) {
24
+ remainingArgsToForward.splice(argsProjectIndex, 2);
25
+ }
26
+
27
+ // Load existing config
28
+ const tsconfigPath = argsProjectValue || resolveFromRoot('tsconfig.json');
29
+ const tsconfigContent = fs.readFileSync(tsconfigPath).toString();
30
+ // Use 'eval' to read the JSON as regular JavaScript syntax so that comments are allowed
31
+ // eslint-disable-next-line prefer-const
32
+ let tsconfig = {};
33
+ // eslint-disable-next-line no-eval
34
+ eval(`tsconfig = ${tsconfigContent}`);
35
+
36
+ // Write a temp config file
37
+ const tmpTsconfigPath = resolveFromRoot(`tsconfig.${randomChars()}.json`);
38
+ const tmpTsconfig = {
39
+ ...tsconfig,
40
+ compilerOptions: {
41
+ ...tsconfig.compilerOptions,
42
+ skipLibCheck: true,
43
+ },
44
+ files,
45
+ include: ['app', 'lib'],
46
+ };
47
+ fs.writeFileSync(tmpTsconfigPath, JSON.stringify(tmpTsconfig, null, 2));
48
+
49
+ // Type-check our files
50
+ let status = 0;
51
+ try {
52
+ execa.sync(
53
+ path.resolve(
54
+ process.cwd(),
55
+ `./node_modules/.bin/tsc${process.platform === 'win32' ? '.cmd' : ''}`,
56
+ ),
57
+ ['-p', tmpTsconfigPath, ...remainingArgsToForward],
58
+ { stdio: 'inherit' },
59
+ );
60
+ } catch (ex) {
61
+ status = ex.exitCode;
62
+ }
63
+
64
+ // Delete temp config file
65
+ fs.unlinkSync(tmpTsconfigPath);
66
+ process.exit(status);
@@ -0,0 +1,16 @@
1
+ const { dirname, join } = require('path');
2
+
3
+ const randomChars = () => Math.random().toString(36).slice(2);
4
+
5
+ const resolveFromModule = (moduleName, ...paths) => {
6
+ const modulePath = dirname(require.resolve(`${moduleName}/package.json`));
7
+ return join(modulePath, ...paths);
8
+ };
9
+
10
+ const resolveFromRoot = (...paths) => join(process.cwd(), ...paths);
11
+
12
+ module.exports = {
13
+ randomChars,
14
+ resolveFromModule,
15
+ resolveFromRoot,
16
+ };
@@ -1,6 +1,9 @@
1
+ /* eslint-disable max-lines */
1
2
  const path = require('path');
2
3
  const fs = require('fs');
3
4
  const _ = require('lodash');
5
+ const CompressionPlugin = require('compression-webpack-plugin');
6
+ const zlib = require('zlib');
4
7
 
5
8
  let pathSep = path.sep;
6
9
  if (pathSep === '\\')
@@ -69,13 +72,11 @@ const getAlias = () =>
69
72
  '@babel/runtime',
70
73
  'react',
71
74
  'react-dom',
72
- 'react-router-dom',
73
75
  'react-redux',
74
76
  'redux',
75
77
  'redux-saga',
76
78
  'moment',
77
79
  'lodash',
78
- 'connected-react-router',
79
80
  'styled-components',
80
81
  'immer',
81
82
  'react-dates',
@@ -122,7 +123,6 @@ const getAppLoaderFileName = () => {
122
123
 
123
124
  const getDiagnosticsFileName = () => {
124
125
  const libName = 'emuiDiagnostics';
125
- // eslint-disable-next-line max-lines
126
126
  const libPath = path.join(
127
127
  process.cwd(),
128
128
  'node_modules/@elliemae/pui-diagnostics/dist/public/js',
@@ -185,6 +185,39 @@ const isGoogleTagManagerEnabled = () => {
185
185
  return !!appConfig?.googleTagManager;
186
186
  };
187
187
 
188
+ const getCompressionPlugins = (isLibrary = false) => {
189
+ const excludeList = [
190
+ /\/adrum-ext/,
191
+ /\/emuiUserMonitoring/,
192
+ /\/emuiDiagnostics/,
193
+ /\/emuiAppLoader/,
194
+ /\/encwLoader/,
195
+ ];
196
+ const commonConfig = {
197
+ test: /\.(js|css)$/,
198
+ exclude: !isLibrary ? excludeList : [],
199
+ // we are compressing all files since in aws cloudfront edge lambda, we don't want to whitelist files that are not compressed due to below limits
200
+ minRatio: Number.MAX_SAFE_INTEGER,
201
+ };
202
+ return [
203
+ new CompressionPlugin({
204
+ filename: '[path][base].gz',
205
+ algorithm: 'gzip',
206
+ ...commonConfig,
207
+ }),
208
+ new CompressionPlugin({
209
+ filename: '[path][base].br',
210
+ algorithm: 'brotliCompress',
211
+ ...commonConfig,
212
+ compressionOptions: {
213
+ params: {
214
+ [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
215
+ },
216
+ },
217
+ }),
218
+ ];
219
+ };
220
+
188
221
  exports.excludeNodeModulesExcept = excludeNodeModulesExcept;
189
222
  exports.getLibraryName = getLibraryName;
190
223
  exports.getAppConfig = getAppConfig;
@@ -209,3 +242,4 @@ exports.resolveExtensions = [
209
242
  ];
210
243
  exports.mainFields = ['browser', 'module', 'main'];
211
244
  exports.isGoogleTagManagerEnabled = isGoogleTagManagerEnabled;
245
+ exports.getCompressionPlugins = getCompressionPlugins;
@@ -4,11 +4,11 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
4
  const PostcssPresetEnv = require('postcss-preset-env');
5
5
  const CopyWebpackPlugin = require('copy-webpack-plugin');
6
6
  const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
7
- const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
8
7
  const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
9
8
  const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
10
- const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
11
- const { ProvidePlugin } = require('webpack');
9
+ const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
10
+ const { ProvidePlugin, ProgressPlugin } = require('webpack');
11
+ const browserslistToEsbuild = require('browserslist-to-esbuild');
12
12
 
13
13
  const {
14
14
  excludeNodeModulesExcept,
@@ -16,13 +16,8 @@ const {
16
16
  modulesToTranspile,
17
17
  getAlias,
18
18
  getPaths,
19
- getMediaPath,
20
19
  } = require('./helpers');
21
- const { ESBUILD_TARGET } = require('../esbuild');
22
- const { isTypeScriptEnabled } = require('../typescript/util');
23
20
 
24
- // get the application configuration
25
- const devMode = process.env.NODE_ENV !== 'production';
26
21
  const minicssLoader = {
27
22
  loader: MiniCssExtractPlugin.loader,
28
23
  options: {},
@@ -35,9 +30,6 @@ const postcssPlugins = [PostcssPresetEnv({ autoprefixer: { grid: true } })];
35
30
  const { buildPath, publicPath } = getPaths();
36
31
 
37
32
  const plugins = [
38
- // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
39
- // inside your code for any environment checks; Terser will automatically
40
- // drop any unreachable code.
41
33
  new webpack.EnvironmentPlugin({
42
34
  NODE_ENV: 'development',
43
35
  ASSET_PATH: '/',
@@ -47,8 +39,6 @@ const plugins = [
47
39
  new webpack.DefinePlugin({
48
40
  APP_CONFIG: getAppConfig(),
49
41
  }),
50
- new CaseSensitivePathsPlugin(),
51
- // new ESLintPlugin(),
52
42
  new ProvidePlugin({
53
43
  React: 'react',
54
44
  }),
@@ -106,27 +96,27 @@ const plugins = [
106
96
  ],
107
97
  }),
108
98
  new DuplicatePackageCheckerPlugin(),
109
- new MomentLocalesPlugin(),
99
+ new MomentLocalesPlugin({ localesToKeep: ['es-us'] }),
110
100
  new WebpackManifestPlugin(),
111
- ];
112
-
113
- if (isTypeScriptEnabled()) {
114
- plugins.push(
115
- new ForkTsCheckerWebpackPlugin({
116
- async: devMode,
117
- eslint: {
118
- files: './app/**/*.{ts,js,tsx,jsx}',
101
+ new FaviconsWebpackPlugin({
102
+ logo: './app/view/images/favicon.png',
103
+ favicons: {
104
+ developerName: 'ICE MT',
105
+ developerURL: null, // prevent retrieving from the nearest package.json
106
+ icons: {
107
+ coast: false,
108
+ yandex: false,
119
109
  },
120
- }),
121
- );
122
- }
110
+ },
111
+ }),
112
+ new ProgressPlugin(),
113
+ ];
123
114
 
124
115
  module.exports = (options) => ({
125
116
  mode: options.mode,
126
117
  entry: options.entry,
127
118
  output: {
128
119
  clean: true,
129
- // Compile into js/build.js
130
120
  path: buildPath,
131
121
  publicPath,
132
122
  ...options.output,
@@ -135,39 +125,7 @@ module.exports = (options) => ({
135
125
  module: {
136
126
  rules: [
137
127
  {
138
- test: /\.(jpe?g|png|gif|svg|ico)$/,
139
- use: [
140
- 'file-loader',
141
- {
142
- loader: 'image-webpack-loader',
143
- options: {
144
- gifsicle: {
145
- enabled: false,
146
- },
147
- },
148
- },
149
- ],
150
- enforce: 'pre',
151
- },
152
- {
153
- test: /\.(js|ts|jsx|tsx)$/,
154
- enforce: 'pre',
155
- exclude: /node_modules/,
156
- resolve: {
157
- fullySpecified: false,
158
- },
159
- use: [
160
- {
161
- loader: 'webpack-strip-block',
162
- options: {
163
- start: 'TEST:START',
164
- end: 'TEST:END',
165
- },
166
- },
167
- ],
168
- },
169
- {
170
- test: /\.(js|jsx)$/,
128
+ test: /\.jsx?$/,
171
129
  exclude: excludeNodeModulesExcept(modulesToTranspile),
172
130
  resolve: {
173
131
  fullySpecified: false,
@@ -176,12 +134,12 @@ module.exports = (options) => ({
176
134
  loader: 'esbuild-loader',
177
135
  options: {
178
136
  loader: 'jsx',
179
- target: ESBUILD_TARGET,
137
+ target: browserslistToEsbuild(),
180
138
  },
181
139
  },
182
140
  },
183
141
  {
184
- test: /\.(ts|tsx)$/,
142
+ test: /\.tsx?$/,
185
143
  exclude: excludeNodeModulesExcept(modulesToTranspile),
186
144
  resolve: {
187
145
  fullySpecified: false,
@@ -190,12 +148,15 @@ module.exports = (options) => ({
190
148
  loader: 'esbuild-loader',
191
149
  options: {
192
150
  loader: 'tsx',
193
- target: ESBUILD_TARGET,
151
+ target: browserslistToEsbuild(),
194
152
  },
195
153
  },
196
154
  },
197
155
  {
198
156
  test: /\.css$/,
157
+ exclude: excludeNodeModulesExcept(
158
+ modulesToTranspile.concat(['sanitize.css']),
159
+ ),
199
160
  use: [
200
161
  finalCSSLoader(options.mode),
201
162
  {
@@ -205,13 +166,6 @@ module.exports = (options) => ({
205
166
  sourceMap: true,
206
167
  },
207
168
  },
208
- {
209
- loader: 'esbuild-loader',
210
- options: {
211
- loader: 'css',
212
- minify: options.mode === 'production',
213
- },
214
- },
215
169
  {
216
170
  loader: 'postcss-loader',
217
171
  options: {
@@ -225,47 +179,39 @@ module.exports = (options) => ({
225
179
  },
226
180
  {
227
181
  test: /\.(woff|woff2)$/,
228
- exclude: excludeNodeModulesExcept(['@elliemae/*']),
229
182
  type: 'asset/resource',
183
+ exclude: excludeNodeModulesExcept(modulesToTranspile),
230
184
  },
231
185
  {
232
- test: /\.svg$/,
233
- exclude: excludeNodeModulesExcept(['@elliemae/*']),
234
- use: [
235
- {
236
- loader: '@svgr/webpack',
237
- },
238
- {
239
- loader: 'file-loader',
240
- options: {
241
- name: getMediaPath(),
242
- },
243
- },
244
- ],
245
- },
246
- {
247
- test: /\.(jpe?g|png|gif|ico)$/i,
248
- exclude: excludeNodeModulesExcept(['@elliemae/*']),
249
- type: 'asset',
186
+ test: /\.svg$/i,
187
+ issuer: /\.[jt]sx?$/,
188
+ resourceQuery: /^((?!url).)*$/,
189
+ exclude: excludeNodeModulesExcept(modulesToTranspile),
190
+ use: ['@svgr/webpack'],
250
191
  },
251
192
  {
252
- test: /\.(mp4|webm)$/,
253
- exclude: excludeNodeModulesExcept(['@elliemae/*']),
193
+ test: /\.(jpe?g|png|gif|ico|mp4|webm)$/i,
194
+ exclude: excludeNodeModulesExcept(modulesToTranspile),
254
195
  type: 'asset',
255
196
  },
256
197
  {
257
198
  resourceQuery: /resource/,
258
199
  type: 'asset/resource',
200
+ exclude: excludeNodeModulesExcept(modulesToTranspile),
201
+ },
202
+ {
203
+ type: 'asset',
204
+ resourceQuery: /url/,
205
+ exclude: excludeNodeModulesExcept(modulesToTranspile),
259
206
  },
260
207
  ],
261
208
  },
262
209
  plugins: plugins.concat(options.plugins),
263
210
  resolve: {
264
211
  modules: ['node_modules', 'app', 'lib'],
265
- extensions: ['.wasm', '.mjs', '.ts', '.tsx', '.js', '.jsx', '.json'],
212
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.wasm', '.mjs'],
266
213
  mainFields: ['browser', 'module', 'main'],
267
214
  alias: {
268
- 'lodash-es': 'lodash',
269
215
  ...getAlias(),
270
216
  ...((options.resolve || {}).alias || {}),
271
217
  },
@@ -276,6 +222,5 @@ module.exports = (options) => ({
276
222
  '@elliemae/pui-diagnostics': 'emuiDiagnostics',
277
223
  },
278
224
  devtool: options.devtool || 'eval-source-map',
279
- target: 'web', // Make web variables accessible to webpack, e.g. window
280
225
  performance: options.performance || {},
281
226
  });
@@ -4,6 +4,9 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
4
4
  const CircularDependencyPlugin = require('circular-dependency-plugin');
5
5
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
6
  const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
7
+ const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
8
+
9
+ const smp = new SpeedMeasurePlugin({ disable: !process.env.MEASURE });
7
10
 
8
11
  const {
9
12
  getAssetPath,
@@ -72,6 +75,7 @@ const devConfig = {
72
75
 
73
76
  // Add development plugins
74
77
  plugins: [
78
+ new webpack.ProgressPlugin(),
75
79
  new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
76
80
  new ReactRefreshWebpackPlugin({
77
81
  overlay: {
@@ -79,6 +83,7 @@ const devConfig = {
79
83
  },
80
84
  }),
81
85
  new HtmlWebpackPlugin({
86
+ scriptLoading: 'module',
82
87
  inject: !isAppLoaderEnabled(), // Inject all files that are generated by webpack, e.g. bundle.js
83
88
  template: !isAppLoaderEnabled()
84
89
  ? 'app/index.html'
@@ -105,8 +110,6 @@ const devConfig = {
105
110
  }),
106
111
  ],
107
112
 
108
- // Emit a source map for easier debugging
109
- // See https://webpack.js.org/configuration/devtool/#devtool
110
113
  devtool: 'eval-source-map',
111
114
 
112
115
  performance: {
@@ -114,4 +117,4 @@ const devConfig = {
114
117
  },
115
118
  };
116
119
 
117
- module.exports = baseConfigFactory(devConfig);
120
+ module.exports = smp.wrap(baseConfigFactory(devConfig));