@elliemae/pui-cli 6.16.0 → 7.0.0-beta.11

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.
@@ -1,20 +1,24 @@
1
1
  const { exit } = require('yargs');
2
+ const path = require('path');
2
3
  const {
3
4
  exec,
4
5
  logInfo,
5
6
  logError,
6
7
  logSuccess,
7
8
  writeAppInfo,
9
+ copyBuildAssetsToVersionedFolder,
8
10
  } = require('./utils');
9
11
  const { esBuild, TARGETS } = require('../transpile/esbuild');
10
12
 
11
- const { name } = require('../../package.json');
12
-
13
13
  async function buildWebApp() {
14
14
  await exec(`rimraf ./build`);
15
15
  await exec(
16
- `cross-env NODE_ENV=production webpack --config node_modules/${name}/lib/webpack/webpack.prod.babel.js --color`,
16
+ `cross-env NODE_ENV=production webpack --config ${path.resolve(
17
+ __dirname,
18
+ '../webpack/webpack.prod.babel.js',
19
+ )} --color`,
17
20
  );
21
+ await copyBuildAssetsToVersionedFolder();
18
22
  await writeAppInfo();
19
23
  }
20
24
 
@@ -1,17 +1,22 @@
1
+ const path = require('path');
1
2
  const { exit } = require('yargs');
2
3
  const { exec, logError, logSuccess } = require('./utils');
3
4
 
4
- const { name } = require('../../package.json');
5
-
6
5
  async function startProdServer() {
7
6
  await exec(
8
- `cross-env NODE_ENV=production ts-node node_modules/${name}/lib/server --color always`,
7
+ `cross-env NODE_ENV=production ts-node ${path.resolve(
8
+ __dirname,
9
+ '../server',
10
+ )} --color always`,
9
11
  );
10
12
  }
11
13
 
12
14
  async function startDevServer() {
13
15
  await exec(
14
- `cross-env NODE_ENV=development ts-node node_modules/${name}/lib/server --color always`,
16
+ `cross-env NODE_ENV=development webpack serve --config ${path.resolve(
17
+ __dirname,
18
+ '../webpack/webpack.dev.babel.js',
19
+ )}`,
15
20
  );
16
21
  }
17
22
 
@@ -1,9 +1,21 @@
1
+ /* eslint-disable max-lines */
1
2
  /* eslint-disable no-console */
2
3
  const execa = require('execa');
3
4
  const chalk = require('chalk');
4
5
  const path = require('path');
5
- const { readFile, writeFile } = require('fs/promises');
6
- const { getPaths } = require('../webpack/helpers');
6
+ const {
7
+ readFile,
8
+ writeFile,
9
+ mkdir,
10
+ readdir,
11
+ copyFile,
12
+ } = require('fs/promises');
13
+ const {
14
+ getPaths,
15
+ isAppLoaderEnabled,
16
+ getAppVersion,
17
+ LATEST_VERSION,
18
+ } = require('../webpack/helpers');
7
19
 
8
20
  const browsersMapping = {
9
21
  and_chr: 'Chrome for Android',
@@ -87,3 +99,37 @@ exports.writeAppInfo = async () => {
87
99
  path.join(process.cwd(), 'build', 'public', 'info.json'),
88
100
  ].forEach(async (infoPath) => writeFile(infoPath, infoJSON));
89
101
  };
