@elliemae/pui-cli 6.0.0-beta.1 → 6.0.0-beta.10

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.
@@ -10,7 +10,7 @@ const nodeEnvPreset = {
10
10
  const webEnvPreset = {
11
11
  modules: process.env.ES_MODULES === 'false' ? 'commonjs' : false,
12
12
  useBuiltIns: 'usage',
13
- corejs: { version: '3.18', proposals: true },
13
+ corejs: { version: '3.19', proposals: true },
14
14
  };
15
15
 
16
16
  const presetEnvOptions =
@@ -39,13 +39,14 @@ const config = {
39
39
  '@babel/plugin-proposal-class-properties',
40
40
  '@babel/plugin-syntax-dynamic-import',
41
41
  '@babel/plugin-proposal-export-default-from',
42
+ 'lodash',
43
+ 'date-fns',
42
44
  ],
43
45
  env: {
44
46
  development: {
45
47
  plugins: [
46
48
  ['babel-plugin-styled-components', { displayName: true }],
47
49
  '@babel/plugin-transform-react-jsx-source',
48
- 'react-refresh/babel',
49
50
  ],
50
51
  },
51
52
  production: {
@@ -79,7 +80,11 @@ if (process.env.MODULE_EXTENSIONS === 'true') {
79
80
  config.plugins.push('babel-plugin-add-import-extension');
80
81
  }
81
82
 
82
- // ToDo: Once ECC team migrates from webpack 3 to webpack 5 remove tis strip-block plugin from commonjs output. without this they are receiving error when import.meta is used in app sdk
83
+ if (process.env.STORYBOOK_BUILD !== 'true') {
84
+ config.env?.development?.plugins?.push?.('react-refresh/babel');
85
+ }
86
+
87
+ // ToDo: Once ECC team migrates from webpack 3 to webpack 5 remove this strip-block plugin from commonjs output. without this they are receiving error when import.meta is used in app sdk
83
88
  if (process.env.ES_MODULES === 'false') {
84
89
  config.plugins.push([
85
90
  'babel-plugin-transform-strip-block',
@@ -21,7 +21,7 @@ async function buildWebApp() {
21
21
  async function buildService() {
22
22
  await exec('rimraf ./build');
23
23
  await exec(
24
- `cross-env NODE_ENV=production MODULE_EXTENSIONS=true TARGET_ENV=node babel --extensions '.ts,.js' --config-file ./babel.config.cjs --out-dir ./build --ignore '**/*.test.js','**/*.test.ts' ./app`,
24
+ `cross-env NODE_ENV=production MODULE_EXTENSIONS=true TARGET_ENV=node babel --extensions '.ts,.js' --config-file ./babel.config.cjs --out-dir ./build --copy-files --no-copy-ignored --ignore '**/*.test.ts','**/*.test.js','**/*.spec.ts','**/*.test.js' ./app`,
25
25
  );
26
26
  }
27
27
 
@@ -1,10 +1,11 @@
1
1
  const { exit } = require('yargs');
2
2
  const { exec, logError, logSuccess } = require('./utils');
3
- const { isTypeScripEnabled } = require('../typescript/util');
3
+ const { isTypeScriptEnabled } = require('../typescript/util');
4
4
 
5
- async function lintCSS() {
5
+ async function lintCSS(fix = false) {
6
+ const fixIssues = fix ? '--fix' : '';
6
7
  await exec(
7
- `stylelint "./**/*.{js, ts}" --color --allowEmptyInput --ignore-pattern '/dist/**/*'`,
8
+ `stylelint ./{lib,app}/**/*.{js,jsx,ts,tsx} ${fixIssues} --color --allowEmptyInput --ignore-pattern /dist/**/*`,
8
9
  );
9
10
  }
10
11
 
@@ -18,7 +19,8 @@ async function lintJS(fix = false) {
18
19
  async function handler(argv) {
19
20
  if (argv.js) {
20
21
  // run typescript compilation
21
- if (isTypeScripEnabled) await exec('tsc');
22
+ if (isTypeScriptEnabled())
23
+ await exec('tsc --noEmit --emitDeclarationOnly false');
22
24
  try {
23
25
  await exec('rimraf ./reports/eslint.json');
24
26
  await lintJS(argv.fix);
@@ -1,8 +1,10 @@
1
+ /* eslint-disable max-lines */
1
2
  const { exit } = require('yargs');
2
3
  const path = require('path');
3
4
  const { writeFile, readFile } = require('fs/promises');
4
5
  const { exec, logInfo, logError, logSuccess } = require('./utils');
5
- const { isTypeScripEnabled } = require('../typescript/util');
6
+ const { isTypeScriptEnabled } = require('../typescript/util');
7
+ const { esBuild } = require('../esbuild');
6
8
 
7
9
  const { name } = require('../../package.json');
8
10
 
@@ -37,14 +39,9 @@ async function createPackageJson(file, commonJS, sideEffects) {
37
39
  await writeFile(file, packageJSON);
38
40
  }
39
41
 
40
- async function nodeBuild({ srcPath, commonJS, emitModuleType, target }) {
42
+ async function nodeBuild({ srcPath, commonJS, emitModuleType }) {
41
43
  const outDir = `./dist/${commonJS ? 'cjs' : 'es'}`;
42
- const targetEnv = target === 'node' ? 'TARGET_ENV=node' : '';
43
- const babelEnv = commonJS ? ' ES_MODULES=false' : '';
44
- await exec(
45
- `cross-env NODE_ENV=production MODULE_EXTENSIONS=true ${targetEnv}${babelEnv} babel --extensions ".ts,.tsx,.js,.jsx" ${srcPath} --out-dir ${outDir} --copy-files --ignore **/*.test.js --ignore **/*.test.ts --ignore **/*.spec.js --ignore **/*.spec.ts --ignore **/*.test.jsx --ignore **/*.test.tsx --ignore **/*.spec.jsx --ignore **/*.spec.tsx`,
46
- { shell: true, stdio: 'inherit' },
47
- );
44
+ await esBuild({ srcPath, commonJS });
48
45
  if (emitModuleType) {
49
46
  const sideEffects = await getSideEffects();
50
47
  await createPackageJson(
@@ -58,7 +55,7 @@ async function nodeBuild({ srcPath, commonJS, emitModuleType, target }) {
58
55
  async function pack({ production, target, module, srcPath, emitModuleType }) {
59
56
  logInfo('Build in-progress...');
60
57
  await exec('rimraf ./dist');
61
- if (isTypeScripEnabled()) {
58
+ if (isTypeScriptEnabled()) {
62
59
  await compileTypeScript();
63
60
  }
64
61
  if (target !== 'node') await webBuild(production);
@@ -79,7 +76,6 @@ async function pack({ production, target, module, srcPath, emitModuleType }) {
79
76
  srcPath,
80
77
  commonJS: false,
81
78
  emitModuleType,
82
- target,
83
79
  });
84
80
  }
85
81
  }
@@ -118,7 +114,6 @@ exports.builder = {
118
114
  },
119
115
  emitModuleType: {
120
116
  type: 'boolean',
121
- // eslint-disable-next-line max-lines
122
117
  default: true,
123
118
  description:
124
119
  'creates type attribute in the package.json and sets its value to commonjs or module based on module cli argument. default: true',
@@ -10,7 +10,7 @@ async function buildStoryBook(isDoc = false) {
10
10
 
11
11
  async function startStoryBook(isDoc = false) {
12
12
  await exec(
13
- `cross-env FORCE_COLOR=true start-storybook ${
13
+ `cross-env NODE_ENV=development STORYBOOK_BUILD=true FORCE_COLOR=true start-storybook ${
14
14
  isDoc && '--docs'
15
15
  } -p 11000 --quiet`,
16
16
  );
@@ -13,7 +13,8 @@ async function handler(argv) {
13
13
  let commandOptions = '--coverage';
14
14
  if (argv.fix) commandOptions = '-u';
15
15
  else if (argv.watch) commandOptions = '--watchAll';
16
- if (CI) commandOptions += ' --ci';
16
+ if (CI) commandOptions += ' --ci --runInBand';
17
+ else commandOptions += ' --maxWorkers=50%';
17
18
  if (argv.p) commandOptions += ' --passWithNoTests';
18
19
  if (argv.r) commandOptions += ' --bail --findRelatedTests';
19
20
  if (argv.s) commandOptions += ' --silent';
package/lib/esbuild.js ADDED
@@ -0,0 +1,44 @@
1
+ const esbuild = require('esbuild');
2
+ const fg = require('fast-glob');
3
+
4
+ const ESBUILD_TARGET = 'es2020';
5
+
6
+ const commonConfig = {
7
+ bundle: false,
8
+ target: ESBUILD_TARGET,
9
+ loader: { '.js': 'jsx' },
10
+ mainFields: ['module', 'browser', 'main'],
11
+ };
12
+
13
+ const outDir = 'dist';
14
+
15
+ const build = async ({ srcPath, commonJS }) => {
16
+ const inputFiles = [
17
+ `${srcPath}/**/*.{js,jsx,ts,tsx}`,
18
+ `!${srcPath}/**/*.test.{js,jsx,ts,tsx}`,
19
+ `!${srcPath}/**/*.stories.{js,jsx,ts,tsx}`,
20
+ `!${srcPath}/**/*.endpoint.{js,jsx,ts,tsx}`,
21
+ ];
22
+ if (!commonJS) {
23
+ const entryPoints = await fg(inputFiles);
24
+ await esbuild.build({
25
+ entryPoints,
26
+ ...commonConfig,
27
+ outdir: `${outDir}/es`,
28
+ format: 'esm',
29
+ });
30
+ } else {
31
+ const commonJSEntryPoints = await fg(
32
+ inputFiles.concat([`${srcPath}/**/*.cjs`]),
33
+ );
34
+ await esbuild.build({
35
+ entryPoints: commonJSEntryPoints,
36
+ ...commonConfig,
37
+ outdir: `${outDir}/cjs`,
38
+ format: 'cjs',
39
+ });
40
+ }
41
+ };
42
+
43
+ exports.esBuild = build;
44
+ exports.ESBUILD_TARGET = ESBUILD_TARGET;
@@ -112,16 +112,15 @@ const reactRules = {
112
112
  exports.reactRules = reactRules;
113
113
 
114
114
  exports.baseConfig = {
115
- parser: 'babel-eslint',
115
+ parser: '@babel/eslint-parser',
116
116
  plugins: basePlugins,
117
117
  env: {
118
118
  jest: true,
119
119
  browser: true,
120
120
  node: true,
121
- es6: true,
121
+ es2021: true,
122
122
  },
123
123
  parserOptions: {
124
- ecmaVersion: 2020,
125
124
  sourceType: 'module',
126
125
  ecmaFeatures: {
127
126
  jsx: true,
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- '*.{ts,tsx}': ['tsc-files'],
2
+ '*.{ts,tsx}': ['tsc-files --noEmit --emitDeclarationOnly false'],
3
3
  '*.{js,ts,jsx,tsx}': [
4
4
  'npm run lint:fix',
5
5
  'npm run test:staged',
@@ -1,16 +1,9 @@
1
1
  module.exports = {
2
- processors: [
3
- [
4
- 'stylelint-processor-styled-components',
5
- {
6
- ignoreFiles: ['**/*.scss'],
7
- },
8
- ],
9
- ],
2
+ customSyntax: '@stylelint/postcss-css-in-js',
10
3
  plugins: [],
11
4
  extends: [
12
5
  'stylelint-config-recommended',
13
6
  'stylelint-config-styled-components',
14
7
  ],
15
- rules: { 'selector-type-no-unknown': null },
8
+ rules: { 'selector-type-no-unknown': null, 'no-extra-semicolons': null },
16
9
  };
@@ -2,11 +2,11 @@ module.exports = {
2
2
  branches: [
3
3
  '+([0-9])?(.{+([0-9]),x}).x',
4
4
  'master',
5
- 'next',
6
5
  'next-major',
7
6
  { name: 'beta', prerelease: true },
8
7
  { name: 'alpha', prerelease: true },
9
8
  { name: 'hotfix', prerelease: true },
9
+ { name: 'next', prerelease: true },
10
10
  ],
11
11
  plugins: [
12
12
  '@semantic-release/commit-analyzer',
package/lib/server/csp.js CHANGED
@@ -12,6 +12,8 @@ const sources = [
12
12
  '*.ellielabs.com',
13
13
  'http://pdx-col.eum-appdynamics.com',
14
14
  'https://pdx-col.eum-appdynamics.com/',
15
+ 'https://www.google-analytics.com',
16
+ 'https://www.googletagmanager.com',
15
17
  ];
16
18
 
17
19
  const sendFileWithCSPNonce = ({
@@ -13,8 +13,11 @@ const { loadRoutes } = require('./util');
13
13
  const { getAssetPath } = require('../webpack/helpers');
14
14
 
15
15
  const pino = expressPinoLogger({
16
- prettyPrint: {
17
- levelFirst: true,
16
+ transport: {
17
+ target: 'pino-pretty',
18
+ options: {
19
+ colorize: true,
20
+ },
18
21
  },
19
22
  });
20
23
  pino.logger.level = 'warn';
@@ -3,9 +3,9 @@ const path = require('path');
3
3
 
4
4
  const getCWD = () => process.cwd();
5
5
 
6
- const allJS = new RegExp(/\.js$/);
6
+ const allJS = /\.js$/;
7
7
 
8
- const serviceEndpoints = new RegExp(/\.endpoint\.js$/);
8
+ const serviceEndpoints = /\.endpoint\.js$/;
9
9
 
10
10
  const getFilesMatching = (filePattern) => {
11
11
  const getFiles = (dir) => {
@@ -62,6 +62,7 @@ const jestConfig = {
62
62
  '.*\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|ico)$': `${getRootDir()}/lib/testing/mocks/image.js`,
63
63
  '.*\\.svg$': `${getRootDir()}/lib/testing/mocks/svg.js`,
64
64
  '.*\\.(html)$': `${getRootDir()}/lib/testing/mocks/html.js`,
65
+ '^lodash-es$': 'lodash',
65
66
  '@elliemae/pui-user-monitoring': `${getRootDir()}/lib/testing/mocks/pui-user-monitoring.js`,
66
67
  '@elliemae/pui-app-loader': `${getRootDir()}/lib/testing/mocks/pui-app-loader.js`,
67
68
  '@elliemae/pui-diagnostics': `${getRootDir()}/lib/testing/mocks/pui-diagnostics.js`,
@@ -74,7 +75,7 @@ const jestConfig = {
74
75
  snapshotSerializers: [],
75
76
  testResultsProcessor: 'jest-sonar-reporter',
76
77
  transformIgnorePatterns: [
77
- 'node_modules/(?!(@elliemae/*)/)',
78
+ 'node_modules/(?!(@elliemae/*|lodash-es/*)/)',
78
79
  'node_modules/@elliemae/em-platform-document-viewer',
79
80
  ],
80
81
  globals: {
@@ -1,3 +1,5 @@
1
- module.exports = {
2
- ReactComponent: 'IMAGE_MOCK',
3
- };
1
+ // eslint-disable-next-line no-unused-vars
2
+ import * as React from 'react';
3
+
4
+ export default 'SvgrURL';
5
+ export const ReactComponent = 'div';
@@ -1,5 +1,5 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
- exports.isTypeScripEnabled = () =>
4
+ exports.isTypeScriptEnabled = () =>
5
5
  fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
@@ -1,8 +1,6 @@
1
- /* eslint-disable max-lines */
2
1
  const path = require('path');
3
2
  const fs = require('fs');
4
3
  const _ = require('lodash');
5
- const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
6
4
 
7
5
  let pathSep = path.sep;
8
6
  if (pathSep === '\\')
@@ -89,7 +87,12 @@ const getAlias = () =>
89
87
  './node_modules',
90
88
  );
91
89
 
92
- const modulesToTranspile = ['@elliemae/pui-*', '@elliemae/ds-*', '@dnd-kit/*'];
90
+ const modulesToTranspile = [
91
+ '@elliemae/pui-*',
92
+ '@elliemae/ds-*',
93
+ '@dnd-kit/*',
94
+ '@elliemae/em-platform-document-viewer',
95
+ ];
93
96
 
94
97
  const getUserMonitoringFileName = () => {
95
98
  const libName = 'emuiUserMonitoring';
@@ -119,6 +122,7 @@ const getAppLoaderFileName = () => {
119
122
 
120
123
  const getDiagnosticsFileName = () => {
121
124
  const libName = 'emuiDiagnostics';
125
+ // eslint-disable-next-line max-lines
122
126
  const libPath = path.join(
123
127
  process.cwd(),
124
128
  'node_modules/@elliemae/pui-diagnostics/dist/public/js',
@@ -176,37 +180,10 @@ const isAppLoaderEnabled = () => process.env.APP_LOADER === 'true';
176
180
 
177
181
  const getMediaPath = () => `assets/[name].[contenthash].[ext]`;
178
182
 
179
- const getImageMinimizerPlugin = () =>
180
- new ImageMinimizerPlugin({
181
- minimizerOptions: {
182
- // Lossless optimization with custom option
183
- // Feel free to experiment with options for better result for you
184
- plugins: [
185
- ['gifsicle', { interlaced: true }],
186
- ['jpegtran', { progressive: true }],
187
- ['optipng', { optimizationLevel: 5 }],
188
- // Svgo configuration here https://github.com/svg/svgo#configuration
189
- [
190
- 'svgo',
191
- {
192
- plugins: [
193
- {
194
- name: 'preset-default',
195
- params: {
196
- overrides: {
197
- removeViewBox: false,
198
- addAttributesToSVGElement: {
199
- attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
200
- },
201
- },
202
- },
203
- },
204
- ],
205
- },
206
- ],
207
- ],
208
- },
209
- });
183
+ const isGoogleTagManagerEnabled = () => {
184
+ const appConfig = JSON.parse(getAppConfig());
185
+ return !!appConfig?.googleTagManager;
186
+ };
210
187
 
211
188
  exports.excludeNodeModulesExcept = excludeNodeModulesExcept;
212
189
  exports.getLibraryName = getLibraryName;
@@ -221,7 +198,6 @@ exports.isAppLoaderEnabled = isAppLoaderEnabled;
221
198
  exports.LATEST_VERSION = LATEST_VERSION;
222
199
  exports.getPaths = getPaths;
223
200
  exports.getMediaPath = getMediaPath;
224
- exports.getImageMinimizerPlugin = getImageMinimizerPlugin;
225
201
  exports.resolveExtensions = [
226
202
  '.wasm',
227
203
  '.mjs',
@@ -232,3 +208,4 @@ exports.resolveExtensions = [
232
208
  '.json',
233
209
  ];
234
210
  exports.mainFields = ['browser', 'module', 'main'];
211
+ exports.isGoogleTagManagerEnabled = isGoogleTagManagerEnabled;
@@ -1,10 +1,5 @@
1
1
  /* eslint-disable max-lines */
2
- /**
3
- * COMMON WEBPACK CONFIGURATION
4
- */
5
-
6
2
  const webpack = require('webpack');
7
- const StyleLintPlugin = require('stylelint-webpack-plugin');
8
3
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
9
4
  const PostcssPresetEnv = require('postcss-preset-env');
10
5
  const CopyWebpackPlugin = require('copy-webpack-plugin');
@@ -12,9 +7,7 @@ const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack
12
7
  const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
13
8
  const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
14
9
  const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
15
- const stylelintFormatter = require('stylelint-formatter-pretty');
16
- // const ESLintPlugin = require('eslint-webpack-plugin');
17
- const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
10
+ const { ProvidePlugin } = require('webpack');
18
11
 
19
12
  const {
20
13
  excludeNodeModulesExcept,
@@ -22,13 +15,10 @@ const {
22
15
  modulesToTranspile,
23
16
  getAlias,
24
17
  getPaths,
25
- getMediaPath,
26
- getImageMinimizerPlugin,
27
18
  } = require('./helpers');
28
- const { isTypeScripEnabled } = require('../typescript/util');
19
+ const { ESBUILD_TARGET } = require('../esbuild');
29
20
 
30
21
  // get the application configuration
31
- const devMode = process.env.NODE_ENV !== 'production';
32
22
  const minicssLoader = {
33
23
  loader: MiniCssExtractPlugin.loader,
34
24
  options: {},
@@ -55,13 +45,8 @@ const plugins = [
55
45
  }),
56
46
  new CaseSensitivePathsPlugin(),
57
47
  // new ESLintPlugin(),
58
- new StyleLintPlugin({
59
- emitError: true,
60
- emitWarning: true,
61
- allowEmptyInput: true,
62
- failOnError: !devMode,
63
- formatter: stylelintFormatter,
64
- files: '(lib|app)/**/view/**/*.{js,ts,jsx,tsx}',
48
+ new ProvidePlugin({
49
+ React: 'react',
65
50
  }),
66
51
  new CopyWebpackPlugin({
67
52
  patterns: [
@@ -81,21 +66,29 @@ const plugins = [
81
66
  {
82
67
  from: 'node_modules/@elliemae/pui-user-monitoring/dist/public/js',
83
68
  to: 'js',
69
+ toType: 'dir',
70
+ info: { minimized: true },
84
71
  },
85
72
  {
86
- from: 'node_modules/@elliemae/pui-app-loader/dist/public/js/emuiAppLoader*.js',
87
- to: 'js/[name][ext]',
73
+ from: 'node_modules/@elliemae/pui-app-loader/dist/public/js',
74
+ to: 'js',
75
+ toType: 'dir',
88
76
  noErrorOnMissing: true,
77
+ info: { minimized: true },
89
78
  },
90
79
  {
91
- from: 'node_modules/@elliemae/encw-loader/dist/public/js/emuiEncwLoader*.js',
92
- to: 'js/[name][ext]',
80
+ from: 'node_modules/@elliemae/encw-loader/dist/public/js',
81
+ to: 'js',
82
+ toType: 'dir',
93
83
  noErrorOnMissing: true,
84
+ info: { minimized: true },
94
85
  },
95
86
  {
96
- from: 'node_modules/@elliemae/pui-diagnostics/dist/public/js/emuiDiagnostics*.js',
97
- to: 'js/[name][ext]',
87
+ from: 'node_modules/@elliemae/pui-diagnostics/dist/public/js',
88
+ to: 'js',
89
+ toType: 'dir',
98
90
  noErrorOnMissing: true,
91
+ info: { minimized: true },
99
92
  },
100
93
  {
101
94
  from: 'public',
@@ -111,20 +104,8 @@ const plugins = [
111
104
  new DuplicatePackageCheckerPlugin(),
112
105
  new MomentLocalesPlugin(),
113
106
  new WebpackManifestPlugin(),
114
- getImageMinimizerPlugin(),
115
107
  ];
116
108
 
117
- if (isTypeScripEnabled()) {
118
- plugins.push(
119
- new ForkTsCheckerWebpackPlugin({
120
- async: devMode,
121
- eslint: {
122
- files: './app/**/*.{ts,js,tsx,jsx}',
123
- },
124
- }),
125
- );
126
- }
127
-
128
109
  module.exports = (options) => ({
129
110
  mode: options.mode,
130
111
  entry: options.entry,
@@ -138,6 +119,21 @@ module.exports = (options) => ({
138
119
  optimization: options.optimization,
139
120
  module: {
140
121
  rules: [
122
+ {
123
+ test: /\.(jpe?g|png|gif|svg|ico)$/,
124
+ use: [
125
+ 'file-loader',
126
+ {
127
+ loader: 'image-webpack-loader',
128
+ options: {
129
+ gifsicle: {
130
+ enabled: false,
131
+ },
132
+ },
133
+ },
134
+ ],
135
+ enforce: 'pre',
136
+ },
141
137
  {
142
138
  test: /\.(js|ts|jsx|tsx)$/,
143
139
  enforce: 'pre',
@@ -165,7 +161,7 @@ module.exports = (options) => ({
165
161
  loader: 'esbuild-loader',
166
162
  options: {
167
163
  loader: 'jsx',
168
- target: 'es2020',
164
+ target: ESBUILD_TARGET,
169
165
  },
170
166
  },
171
167
  },
@@ -179,7 +175,7 @@ module.exports = (options) => ({
179
175
  loader: 'esbuild-loader',
180
176
  options: {
181
177
  loader: 'tsx',
182
- target: 'es2020',
178
+ target: ESBUILD_TARGET,
183
179
  },
184
180
  },
185
181
  },
@@ -194,6 +190,13 @@ module.exports = (options) => ({
194
190
  sourceMap: true,
195
191
  },
196
192
  },
193
+ {
194
+ loader: 'esbuild-loader',
195
+ options: {
196
+ loader: 'css',
197
+ minify: options.mode === 'production',
198
+ },
199
+ },
197
200
  {
198
201
  loader: 'postcss-loader',
199
202
  options: {
@@ -211,22 +214,16 @@ module.exports = (options) => ({
211
214
  type: 'asset/resource',
212
215
  },
213
216
  {
214
- test: /\.svg$/,
215
- exclude: excludeNodeModulesExcept(['@elliemae/*']),
216
- use: [
217
- {
218
- loader: '@svgr/webpack',
219
- },
220
- {
221
- loader: 'file-loader',
222
- options: {
223
- name: getMediaPath(),
224
- },
225
- },
226
- ],
217
+ type: 'asset',
218
+ resourceQuery: /url/, // *.svg?react
219
+ },
220
+ {
221
+ test: /\.svg$/i,
222
+ issuer: /\.[jt]sx?$/,
223
+ use: ['@svgr/webpack'],
227
224
  },
228
225
  {
229
- test: /\.(jpe?g|png|gif)$/i,
226
+ test: /\.(jpe?g|png|gif|ico)$/i,
230
227
  exclude: excludeNodeModulesExcept(['@elliemae/*']),
231
228
  type: 'asset',
232
229
  },
@@ -247,6 +244,7 @@ module.exports = (options) => ({
247
244
  extensions: ['.wasm', '.mjs', '.ts', '.tsx', '.js', '.jsx', '.json'],
248
245
  mainFields: ['browser', 'module', 'main'],
249
246
  alias: {
247
+ 'lodash-es': 'lodash',
250
248
  ...getAlias(),
251
249
  ...((options.resolve || {}).alias || {}),
252
250
  },
@@ -1,7 +1,3 @@
1
- /**
2
- * DEVELOPMENT WEBPACK CONFIGURATION
3
- */
4
-
5
1
  const path = require('path');
6
2
  const webpack = require('webpack');
7
3
  const HtmlWebpackPlugin = require('html-webpack-plugin');
@@ -9,7 +5,12 @@ const CircularDependencyPlugin = require('circular-dependency-plugin');
9
5
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
10
6
  const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
11
7
 
12
- const { getAssetPath, isAppLoaderEnabled, getPaths } = require('./helpers');
8
+ const {
9
+ getAssetPath,
10
+ isAppLoaderEnabled,
11
+ getPaths,
12
+ isGoogleTagManagerEnabled,
13
+ } = require('./helpers');
13
14
  const baseConfigFactory = require('./webpack.base.babel');
14
15
 
15
16
  const {
@@ -25,6 +26,14 @@ const {
25
26
  const devConfig = {
26
27
  mode: 'development',
27
28
 
29
+ cache: {
30
+ type: 'filesystem',
31
+ allowCollectingMemory: true,
32
+ buildDependencies: {
33
+ config: [__filename],
34
+ },
35
+ },
36
+
28
37
  // Add hot reloading in development
29
38
  entry: {
30
39
  app: [
@@ -83,6 +92,7 @@ const devConfig = {
83
92
  appLoaderScriptPath,
84
93
  diagnosticsScriptPath,
85
94
  encwLoaderScriptPath,
95
+ googleTagManager: isGoogleTagManagerEnabled(),
86
96
  },
87
97
  }),
88
98
  new CircularDependencyPlugin({