102
+
103
+ const copyDir = async (src, dest) => {
104
+ const entries = await readdir(src, {
105
+ withFileTypes: true,
106
+ });
107
+ await mkdir(dest);
108
+ return Promise.all(
109
+ entries.map((entry) => {
110
+ const srcPath = path.join(src, entry.name);
111
+ const destPath = path.join(dest, entry.name);
112
+ if (entry.isDirectory()) {
113
+ return copyDir(srcPath, destPath);
114
+ }
115
+ return copyFile(srcPath, destPath);
116
+ }),
117
+ );
118
+ };
119
+
120
+ const updateManifestWithVersionInfo = async (dest) => {
121
+ const manifestFile = path.join(dest, 'manifest.json');
122
+ let manifestData = await readFile(manifestFile, 'utf8');
123
+ manifestData = manifestData.replace(/latest\//g, `${getAppVersion()}/`);
124
+ await writeFile(manifestFile, manifestData);
125
+ };
126
+
127
+ exports.copyBuildAssetsToVersionedFolder = async () => {
128
+ const appVersion = getAppVersion();
129
+ const isVersionedApp = isAppLoaderEnabled() && appVersion !== LATEST_VERSION;
130
+ if (!isVersionedApp) return;
131
+ const src = path.resolve(process.cwd(), 'build/public/latest');
132
+ const dest = path.resolve(process.cwd(), `build/public/${appVersion}`);
133
+ await copyDir(src, dest);
134
+ await updateManifestWithVersionInfo(dest);
135
+ };
package/lib/server/csp.js CHANGED
@@ -17,13 +17,13 @@ const sources = [
17
17
  ];
18
18
 
19
19
  const sendFileWithCSPNonce = ({
20
- outputPath,
20
+ buildPath,
21
21
  page = 'index.html',
22
22
  nonceRegex = /__CSP_NONCE__/g,
23
23
  res,
24
24
  fileSystem = fs,
25
25
  }) => {
26
- fileSystem.readFile(path.resolve(outputPath, page), 'utf8', (err, html) => {
26
+ fileSystem.readFile(path.resolve(buildPath, page), 'utf8', (err, html) => {
27
27
  if (err) {
28
28
  res.sendStatus(404);
29
29
  } else {
@@ -1,26 +1,11 @@
1
1
  /* eslint consistent-return:0 import/order:0 */
2
-
3
2
  const express = require('express');
4
- const cors = require('cors');
5
- const { resolve } = require('path');
6
- const expressPinoLogger = require('express-pino-logger');
7
- const { csp } = require('./csp');
8
3
  const logger = require('./logger');
9
- const argv = require('./argv');
10
- const port = require('./port');
11
- const setup = require('./middlewares/frontendMiddleware');
12
- const { loadRoutes } = require('./util');
13
- const { getAssetPath } = require('../webpack/helpers');
14
-
15
- const pino = expressPinoLogger({
16
- transport: {
17
- target: 'pino-pretty',
18
- options: {
19
- colorize: true,
20
- },
21
- },
22
- });
23
- pino.logger.level = 'warn';
4
+ const {
5
+ setupDefaultMiddlewares,
6
+ setupAdditionalMiddlewars,
7
+ } = require('./middlewares');
8
+ const { loadRoutes, port, host } = require('./util');
24
9
 
25
10
  // const corsOptions = {
26
11
  // origin: '*',
@@ -37,33 +22,16 @@ pino.logger.level = 'warn';
37
22
  // maxAge: 3600,
38
23
  // };
39
24
  const app = express();
40
- app.use(pino);
41
- app.use(cors());
42
- app.options('*', cors());
43
- csp(app);
44
- app.use(express.urlencoded({ extended: false }));
45
- app.use(express.text({ type: 'text/plain' }));
46
- app.use(express.json({ type: 'application/json' }));
47
- app.use(express.json({ type: 'application/csp-report' }));
48
-
25
+ setupDefaultMiddlewares(app);
49
26
  // load all custom routes from the application
50
27
  loadRoutes(app);
51
-
52
28
  // In production we need to pass these values in instead of relying on webpack
53
- setup(app, {
54
- outputPath: resolve(process.cwd(), 'build/public'),
55
- publicPath: getAssetPath(),
56
- });
57
-
58
- // get the intended host and port number, use localhost and port 3000 if not provided
59
- const customHost = argv.host || process.env.HOST;
60
- const host = customHost || null; // Let http.Server use its default IPv6/4 host
61
- const prettyHost = customHost || 'localhost';
29
+ setupAdditionalMiddlewars(app);
62
30
 
63
31
  // Start your app.
64
32
  app.listen(port, host, async (err) => {
65
33
  if (err) {
66
34
  return logger.error(err.message);
67
35
  }
68
- logger.appStarted(port, prettyHost);
36
+ logger.appStarted(port, host || 'localhost');
69
37
  });
@@ -1,25 +1,24 @@
1
- const path = require('path');
2
1
  const compression = require('compression');
3
2
  const expressStaticGzip = require('express-static-gzip');
4
3
  const { sendFileWithCSPNonce } = require('../csp');
4
+ const { getPaths } = require('../../webpack/helpers');
5
5
 
6
- module.exports = function addProdMiddlewares(app, options) {
7
- const publicPath = options.publicPath || '/';
8
- const outputPath =
9
- options.outputPath || path.resolve(process.cwd(), 'build/public');
6
+ const paths = getPaths();
10
7
 
8
+ module.exports = function addProdMiddlewares(app, options = {}) {
9
+ const { buildPath = paths.buildPath, basePath = paths.basePath } = options;
11
10
  // compression middleware compresses your server responses which makes them
12
11
  // smaller (applies also to assets). You can read more about that technique
13
12
  // and other good practices on official Express.js docs http://mxs.is/googmy
14
13
  app.use(compression());
15
14
 
16
- app.get(publicPath, (req, res) => {
17
- sendFileWithCSPNonce({ outputPath, res });
15
+ app.get(basePath, (req, res) => {
16
+ sendFileWithCSPNonce({ buildPath, res });
18
17
  });
19
18
 
20
19
  app.use(
21
- publicPath,
22
- expressStaticGzip(outputPath, {
20
+ basePath,
21
+ expressStaticGzip(buildPath, {
23
22
  index: false,
24
23
  enableBrotli: true,
25
24
  orderPreference: ['br'],
@@ -27,5 +26,5 @@ module.exports = function addProdMiddlewares(app, options) {
27
26
  );
28
27
  app.use(expressStaticGzip('cdn'));
29
28
 
30
- app.get('*', (req, res) => sendFileWithCSPNonce({ outputPath, res }));
29
+ app.get('*', (req, res) => sendFileWithCSPNonce({ buildPath, res }));
31
30
  };
@@ -0,0 +1,37 @@
1
+ const express = require('express');
2
+ const cors = require('cors');
3
+ const expressPinoLogger = require('express-pino-logger');
4
+ const { csp } = require('../csp');
5
+ const addProdMiddlewares = require('./addProdMiddlewares');
6
+ const addDevMiddlewares = require('./addDevMiddlewares');
7
+ const webpackConfig = require('../../webpack/webpack.dev.babel');
8
+
9
+ exports.setupDefaultMiddlewares = (app) => {
10
+ const pino = expressPinoLogger({
11
+ transport: {
12
+ target: 'pino-pretty',
13
+ options: {
14
+ colorize: true,
15
+ },
16
+ },
17
+ });
18
+ pino.logger.level = 'warn';
19
+ app.use(pino);
20
+ app.use(cors());
21
+ app.options('*', cors());
22
+ csp(app);
23
+ app.use(express.urlencoded({ extended: false }));
24
+ app.use(express.text({ type: 'text/plain' }));
25
+ app.use(express.json({ type: 'application/json' }));
26
+ app.use(express.json({ type: 'application/csp-report' }));
27
+ };
28
+
29
+ exports.setupAdditionalMiddlewars = (app, options) => {
30
+ const isProd = process.env.NODE_ENV === 'production';
31
+ if (isProd) {
32
+ addProdMiddlewares(app, options);
33
+ } else {
34
+ addDevMiddlewares(app, webpackConfig);
35
+ }
36
+ return app;
37
+ };
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const argv = require('minimist')(process.argv.slice(2));
3
4
 
4
5
  const getCWD = () => process.cwd();
5
6
 
@@ -25,7 +26,7 @@ const getFilesMatching = (filePattern) => {
25
26
  const getServerRouteFiles = getFilesMatching(allJS);
26
27
  const getServiceEndpoints = getFilesMatching(serviceEndpoints);
27
28
 
28
- const loadRoutes = (app) => {
29
+ exports.loadRoutes = (app) => {
29
30
  const routeFiles = getServerRouteFiles(path.join(getCWD(), 'server/routes'));
30
31
  routeFiles.push(...getServiceEndpoints(path.join(getCWD(), 'app')));
31
32
  routeFiles.push(...getServiceEndpoints(path.join(getCWD(), 'lib')));
@@ -41,7 +42,11 @@ const loadRoutes = (app) => {
41
42
  });
42
43
  };
43
44
 
44
- module.exports = {
45
- getCWD,
46
- loadRoutes,
47
- };
45
+ exports.port = parseInt(
46
+ argv.port || process.env.port || process.env.PORT || '3000',
47
+ 10,
48
+ );
49
+
50
+ exports.host = argv.host || process.env.HOST;
51
+
52
+ exports.getCWD = getCWD;
@@ -1,9 +1,11 @@
1
1
  const path = require('path');
2
2
  const normalizePath = require('normalize-path');
3
- const { getAppConfig, getAssetPath } = require('../webpack/helpers');
3
+ const { getAppConfig, getPaths } = require('../webpack/helpers');
4
4
  const swcrcConfig = require('../transpile/swcrc.config.js');
5
5
  const { findMonoRepoRoot } = require('../monorepo/utils');
6
6
 
7
+ const { basePath } = getPaths();
8
+
7
9
  let isReactModule = true;
8
10
  try {
9
11
  /* eslint-disable global-require, import/no-unresolved */
@@ -63,9 +65,10 @@ const jestConfig = {
63
65
  getMockFilePath('image.js'),
64
66
  '.*\\.svg$': getMockFilePath('svg.js'),
65
67
  '.*\\.(html)$': getMockFilePath('html.js'),
68
+ '.*index.html\\?resource$': getMockFilePath('html.js'),
66
69
  '@elliemae/pui-user-monitoring': getMockFilePath('pui-user-monitoring.js'),
67
- '@elliemae/pui-app-loader': getMockFilePath('webpack-hmr.js'),
68
- '@elliemae/pui-diagnostics': getMockFilePath('pui-app-loader.js'),
70
+ '@elliemae/pui-app-loader': getMockFilePath('pui-app-loader.js'),
71
+ '@elliemae/pui-diagnostics': getMockFilePath('pui-diagnostics.js'),
69
72
  'react-spring/web': getNodeModulesPath('react-spring/web.cjs.js'),
70
73
  'react-spring/renderprops': getNodeModulesPath(
71
74
  'react-spring/renderprops.cjs.js',
@@ -88,7 +91,7 @@ const jestConfig = {
88
91
  APP_CONFIG: getAppConfig(),
89
92
  __webpack_public_path__: '/',
90
93
  },
91
- testURL: `http://localhost:3111${getAssetPath()}`,
94
+ testURL: `http://localhost:3111${basePath}`,
92
95
  testEnvironment: 'jsdom',
93
96
  };
94
97
 
@@ -150,9 +150,6 @@ const getENCWLoaderFileName = () => {
150
150
  )[0];
151
151
  };
152
152
 
153
- // base path for index page
154
- const getAssetPath = () => (process.env.ASSET_PATH || '/').replace(/\/?$/, '/');
155
-
156
153
  const getAppVersion = () => {
157
154
  if (!process.env.APP_VERSION) return LATEST_VERSION;
158
155
  const match = process.env.APP_VERSION.match(/^v?(\d+\.\d+)\..*$/);
@@ -161,19 +158,19 @@ const getAppVersion = () => {
161
158
 
162
159
  const getPaths = (latestVersion = true) => {
163
160
  const version = latestVersion ? LATEST_VERSION : getAppVersion();
164
- const publicPath = `${getAssetPath()}${version}/`;
161
+ const publicPath = `${version}/`;
165
162
  const timeStampQuery =
166
163
  process.env.PUI_PIPELINE !== 'true' ? `?timeStamp=${Date.now()}` : '';
167
164
  return {
168
165
  appVersion: version,
169
- buildPath: path.resolve(process.cwd(), `build/public/${version}`),
170
- // base path for all assets
166
+ buildPath: path.resolve(process.cwd(), `build/public/`),
167
+ basePath: (process.env.BASE_PATH || '/').replace(/\/?$/, '/'),
171
168
  publicPath,
172
- userMonScriptPath: `${publicPath}js/${getUserMonitoringFileName()}`,
173
- appLoaderScriptPath: `${publicPath}js/${getAppLoaderFileName()}`,
174
- diagnosticsScriptPath: `${publicPath}js/${getDiagnosticsFileName()}`,
175
- globalScriptPath: `${publicPath}js/global.js${timeStampQuery}`,
176
- encwLoaderScriptPath: `${publicPath}js/${getENCWLoaderFileName()}`,
169
+ userMonScriptPath: `latest/js/${getUserMonitoringFileName()}`,
170
+ appLoaderScriptPath: `latest/js/${getAppLoaderFileName()}`,
171
+ diagnosticsScriptPath: `latest/js/${getDiagnosticsFileName()}`,
172
+ globalScriptPath: `latest/js/global.js${timeStampQuery}`,
173
+ encwLoaderScriptPath: `latest/js/${getENCWLoaderFileName()}`,
177
174
  };
178
175
  };
179
176
 
@@ -227,11 +224,11 @@ const filterByFilePresence = (patterns) =>
227
224
  !noErrorOnMissing || fs.existsSync(path.resolve(process.cwd(), from)),
228
225
  );
229
226
 
227
+ exports.LATEST_VERSION = LATEST_VERSION;
230
228
  exports.excludeNodeModulesExcept = excludeNodeModulesExcept;
231
229
  exports.getLibraryName = getLibraryName;
232
230
  exports.getAppConfig = getAppConfig;
233
231
  exports.mapToFolder = mapToFolder;
234
- exports.getAssetPath = getAssetPath;
235
232
  exports.isApp = isApp;
236
233
  exports.getAlias = getAlias;
237
234
  exports.getAppVersion = getAppVersion;
@@ -13,7 +13,6 @@ const browserslistToEsbuild = require('browserslist-to-esbuild');
13
13
 
14
14
  const {
15
15
  excludeNodeModulesExcept,
16
- getAppConfig,
17
16
  modulesToTranspile,
18
17
  getAlias,
19
18
  getPaths,
@@ -29,18 +28,13 @@ const finalCSSLoader = (mode) =>
29
28
  mode !== 'production' ? { loader: 'style-loader' } : minicssLoader;
30
29
 
31
30
  const postcssPlugins = [PostcssPresetEnv({ autoprefixer: { grid: true } })];
32
- const { buildPath, publicPath } = getPaths();
31
+ const { buildPath } = getPaths();
33
32
 
34
33
  const plugins = [
35
34
  new webpack.EnvironmentPlugin({
36
35
  NODE_ENV: 'development',
37
- ASSET_PATH: '/',
38
- PUBLIC_PATH: publicPath,
39
36
  CI: 'false',
40
37
  }),
41
- new webpack.DefinePlugin({
42
- APP_CONFIG: getAppConfig(),
43
- }),
44
38
  new ProvidePlugin({
45
39
  React: 'react',
46
40
  }),
@@ -48,46 +42,47 @@ const plugins = [
48
42
  patterns: filterByFilePresence([
49
43
  {
50
44
  from: 'app/app.config.json',
51
- to: 'app.config.json',
45
+ to: './latest/app.config.json',
52
46
  },
53
47
  {
54
48
  from: 'app/robots.txt',
55
- to: '../robots.txt',
49
+ to: 'robots.txt',
56
50
  noErrorOnMissing: true,
57
51
  },
58
52
  {
59
53
  from: 'app/global*.js',
60
- to: 'js/[name][ext]',
54
+ to: './latest/js/[name][ext]',
61
55
  },
62
56
  {
63
57
  from: 'node_modules/@elliemae/pui-user-monitoring/dist/public/js',
64
- to: 'js',
58
+ to: './latest/js',
65
59
  toType: 'dir',
66
60
  info: { minimized: true },
67
61
  },
68
62
  {
69
63
  from: 'node_modules/@elliemae/pui-app-loader/dist/public/js',
70
- to: 'js',
64
+ to: './latest/js',
71
65
  toType: 'dir',
72
66
  noErrorOnMissing: true,
73
67
  info: { minimized: true },
74
68
  },
75
69
  {
76
70
  from: 'node_modules/@elliemae/encw-loader/dist/public/js',
77
- to: 'js',
71
+ to: './latest/js',
78
72
  toType: 'dir',
79
73
  noErrorOnMissing: true,
80
74
  info: { minimized: true },
81
75
  },
82
76
  {
83
77
  from: 'node_modules/@elliemae/pui-diagnostics/dist/public/js',
84
- to: 'js',
78
+ to: './latest/js',
85
79
  toType: 'dir',
86
80
  noErrorOnMissing: true,
87
81
  info: { minimized: true },
88
82
  },
89
83
  {
90
84
  from: 'public',
85
+ to: './latest',
91
86
  noErrorOnMissing: true,
92
87
  globOptions: {
93
88
  ignore: ['readme.md'],
@@ -95,7 +90,6 @@ const plugins = [
95
90
  },
96
91
  {
97
92
  from: 'webroot',
98
- to: '../',
99
93
  noErrorOnMissing: true,
100
94
  globOptions: {
101
95
  ignore: ['readme.md'],
@@ -105,8 +99,16 @@ const plugins = [
105
99
  }),
106
100
  new DuplicatePackageCheckerPlugin(),
107
101
  new MomentLocalesPlugin({ localesToKeep: ['es-us'] }),
108
- new WebpackManifestPlugin(),
102
+ new WebpackManifestPlugin({
103
+ fileName: './latest/manifest.json',
104
+ publicPath: '',
105
+ map: (file) => {
106
+ file.name = file.name.replace(/^latest\//, '');
107
+ return file;
108
+ },
109
+ }),
109
110
  new FaviconsWebpackPlugin({
111
+ outputPath: './latest/assets',
110
112
  logo: './app/view/images/favicon.png',
111
113
  favicons: {
112
114
  developerName: 'ICE MT',
@@ -126,7 +128,7 @@ module.exports = (options) => ({
126
128
  output: {
127
129
  clean: true,
128
130
  path: buildPath,
129
- publicPath,
131
+ publicPath: 'auto',
130
132
  ...options.output,
131
133
  }, // Merge with env dependent settings
132
134
  optimization: options.optimization,
@@ -236,4 +238,5 @@ module.exports = (options) => ({
236
238
  },
237
239
  devtool: options.devtool || 'eval-source-map',
238
240
  performance: options.performance || {},
241
+ devServer: options.devServer || {},
239
242
  });
@@ -1,15 +1,17 @@
1
+ /* eslint-disable max-lines */
1
2
  const path = require('path');
2
- const { HotModuleReplacementPlugin } = require('webpack');
3
3
  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
7
  const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
8
+ const expressStaticGzip = require('express-static-gzip');
9
+ const { setupDefaultMiddlewares } = require('../server/middlewares');
10
+ const { loadRoutes } = require('../server/util');
8
11
 
9
12
  const smp = new SpeedMeasurePlugin({ disable: !process.env.MEASURE });
10
13
 
11
14
  const {
12
- getAssetPath,
13
15
  isAppLoaderEnabled,
14
16
  getPaths,
15
17
  isGoogleTagManagerEnabled,
@@ -18,7 +20,8 @@ const baseConfigFactory = require('./webpack.base.babel');
18
20
 
19
21
  const {
20
22
  appVersion,
21
- publicPath,
23
+ buildPath,
24
+ basePath,
22
25
  userMonScriptPath,
23
26
  globalScriptPath,
24
27
  appLoaderScriptPath,
@@ -39,14 +42,13 @@ const devConfig = {
39
42
 
40
43
  // Add hot reloading in development
41
44
  entry: {
42
- app: [
43
- 'webpack-hot-middleware/client',
44
- path.join(process.cwd(), 'app/index'),
45
- ],
45
+ app: path.join(process.cwd(), 'app/index'),
46
46
  },
47
47
 
48
48
  // Don't use hashes in dev mode for better performance
49
49
  output: {
50
+ path: buildPath,
51
+ publicPath: 'auto',
50
52
  filename: '[name].js',
51
53
  chunkFilename: '[name].chunk.js',
52
54
  assetModuleFilename: '[name][ext][query]',
@@ -82,8 +84,6 @@ const devConfig = {
82
84
  : 'app/index-app-loader.html',
83
85
  emui: {
84
86
  appVersion,
85
- assetPath: publicPath,
86
- basePath: getAssetPath(),
87
87
  globalScriptPath,
88
88
  userMonScriptPath,
89
89
  appLoaderScriptPath,
@@ -107,11 +107,32 @@ const devConfig = {
107
107
  performance: {
108
108
  hints: false,
109
109
  },
110
+
111
+ devServer: {
112
+ client: {
113
+ overlay: {
114
+ errors: true,
115
+ warnings: false,
116
+ },
117
+ },
118
+ devMiddleware: {
119
+ publicPath: basePath,
120
+ },
121
+ historyApiFallback: true,
122
+ hot: true,
123
+ open: [basePath],
124
+ port: 3000,
125
+ setupMiddlewares: (middlewares, devServer) => {
126
+ setupDefaultMiddlewares(devServer.app);
127
+ devServer.app.use(expressStaticGzip('cdn'));
128
+ loadRoutes(devServer.app);
129
+ return middlewares;
130
+ },
131
+ },
110
132
  };
111
133
 
112
134
  const config = smp.wrap(baseConfigFactory(devConfig));
113
135
  config.plugins = config.plugins.concat([
114
- new HotModuleReplacementPlugin(),
115
136
  new ReactRefreshWebpackPlugin({
116
137
  overlay: {
117
138
  sockIntegration: 'whm',
@@ -10,17 +10,14 @@ const browserslistToEsbuild = require('browserslist-to-esbuild');
10
10
 
11
11
  const baseConfigFactory = require('./webpack.base.babel');
12
12
  const {
13
- getAssetPath,
14
13
  isAppLoaderEnabled,
15
- LATEST_VERSION,
16
14
  getPaths,
17
- getAppVersion,
18
15
  isGoogleTagManagerEnabled,
19
16
  getCompressionPlugins,
20
17
  } = require('./helpers');
21
18
 
22
19
  const getProdConfig = ({ latestVersion = true } = {}) => {
23
- const { buildPath, publicPath } = getPaths(latestVersion);
20
+ const { buildPath } = getPaths(latestVersion);
24
21
 
25
22
  return {
26
23
  mode: 'production',
@@ -32,10 +29,10 @@ const getProdConfig = ({ latestVersion = true } = {}) => {
32
29
  // Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
33
30
  output: {
34
31
  path: buildPath,
35
- publicPath,
36
- filename: 'js/[name].[contenthash].js',
37
- chunkFilename: 'js/[name].[contenthash].chunk.js',
38
- assetModuleFilename: 'assets/[name].[hash][ext][query]',
32
+ publicPath: 'auto',
33
+ filename: 'latest/js/[name].[contenthash].js',
34
+ chunkFilename: 'latest/js/[name].[contenthash].chunk.js',
35
+ assetModuleFilename: 'latest/assets/[name].[hash][ext][query]',
39
36
  },
40
37
 
41
38
  optimization: {
@@ -64,11 +61,6 @@ const getProdConfig = ({ latestVersion = true } = {}) => {
64
61
  },
65
62
 
66
63
  plugins: [
67
- // new MiniCssExtractPlugin({
68
- // filename: 'css/[name].[contenthash].css',
69
- // chunkFilename: 'css/[name].[contenthash].chunk.css',
70
- // }),
71
-
72
64
  ...getCompressionPlugins(),
73
65
 
74
66
  new BundleAnalyzerPlugin({
@@ -78,7 +70,7 @@ const getProdConfig = ({ latestVersion = true } = {}) => {
78
70
  }),
79
71
 
80
72
  new GenerateSW({
81
- swDest: '../sw.js',
73
+ swDest: 'sw.js',
82
74
  clientsClaim: true,
83
75
  skipWaiting: true,
84
76
  }),
@@ -94,15 +86,14 @@ const getProdConfig = ({ latestVersion = true } = {}) => {
94
86
  };
95
87
 
96
88
  const {
97
- publicPath,
98
89
  userMonScriptPath,
99
90
  globalScriptPath,
100
91
  appLoaderScriptPath,
101
92
  diagnosticsScriptPath,
102
93
  encwLoaderScriptPath,
94
+ basePath,
103
95
  } = getPaths();
104
96
  const htmlWebpackPlugin = new HtmlWebpackPlugin({
105
- filename: '../index.html',
106
97
  inject: !isAppLoaderEnabled(),
107
98
  template: !isAppLoaderEnabled()
108
99
  ? 'app/index.html'
@@ -121,8 +112,7 @@ const htmlWebpackPlugin = new HtmlWebpackPlugin({
121
112
  },
122
113
  emui: {
123
114
  appVersion: 'latest',
124
- assetPath: publicPath,
125
- basePath: getAssetPath(),
115
+ basePath,
126
116
  globalScriptPath,
127
117
  userMonScriptPath,
128
118
  appLoaderScriptPath,
@@ -132,33 +122,21 @@ const htmlWebpackPlugin = new HtmlWebpackPlugin({
132
122
  },
133
123
  });
134
124
 
135
- // user want to version the web app to support backward compatible releases
136
- const isVersionedApp =
137
- isAppLoaderEnabled() && getAppVersion() !== LATEST_VERSION;
138
-
139
- const latestVersionConfig = baseConfigFactory(getProdConfig());
140
- latestVersionConfig.plugins.push(htmlWebpackPlugin);
125
+ const config = baseConfigFactory(getProdConfig());
126
+ config.plugins.push(htmlWebpackPlugin);
141
127
 
142
- const appVersionConfig = baseConfigFactory(
143
- getProdConfig({ latestVersion: false }),
144
- );
145
-
146
- const addSMPPlugin = (config) => {
128
+ const addSMPPlugin = (webpackConfig) => {
147
129
  const smpConfig = new SpeedMeasurePlugin({
148
130
  disable: !process.env.MEASURE,
149
- }).wrap(config);
131
+ }).wrap(webpackConfig);
150
132
  // mini css extract plugin is not working fine with smp
151
133
  smpConfig.plugins.push(
152
134
  new MiniCssExtractPlugin({
153
- filename: 'css/[name].[contenthash].css',
154
- chunkFilename: 'css/[name].[contenthash].chunk.css',
135
+ filename: 'latest/css/[name].[contenthash].css',
136
+ chunkFilename: 'latest/css/[name].[contenthash].chunk.css',
155
137
  }),
156
138
  );
157
139
  return smpConfig;
158
140
  };
159
141
 
160
- const config = isVersionedApp
161
- ? [latestVersionConfig, appVersionConfig].map(addSMPPlugin)
162
- : addSMPPlugin(latestVersionConfig);
163
-
164
- module.exports = config;
142
+ module.exports = addSMPPlugin(config);
@@ -1,21 +1,13 @@
1
- const { DefinePlugin, EnvironmentPlugin } = require('webpack');
1
+ const { EnvironmentPlugin } = require('webpack');
2
2
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
3
  const CopyWebpackPlugin = require('copy-webpack-plugin');
4
4
  const ResolveTypeScriptPlugin = require('resolve-typescript-plugin');
5
- const {
6
- getAppConfig,
7
- isApp,
8
- getAlias,
9
- getCompressionPlugins,
10
- } = require('./helpers');
5
+ const { isApp, getAlias, getCompressionPlugins } = require('./helpers');
11
6
 
12
7
  const IS_APP = isApp();
13
8
  const CWD = process.cwd();
14
9
 
15
10
  const getAdditionalPlugins = () => [
16
- new DefinePlugin({
17
- APP_CONFIG: getAppConfig(),
18
- }),
19
11
  new EnvironmentPlugin({
20
12
  IS_APP,
21
13
  CWD,
@@ -55,6 +47,10 @@ const getModuleRules = () => [
55
47
  resourceQuery: /^((?!url).)*$/,
56
48
  use: ['@svgr/webpack'],
57
49
  },
50
+ {
51
+ resourceQuery: /resource/,
52
+ type: 'asset/resource',
53
+ },
58
54
  ];
59
55
 
60
56
  exports.webpackFinal = async (config, { configType }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/pui-cli",
3
- "version": "6.16.0",
3
+ "version": "7.0.0-beta.11",
4
4
  "private": false,
5
5
  "description": "ICE MT UI Platform CLI",
6
6
  "sideEffects": false,
@@ -47,10 +47,10 @@
47
47
  "indent": 4
48
48
  },
49
49
  "dependencies": {
50
- "@babel/cli": "~7.17.6",
51
- "@babel/core": "~7.17.9",
50
+ "@babel/cli": "~7.17.10",
51
+ "@babel/core": "~7.17.10",
52
52
  "@babel/eslint-parser": "~7.17.0",
53
- "@babel/node": "~7.16.8",
53
+ "@babel/node": "~7.17.10",
54
54
  "@babel/plugin-proposal-class-properties": "~7.16.7",
55
55
  "@babel/plugin-proposal-export-default-from": "~7.16.7",
56
56
  "@babel/plugin-syntax-dynamic-import": "~7.8.3",
@@ -58,8 +58,8 @@
58
58
  "@babel/plugin-transform-react-constant-elements": "~7.17.6",
59
59
  "@babel/plugin-transform-react-inline-elements": "~7.16.7",
60
60
  "@babel/plugin-transform-react-jsx-source": "~7.16.7",
61
- "@babel/plugin-transform-runtime": "~7.17.0",
62
- "@babel/preset-env": "~7.16.11",
61
+ "@babel/plugin-transform-runtime": "~7.17.10",
62
+ "@babel/preset-env": "~7.17.10",
63
63
  "@babel/preset-react": "~7.16.7",
64
64
  "@babel/preset-typescript": "~7.16.7",
65
65
  "@babel/runtime": "~7.17.9",
@@ -67,10 +67,10 @@
67
67
  "@commitlint/config-conventional": "~16.2.4",
68
68
  "@elliemae/browserslist-config-elliemae-latest-browsers": "~1.4.2",
69
69
  "@faker-js/faker": "6.2.0",
70
- "@nrwl/cli": "13.10.3",
71
- "@nrwl/tao": "13.10.3",
72
- "@nrwl/workspace": "13.10.3",
73
- "@pmmmwh/react-refresh-webpack-plugin": "~0.5.4",
70
+ "@nrwl/cli": "14.0.5",
71
+ "@nrwl/tao": "14.0.5",
72
+ "@nrwl/workspace": "14.0.5",
73
+ "@pmmmwh/react-refresh-webpack-plugin": "~0.5.5",
74
74
  "@semantic-release/changelog": "~6.0.1",
75
75
  "@semantic-release/exec": "~6.0.3",
76
76
  "@semantic-release/git": "~10.0.1",
@@ -80,7 +80,7 @@
80
80
  "@storybook/addon-interactions": "~6.4.22",
81
81
  "@storybook/addon-links": "~6.4.22",
82
82
  "@storybook/addon-storysource": "~6.4.22",
83
- "@storybook/builder-vite": "~0.1.30",
83
+ "@storybook/builder-vite": "~0.1.32",
84
84
  "@storybook/builder-webpack5": "~6.4.22",
85
85
  "@storybook/manager-webpack5": "~6.4.22",
86
86
  "@storybook/react": "~6.4.22",
@@ -91,10 +91,10 @@
91
91
  "@swc/core": "~1.2.173",
92
92
  "@swc/jest": "~0.2.20",
93
93
  "@testing-library/jest-dom": "~5.16.4",
94
- "@testing-library/react": "~12.1.4",
95
- "@testing-library/react-hooks": "~7.0.2",
94
+ "@testing-library/react": "~13.1.1",
95
+ "@testing-library/react-hooks": "~8.0.0",
96
96
  "@types/jest": "~27.4.1",
97
- "@types/node": "~17.0.29",
97
+ "@types/node": "~17.0.30",
98
98
  "@types/rimraf": "~3.0.2",
99
99
  "@types/testing-library__jest-dom": "~5.14.3",
100
100
  "@typescript-eslint/eslint-plugin": "~5.21.0",
@@ -159,14 +159,14 @@
159
159
  "eslint-plugin-testing-library": "~5.3.1",
160
160
  "eslint-plugin-wdio": "~7.19.4",
161
161
  "execa": "~5.1.1",
162
- "express": "~4.18.0",
162
+ "express": "~4.18.1",
163
163
  "express-pino-logger": "~7.0.0",
164
164
  "express-static-gzip": "~2.1.5",
165
165
  "favicons": "~6.2.2",
166
166
  "favicons-webpack-plugin": "~5.0.2",
167
167
  "fast-glob": "~3.2.11",
168
168
  "find-up": "~5.0.0",
169
- "happy-dom": "~2.55.0",
169
+ "happy-dom": "~3.1.0",
170
170
  "helmet-csp": "~3.4.0",
171
171
  "html-webpack-plugin": "~5.5.0",
172
172
  "http-server": "~14.1.0",
@@ -175,7 +175,7 @@
175
175
  "imports-loader": "~3.1.1",
176
176
  "ip": "~1.1.5",
177
177
  "jest-axe": "~6.0.0",
178
- "jest-cli": "~27.5.1",
178
+ "jest-cli": "~28.0.3",
179
179
  "jest-sonar-reporter": "~2.0.0",
180
180
  "jest-styled-components": "~7.0.8",
181
181
  "jscodeshift": "~0.13.1",
@@ -189,7 +189,7 @@
189
189
  "msw": "~0.39.2",
190
190
  "node-gyp": "~9.0.0",
191
191
  "node-plop": "~0.31.0",
192
- "nodemon": "~2.0.15",
192
+ "nodemon": "~2.0.16",
193
193
  "normalize-path": "~3.0.0",
194
194
  "npm-check-updates": "12.5.10",
195
195
  "null-loader": "~4.0.1",
@@ -210,7 +210,7 @@
210
210
  "raf": "~3.4.1",
211
211
  "react-axe": "~3.5.4",
212
212
  "react-docgen": "~5.4.0",
213
- "react-refresh": "~0.11.0",
213
+ "react-refresh": "~0.13.0",
214
214
  "react-test-renderer": "~18.1.0",
215
215
  "resize-observer-polyfill": "~1.5.1",
216
216
  "resolve-typescript-plugin": "~1.2.0",
@@ -219,16 +219,17 @@
219
219
  "slackify-markdown": "~4.3.1",
220
220
  "speed-measure-webpack-plugin": "~1.5.0",
221
221
  "storybook-addon-turbo-build": "~1.1.0",
222
+ "storybook-builder-vite": "~0.1.23",
222
223
  "storybook-react-router": "~1.0.8",
223
224
  "style-loader": "~3.3.1",
224
- "stylelint": "~14.8.0",
225
+ "stylelint": "~14.8.1",
225
226
  "stylelint-config-recommended": "~7.0.0",
226
227
  "stylelint-config-styled-components": "~0.1.1",
227
228
  "swc-loader": "~0.2.0",
228
229
  "terser-webpack-plugin": "~5.3.1",
229
230
  "ts-node": "~10.7.0",
230
231
  "tsc-alias": "~1.6.7",
231
- "typescript": "~4.6.3",
232
+ "typescript": "~4.6.4",
232
233
  "update-notifier": "~5.1.0",
233
234
  "url-loader": "~4.1.1",
234
235
  "uuid": "~8.3.2",
@@ -238,6 +239,7 @@
238
239
  "webpack-bundle-analyzer": "~4.5.0",
239
240
  "webpack-cli": "~4.9.2",
240
241
  "webpack-dev-middleware": "~5.3.1",
242
+ "webpack-dev-server": "~4.8.1",
241
243
  "webpack-hot-middleware": "~2.25.1",
242
244
  "webpack-manifest-plugin": "~5.0.0",
243
245
  "webpack-merge": "~5.8.0",
@@ -246,8 +248,8 @@
246
248
  "yargs": "~17.4.1"
247
249
  },
248
250
  "devDependencies": {
249
- "react": "~17.0.2",
250
- "react-dom": "~17.0.2",
251
+ "react": "~18.1.0",
252
+ "react-dom": "~18.1.0",
251
253
  "redux": "~4.2.0",
252
254
  "redux-saga": "~1.1.3",
253
255
  "styled-components": "~5.3.5"
@@ -1 +0,0 @@
1
- module.exports = require('minimist')(process.argv.slice(2));
@@ -1,16 +0,0 @@
1
- /* eslint-disable global-require */
2
-
3
- module.exports = (app, options) => {
4
- const isProd = process.env.NODE_ENV === 'production';
5
-
6
- if (isProd) {
7
- const addProdMiddlewares = require('./addProdMiddlewares');
8
- addProdMiddlewares(app, options);
9
- } else {
10
- const webpackConfig = require('../../webpack/webpack.dev.babel');
11
- const addDevMiddlewares = require('./addDevMiddlewares');
12
- addDevMiddlewares(app, webpackConfig);
13
- }
14
-
15
- return app;
16
- };
@@ -1,6 +0,0 @@
1
- const argv = require('./argv');
2
-
3
- module.exports = parseInt(
4
- argv.port || process.env.port || process.env.PORT || '3000',
5
- 10,
6
- );