@autobest-ui/scripts 0.1.0 → 1.0.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.
@@ -12,9 +12,9 @@ function formatMessage(message) {
12
12
  } else if ('message' in message) {
13
13
  lines = message.message.split('\n');
14
14
  } else if (Array.isArray(message)) {
15
- message.forEach(message => {
16
- if ('message' in message) {
17
- lines = message.message.split('\n');
15
+ message.forEach(child => {
16
+ if ('message' in child) {
17
+ lines = child.message.split('\n');
18
18
  }
19
19
  });
20
20
  }
@@ -31,10 +31,7 @@ function formatMessage(message) {
31
31
  });
32
32
 
33
33
  message = lines.join('\n');
34
- message = message.replace(
35
- /SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
36
- `${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
37
- );
34
+ message = message.replace(/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g, `${friendlySyntaxErrorLabel} $3 ($1:$2)\n`);
38
35
 
39
36
  message = message.replace(
40
37
  /^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
@@ -58,9 +55,7 @@ function formatMessage(message) {
58
55
  if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
59
56
  lines = [
60
57
  lines[0],
61
- lines[1]
62
- .replace('Error: ', '')
63
- .replace('Module not found: Cannot find file:', 'Cannot find file:')
58
+ lines[1].replace('Error: ', '').replace('Module not found: Cannot find file:', 'Cannot find file:')
64
59
  ];
65
60
  }
66
61
 
@@ -1,14 +1,8 @@
1
1
  const loaderUtils = require('loader-utils');
2
2
 
3
3
  module.exports = function getLocalIdent(context, localIdentName, localName, options) {
4
- const fileNameOrFolder = context.resourcePath.match(/index\.module\.(css|scss|sass)$/)
5
- ? '[folder]'
6
- : '[name]';
4
+ const fileNameOrFolder = context.resourcePath.match(/index\.module\.(css|scss|sass)$/) ? '[folder]' : '[name]';
7
5
  const hash = loaderUtils.getHashDigest(context.resourcePath + localName, 'md5', 'base64', 5);
8
- const className = loaderUtils.interpolateName(
9
- context,
10
- `${fileNameOrFolder}_${localName}_${hash}`,
11
- options
12
- );
6
+ const className = loaderUtils.interpolateName(context, `${fileNameOrFolder}_${localName}_${hash}`, options);
13
7
  return className.replace('.module_', '_');
14
8
  };
package/common/start.js CHANGED
@@ -1,4 +1,4 @@
1
- const webpackDevServer = require('webpack-dev-server');
1
+ const WebpackDevServer = require('webpack-dev-server');
2
2
  const webpack = require('webpack');
3
3
  const open = require('open');
4
4
  const appConfig = require('./appConfig');
@@ -15,36 +15,38 @@ function openStartRun(webpackFactory) {
15
15
  const extendEnv = getEnvironmentInfo();
16
16
 
17
17
  const options = {
18
- contentBase: getProjectPath(appConfig.startOutput.path),
18
+ allowedHosts: 'all',
19
19
  hot: true,
20
20
  host: HOST,
21
- quiet: true,
22
- publicPath: appConfig.startOutput.publicPath || '/',
21
+ port: PORT,
23
22
  compress: true,
24
- overlay: false,
25
23
  historyApiFallback: {
26
24
  // https://github.com/facebook/create-react-app/issues/387.
27
25
  disableDotRule: true
28
26
  },
29
- watchOptions: {
30
- aggregateTimeout: 300,
31
- poll: 1000,
32
- ignored: /node_modules/
27
+ client: {
28
+ overlay: false,
29
+ progress: false
33
30
  },
34
- disableHostCheck: true
31
+ static: {
32
+ directory: getProjectPath(appConfig.startOutput.path),
33
+ publicPath: appConfig.startOutput.publicPath || '/',
34
+ watch: {
35
+ aggregateTimeout: 300,
36
+ poll: 1000,
37
+ ignored: /node_modules/
38
+ }
39
+ }
35
40
  };
36
41
 
37
42
  const startOpenPath = appConfig.startOpenPath ? appConfig.startOpenPath : '';
38
43
 
39
44
  try {
40
45
  const config = webpackFactory({ ...appConfig, port: PORT, startOpenPath }, extendEnv);
41
-
42
- webpackDevServer.addDevServerEntrypoints(config, options);
43
46
  const compiler = webpack(config);
44
- // eslint-disable-next-line new-cap
45
- const server = new webpackDevServer(compiler, options);
47
+ const server = new WebpackDevServer(options, compiler);
46
48
 
47
- server.listen(PORT, HOST, err => {
49
+ server.startCallback(err => {
48
50
  if (err) {
49
51
  // eslint-disable-next-line no-console
50
52
  console.log(err);
@@ -52,7 +54,6 @@ function openStartRun(webpackFactory) {
52
54
  }
53
55
  open(`http://localhost:${PORT}${startOpenPath}`);
54
56
  });
55
-
56
57
  ['SIGINT', 'SIGTERM'].forEach(sig => {
57
58
  process.on(sig, () => {
58
59
  server.close();
package/common/utils.js CHANGED
@@ -34,25 +34,25 @@ function getParseArgsToJson() {
34
34
  return result;
35
35
  }
36
36
 
37
- function isExistsSyncFile(path) {
38
- return fs.existsSync(path);
37
+ function isExistsSyncFile(currentPath) {
38
+ return fs.existsSync(currentPath);
39
39
  }
40
40
 
41
41
  const parseArgsToJson = getParseArgsToJson();
42
42
 
43
- function deleteFolders(path) {
43
+ function deleteFolders(currentPath) {
44
44
  let files = [];
45
- if (isExistsSyncFile(path)) {
46
- files = fs.readdirSync(path);
45
+ if (isExistsSyncFile(currentPath)) {
46
+ files = fs.readdirSync(currentPath);
47
47
  files.forEach(file => {
48
- const curPath = `${path}/${file}`;
48
+ const curPath = `${currentPath}/${file}`;
49
49
  if (fs.statSync(curPath).isDirectory()) {
50
50
  deleteFolders(curPath);
51
51
  } else {
52
52
  fs.unlinkSync(curPath);
53
53
  }
54
54
  });
55
- fs.rmdirSync(path);
55
+ fs.rmdirSync(currentPath);
56
56
  }
57
57
  }
58
58
 
@@ -1,64 +1,76 @@
1
1
  const webpack = require('webpack');
2
2
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
- const HappyPack = require('happypack');
4
3
  const ESLintPlugin = require('eslint-webpack-plugin');
5
4
  const ProgressBarPlugin = require('progress-bar-webpack-plugin');
6
5
  const getCSSModuleLocalIdent = require('./getCSSModuleLocalIdent');
7
6
  const { getProjectPath, isExistsSyncFile } = require('./utils');
8
-
9
7
  const appWebpackConfigPath = getProjectPath('/config/app.webpack.js');
10
8
 
11
- const happyThreadPool = HappyPack.ThreadPool({ size: 5 });
12
9
  const sassRegex = /\.(scss|sass)$/;
13
10
  const sassModuleRegex = /\.module\.(scss|sass)$/;
11
+ const imageResolvingRegex = /\.resolving\.(png|jpg|jepg|gif)$/;
14
12
 
15
13
  function getStyleLoaders({ isProd, isServer, isHotServer, isSass, moduleOption = {} }) {
16
14
  const result = [
17
15
  {
18
- loader: 'css-loader',
16
+ loader: require.resolve('css-loader'),
19
17
  options: {
20
- importLoaders: 1,
21
- ...moduleOption
18
+ ...moduleOption,
19
+ url: {
20
+ // background image只解析以".resolving."结尾的静态资源, 例如:'img.resolving.png'
21
+ filter: url => imageResolvingRegex.test(url)
22
+ }
22
23
  }
23
24
  },
24
25
  {
25
- loader: 'postcss-loader',
26
+ loader: require.resolve('postcss-loader'),
26
27
  options: {
27
- ident: 'postcss',
28
- plugins: () => [
29
- require('postcss-flexbugs-fixes'),
30
- require('postcss-preset-env')({
31
- autoprefixer: {
32
- flexbox: 'no-2009',
33
- remove: false,
34
- grid: true
35
- },
36
- stage: 3
37
- })
38
- ],
28
+ postcssOptions: {
29
+ ident: 'postcss',
30
+ config: false,
31
+ plugins: [
32
+ 'postcss-flexbugs-fixes',
33
+ [
34
+ 'postcss-preset-env',
35
+ {
36
+ autoprefixer: {
37
+ flexbox: 'no-2009'
38
+ },
39
+ stage: 3
40
+ }
41
+ ],
42
+ 'postcss-normalize'
43
+ ]
44
+ },
39
45
  sourceMap: false
40
46
  }
41
47
  }
42
48
  ];
43
49
 
44
50
  if (isSass) {
45
- result.push({
46
- loader: 'sass-loader'
47
- });
51
+ result.push(
52
+ {
53
+ loader: require.resolve('resolve-url-loader')
54
+ },
55
+ {
56
+ loader: require.resolve('sass-loader'),
57
+ options: {
58
+ // 增加环境变量,供sass使用
59
+ additionalData: `$env: ${process.env.NODE_ENV};`
60
+ }
61
+ }
62
+ );
48
63
  }
49
64
 
50
65
  if ((isProd || isHotServer) && !isServer) {
51
66
  result.unshift({
52
- loader: MiniCssExtractPlugin.loader,
53
- options: {
54
- hmr: false
55
- }
67
+ loader: MiniCssExtractPlugin.loader
56
68
  });
57
69
  }
58
70
 
59
71
  if (!isProd && !isHotServer) {
60
72
  result.unshift({
61
- loader: 'style-loader'
73
+ loader: require.resolve('style-loader')
62
74
  });
63
75
  }
64
76
 
@@ -67,6 +79,7 @@ function getStyleLoaders({ isProd, isServer, isHotServer, isSass, moduleOption =
67
79
 
68
80
  module.exports = (appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCommonAlias }) => {
69
81
  const result = {
82
+ stats: 'errors-only',
70
83
  // 原始源代码(仅限行)定位到原始代码问题,比source-map 快,但是没有列映射(column mapping)的 source-map
71
84
  devtool: isProd ? 'source-map' : 'cheap-module-source-map',
72
85
  // 会将 process.env.NODE_ENV 的值设为 development, 告知 webpack 使用相应模式的内置优化
@@ -82,10 +95,59 @@ module.exports = (appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCo
82
95
  rules: [
83
96
  {
84
97
  oneOf: [
98
+ {
99
+ test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
100
+ type: 'asset'
101
+ },
85
102
  {
86
103
  test: /\.(js|ts|tsx)$/,
87
104
  exclude: /node_modules/,
88
- use: 'happypack/loader?id=jsbabel'
105
+ use: {
106
+ loader: require.resolve('babel-loader'),
107
+ options: {
108
+ cacheDirectory: true,
109
+ presets: [
110
+ [
111
+ require('@babel/preset-env').default,
112
+ {
113
+ useBuiltIns: 'entry',
114
+ corejs: 3,
115
+ exclude: ['transform-typeof-symbol']
116
+ }
117
+ ],
118
+ require('@babel/preset-react').default,
119
+ require('@babel/preset-typescript').default
120
+ ],
121
+ plugins: [
122
+ require('@loadable/babel-plugin').default,
123
+ require('@babel/plugin-transform-runtime').default,
124
+ [require('@babel/plugin-proposal-decorators').default, { legacy: true }],
125
+
126
+ [
127
+ require('@babel/plugin-proposal-class-properties').default,
128
+ {
129
+ loose: true
130
+ }
131
+ ],
132
+ [
133
+ require('@babel/plugin-proposal-private-methods').default,
134
+ {
135
+ loose: true
136
+ }
137
+ ],
138
+ [
139
+ require('@babel/plugin-proposal-private-property-in-object').default,
140
+ {
141
+ loose: true
142
+ }
143
+ ],
144
+ // 支持 "??"
145
+ require('@babel/plugin-proposal-nullish-coalescing-operator').default,
146
+ // 支持"?."
147
+ require('@babel/plugin-proposal-optional-chaining').default
148
+ ]
149
+ }
150
+ }
89
151
  },
90
152
  {
91
153
  test: sassRegex,
@@ -104,10 +166,13 @@ module.exports = (appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCo
104
166
  isServer,
105
167
  isHotServer,
106
168
  isSass: true,
107
- moduleOption: {
108
- getLocalIdent: getCSSModuleLocalIdent,
109
- importLoaders: 2,
110
- modules: true
169
+ modulesOptions: {
170
+ importLoaders: 3,
171
+ sourceMap: false,
172
+ modules: {
173
+ mode: 'local',
174
+ getLocalIdent: getCSSModuleLocalIdent
175
+ }
111
176
  }
112
177
  })
113
178
  },
@@ -118,14 +183,6 @@ module.exports = (appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCo
118
183
  isServer,
119
184
  isHotServer
120
185
  })
121
- },
122
- {
123
- test: [/\.jpe?g$/, /\.png$/, /\.bmp$/, /\.gif$/],
124
- loader: 'url-loader',
125
- options: {
126
- limit: 2048,
127
- name: `static/[name].[contenthash:8].[ext]?v=${extendEnv.version}`
128
- }
129
186
  }
130
187
  ]
131
188
  }
@@ -143,52 +200,17 @@ module.exports = (appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCo
143
200
  failOnError: false,
144
201
  extensions: ['ts', 'tsx', 'js']
145
202
  }),
146
- new HappyPack({
147
- id: 'jsbabel',
148
- verbose: false,
149
- threadPool: happyThreadPool,
150
- loaders: [
151
- {
152
- loader: 'babel-loader',
153
- options: {
154
- cacheDirectory: true,
155
- presets: [
156
- 'react-app',
157
- '@babel/preset-env',
158
- '@babel/preset-react',
159
- '@babel/typescript'
160
- ],
161
- plugins: [
162
- '@loadable/babel-plugin',
163
- '@babel/plugin-transform-object-assign',
164
- '@babel/plugin-transform-shorthand-properties',
165
- '@babel/plugin-transform-runtime',
166
- [
167
- '@babel/plugin-proposal-decorators',
168
- {
169
- legacy: true
170
- }
171
- ],
172
- [
173
- '@babel/plugin-proposal-class-properties',
174
- {
175
- loose: false
176
- }
177
- ]
178
- ]
179
- }
180
- }
181
- ]
182
- }),
183
203
  new ProgressBarPlugin({
184
204
  // eslint-disable-next-line no-useless-concat
185
205
  format: 'build [:bar] ' + ':percent' + ' (:elapsed seconds)',
186
- clear: false
206
+ clear: true
187
207
  })
188
208
  ]
189
209
  };
190
210
  if (isProd && !isServer) {
191
211
  result.optimization = {
212
+ chunkIds: 'named',
213
+ moduleIds: 'named',
192
214
  minimize: true
193
215
  };
194
216
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobest-ui/scripts",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "description": "utils for project tools",
6
6
  "bin": {
@@ -44,54 +44,54 @@
44
44
  },
45
45
  "homepage": "https://autobest.visualstudio.com/AutoBestChina/_git/AutobestFrontendCommon#readme",
46
46
  "dependencies": {
47
- "@babel/core": "7.13.0",
48
- "@babel/plugin-proposal-class-properties": "7.12.13",
49
- "@babel/plugin-proposal-decorators": "7.14.2",
50
- "@babel/plugin-transform-object-assign": "7.2.0",
51
- "@babel/plugin-transform-runtime": "7.14.3",
52
- "@babel/plugin-transform-shorthand-properties": "7.2.0",
53
- "@babel/preset-env": "7.13.15",
54
- "@babel/preset-react": "7.13.13",
55
- "@babel/preset-typescript": "^7.10.1",
56
- "@loadable/babel-plugin": "5.12.0",
57
- "@loadable/webpack-plugin": "5.12.0",
58
- "babel-eslint": "10.0.1",
59
- "babel-loader": "8.0.5",
60
- "babel-plugin-named-asset-import": "^0.3.2",
61
- "babel-polyfill": "^6.26.0",
62
- "babel-preset-react-app": "^9.0.0",
63
- "chalk": "2.4.2",
47
+ "@babel/core": "7.17.8",
48
+ "@babel/plugin-proposal-class-properties": "7.16.7",
49
+ "@babel/plugin-transform-runtime": "7.17.0",
50
+ "@babel/preset-env": "7.16.11",
51
+ "@babel/preset-react": "7.16.7",
52
+ "@babel/preset-typescript": "7.16.7",
53
+ "@loadable/babel-plugin": "5.13.2",
54
+ "@loadable/webpack-plugin": "5.15.2",
55
+ "@soda/friendly-errors-webpack-plugin": "1.8.1",
56
+ "babel-loader": "8.2.4",
57
+ "babel-preset-react-app": "10.0.1",
58
+ "browserslist": "4.20.2",
59
+ "chalk": "4.1.2",
64
60
  "cross-spawn": "7.0.3",
65
- "css-loader": "2.1.1",
66
- "cssnano": "^4.1.10",
67
- "eslint-webpack-plugin": "2.5.3",
68
- "file-loader": "3.0.1",
69
- "friendly-errors-webpack-plugin": "^1.7.0",
70
- "happypack": "5.0.1",
71
- "html-webpack-plugin": "4.3.0",
72
- "ignore-loader": "^0.1.2",
61
+ "css-loader": "6.7.1",
62
+ "css-minimizer-webpack-plugin": "3.4.1",
63
+ "eslint": "8.12.0",
64
+ "eslint-config-react-app": "7.0.0",
65
+ "eslint-webpack-plugin": "3.1.1",
66
+ "html-webpack-plugin": "5.5.0",
67
+ "ignore-loader": "0.1.2",
73
68
  "ip": "1.1.5",
74
- "loader-utils": "2.0.0",
75
- "mini-css-extract-plugin": "^0.8.0",
76
- "node-sass": "4.12.0",
77
- "nodemon": "^1.19.1",
78
- "open": "7.0.4",
79
- "optimize-css-assets-webpack-plugin": "5.0.3",
80
- "postcss-flexbugs-fixes": "4.1.0",
81
- "postcss-loader": "3.0.0",
82
- "postcss-preset-env": "6.6.0",
83
- "postcss-safe-parser": "4.0.1",
84
- "progress-bar-webpack-plugin": "^2.1.0",
85
- "sass-loader": "7.1.0",
86
- "script-ext-html-webpack-plugin": "2.1.4",
87
- "style-loader": "0.23.1",
88
- "terser-webpack-plugin": "^4.0.0",
89
- "ts-pnp": "1.1.2",
90
- "url-loader": "1.1.2",
91
- "webpack": "4.43.0",
92
- "webpack-dev-server": "3.7.1",
93
- "webpack-merge": "^4.2.1",
94
- "webpack-node-externals": "1.7.2"
69
+ "loader-utils": "3.2.0",
70
+ "mini-css-extract-plugin": "2.6.0",
71
+ "nodemon": "2.0.15",
72
+ "open": "8.4.0",
73
+ "postcss": "8.4.12",
74
+ "postcss-flexbugs-fixes": "5.0.2",
75
+ "postcss-loader": "6.2.1",
76
+ "postcss-preset-env": "7.4.3",
77
+ "sass": "1.49.9",
78
+ "sass-loader": "12.6.0",
79
+ "style-loader": "3.3.1",
80
+ "terser-webpack-plugin": "5.3.1",
81
+ "webpack": "5.70.0",
82
+ "webpack-dev-server": "4.7.4",
83
+ "webpack-merge": "5.8.0",
84
+ "webpack-node-externals": "3.0.0"
95
85
  },
96
- "gitHead": "5350d0e451afedca23971bd5469c6f7320145fae"
86
+ "gitHead": "5350d0e451afedca23971bd5469c6f7320145fae",
87
+ "devDependencies": {
88
+ "@babel/plugin-proposal-decorators": "^7.17.8",
89
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
90
+ "@babel/plugin-proposal-optional-chaining": "^7.16.7",
91
+ "@babel/plugin-proposal-private-methods": "^7.16.11",
92
+ "@babel/plugin-proposal-private-property-in-object": "^7.16.7",
93
+ "postcss-normalize": "^10.0.1",
94
+ "progress-bar-webpack-plugin": "^2.1.0",
95
+ "resolve-url-loader": "^5.0.0"
96
+ }
97
97
  }
@@ -34,15 +34,9 @@ build()
34
34
  // eslint-disable-next-line no-console
35
35
  console.log(warnings.join('\n\n'));
36
36
  // eslint-disable-next-line no-console
37
- console.log(
38
- `\nSearch for the ${chalk.underline(
39
- chalk.yellow('keywords')
40
- )} to learn more about each warning.`
41
- );
37
+ console.log(`\nSearch for the ${chalk.underline(chalk.yellow('keywords'))} to learn more about each warning.`);
42
38
  // eslint-disable-next-line no-console
43
- console.log(
44
- `To ignore, add ${chalk.cyan('// eslint-disable-next-line')} to the line before.\n`
45
- );
39
+ console.log(`To ignore, add ${chalk.cyan('// eslint-disable-next-line')} to the line before.\n`);
46
40
  } else {
47
41
  // eslint-disable-next-line no-console
48
42
  console.log(chalk.green('Compiled successfully.\n'));
@@ -1,4 +1,4 @@
1
- const webpackFactory = require('./webpack.dev');
2
1
  const openStartRun = require('../common/start');
2
+ const webpackFactory = require('./webpack.dev');
3
3
 
4
4
  openStartRun(webpackFactory);
@@ -1,4 +1,4 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
3
  const HtmlWebpackPlugin = require('html-webpack-plugin');
4
4
  const { getProjectPath } = require('../common/utils');
@@ -9,7 +9,19 @@ module.exports = (isProd, appConfig, extendEnv) => {
9
9
  plugins: [
10
10
  new HtmlWebpackPlugin({
11
11
  inject: true,
12
- template: getProjectPath(appConfig.htmlPluginTemplate)
12
+ template: getProjectPath(appConfig.htmlPluginTemplate),
13
+ templateParameters: isProd
14
+ ? (compilation, assets, tags, options) => {
15
+ tags.headTags.forEach(tag => {
16
+ if (tag.tagName === 'script') {
17
+ tag.attributes.async = true;
18
+ }
19
+ });
20
+ return {
21
+ htmlWebpackPlugin: { options }
22
+ };
23
+ }
24
+ : null
13
25
  })
14
26
  ]
15
27
  };
@@ -17,9 +29,7 @@ module.exports = (isProd, appConfig, extendEnv) => {
17
29
  if (isProd) {
18
30
  result.plugins.push(
19
31
  new MiniCssExtractPlugin({
20
- filename: `css/[name].css?v=${extendEnv.version}`,
21
- allChunks: true,
22
- ignoreOrder: true
32
+ filename: `css/[name].css?v=${extendEnv.version}`
23
33
  })
24
34
  );
25
35
  }
@@ -1,25 +1,21 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const ip = require('ip');
3
- const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
4
- const baseConfig = require('./webpack.base');
3
+ const FriendlyErrorsPlugin = require('@soda/friendly-errors-webpack-plugin');
5
4
  const { getProjectPath } = require('../common/utils');
5
+ const baseConfig = require('./webpack.base');
6
6
 
7
7
  const HOST = process.env.HOST || ip.address() || 'localhost';
8
8
 
9
- module.exports = function(appConfig, extendEnv) {
9
+ module.exports = function (appConfig, extendEnv) {
10
10
  return merge(baseConfig(false, appConfig, extendEnv), {
11
11
  entry: getProjectPath(appConfig.startEntry),
12
12
  output: {
13
13
  publicPath: appConfig.startOutput.publicPath || '/',
14
14
  path: appConfig.startOutput.path,
15
15
  pathinfo: true,
16
- futureEmitAssets: true,
17
- filename: 'bundle.js',
16
+ filename: '[name].js',
18
17
  chunkFilename: '[name].chunk.js'
19
18
  },
20
- node: {
21
- fs: 'empty'
22
- },
23
19
  plugins: [
24
20
  // 相关配置文档:https://github.com/geowarin/friendly-errors-webpack-plugin
25
21
  new FriendlyErrorsPlugin({
@@ -1,13 +1,10 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const TerserPlugin = require('terser-webpack-plugin');
3
- const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
4
- // eslint-disable-next-line import/no-extraneous-dependencies
5
- const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
6
- const safePostCssParser = require('postcss-safe-parser');
7
- const baseConfig = require('./webpack.base');
3
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
8
4
  const { getProjectPath, deleteFolders } = require('../common/utils');
5
+ const baseConfig = require('./webpack.base');
9
6
 
10
- module.exports = function(appConfig, extendEnv) {
7
+ module.exports = function (appConfig, extendEnv) {
11
8
  const outputPath = getProjectPath(appConfig.buildOutput.path);
12
9
  deleteFolders(outputPath);
13
10
 
@@ -23,48 +20,47 @@ module.exports = function(appConfig, extendEnv) {
23
20
  // 非入口文件生产的js
24
21
  chunkFilename: `js/[name].chunk.js?v=${extendEnv.version}`
25
22
  },
26
- node: {
27
- fs: 'empty'
28
- },
29
- plugins: [
30
- new ScriptExtHtmlWebpackPlugin({
31
- defaultAttribute: 'async',
32
- preload: /\.js\?v=/
33
- })
34
- ],
35
23
  optimization: {
36
24
  concatenateModules: true,
37
25
  minimizer: [
38
26
  // 压缩js
39
27
  new TerserPlugin({
40
- cache: true,
41
- parallel: true,
42
- sourceMap: true
43
- }),
44
-
45
- // 压缩css
46
- new OptimizeCSSAssetsPlugin({
47
- cssProcessorOptions: {
48
- parser: safePostCssParser,
49
- map: {
50
- inline: false,
51
- annotation: false
28
+ terserOptions: {
29
+ parse: {
30
+ ecma: 8
31
+ },
32
+ compress: {
33
+ ecma: 5,
34
+ warnings: false,
35
+ comparisons: false,
36
+ inline: 2
37
+ },
38
+ mangle: {
39
+ safari10: true
40
+ },
41
+ output: {
42
+ ecma: 5,
43
+ comments: false,
44
+ ascii_only: true
52
45
  }
53
46
  }
54
- })
47
+ }),
48
+ // 压缩css
49
+ new CssMinimizerPlugin()
55
50
  ],
56
51
  splitChunks: {
57
52
  chunks: 'initial',
58
53
  minSize: 0,
54
+ // 按需加载时并行请求的最大数量
59
55
  maxAsyncRequests: 5,
56
+ // 入口位置最大的请求数量
60
57
  maxInitialRequests: 3,
61
58
  automaticNameDelimiter: '~',
62
- name: true,
63
59
  cacheGroups: {
64
- vendor: {
60
+ commons: {
65
61
  test: /[\\/]node_modules[\\/]/,
66
62
  chunks: 'initial',
67
- name: 'vendor',
63
+ name: 'vendors',
68
64
  minChunks: 1,
69
65
  priority: 10
70
66
  }
@@ -51,15 +51,9 @@ build()
51
51
  // eslint-disable-next-line no-console
52
52
  console.log(serverInfo.warnings.join('\n\n'));
53
53
  // eslint-disable-next-line no-console
54
- console.log(
55
- `\nSearch for the ${chalk.underline(
56
- chalk.yellow('keywords')
57
- )} to learn more about each warning.`
58
- );
54
+ console.log(`\nSearch for the ${chalk.underline(chalk.yellow('keywords'))} to learn more about each warning.`);
59
55
  // eslint-disable-next-line no-console
60
- console.log(
61
- `To ignore, add ${chalk.cyan('// eslint-disable-next-line')} to the line before.\n`
62
- );
56
+ console.log(`To ignore, add ${chalk.cyan('// eslint-disable-next-line')} to the line before.\n`);
63
57
  } else {
64
58
  // eslint-disable-next-line no-console
65
59
  console.log(chalk.green('Compiled successfully.\n'));
@@ -3,9 +3,9 @@ const open = require('open');
3
3
  const webpack = require('webpack');
4
4
  const appConfig = require('../common/appConfig');
5
5
  const getEnvironmentInfo = require('../common/extendEnv');
6
+ const { getProjectPath, parseArgsToJson } = require('../common/utils');
6
7
  const clientConfigFactory = require('./webpack.dev.client');
7
8
  const serverConfigFactory = require('./webpack.dev.server');
8
- const { getProjectPath, parseArgsToJson } = require('../common/utils');
9
9
 
10
10
  const extendEnv = getEnvironmentInfo(true);
11
11
  const clientConfig = clientConfigFactory(appConfig, extendEnv);
@@ -78,8 +78,7 @@ function run() {
78
78
  const info = stats.toJson({
79
79
  assets: false,
80
80
  hash: false,
81
- colors: false,
82
- warningsFilter: warn => warn.indexOf('Conflicting order between:') > -1
81
+ colors: false
83
82
  });
84
83
  if (stats.hasErrors()) {
85
84
  // eslint-disable-next-line no-console
@@ -87,8 +86,13 @@ function run() {
87
86
  }
88
87
 
89
88
  if (stats.hasWarnings()) {
90
- // eslint-disable-next-line no-console
91
- info.warnings.forEach(item => console.log(item));
89
+ info.warnings.forEach(item => {
90
+ if (item && item.message && item.message.indexOf('Conflicting order') > -1) {
91
+ return;
92
+ }
93
+ // eslint-disable-next-line no-console
94
+ console.log(item);
95
+ });
92
96
  }
93
97
  }
94
98
 
@@ -1,4 +1,4 @@
1
- const webpackFactory = require('./webpack.dev');
2
1
  const openStartRun = require('../common/start');
2
+ const webpackFactory = require('./webpack.dev');
3
3
 
4
4
  openStartRun(webpackFactory);
@@ -1,6 +1,4 @@
1
- const webpack = require('webpack');
2
- const merge = require('webpack-merge');
3
- const path = require('path');
1
+ const { merge } = require('webpack-merge');
4
2
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5
3
  const webpackCommon = require('../common/webpack.common');
6
4
 
@@ -13,34 +11,13 @@ module.exports = (appConfig, extendEnv, { isServer, isHotServer, isSetCommonAlia
13
11
  };
14
12
  if ((isProd || isHotServer) && !isServer) {
15
13
  result.plugins.push(
16
- // modules Id 随机数导致缓存失效
17
- new webpack.HashedModuleIdsPlugin(),
18
- // 解决新旧版本迭代时,google cache 旧版不能正常运行js
19
- // 通过指定chunk name而不是随机数
20
- new webpack.NamedChunksPlugin(chunk => {
21
- if (chunk.name) {
22
- return chunk.name;
23
- }
24
-
25
- // eslint-disable-next-line no-underscore-dangle
26
- return [...chunk._modules]
27
- .map(m =>
28
- path.relative(m.context, m.userRequest.substring(0, m.userRequest.lastIndexOf('.')))
29
- )
30
- .join('_');
31
- }),
32
14
  new MiniCssExtractPlugin({
33
15
  // filename: isHotServer ? 'css/[name].css' : `css/[name].css?v=${env.version}`,
34
16
  // 采用AMP 直接 把css 填充到html
35
- filename: isHotServer ? 'css/[name].css' : 'css/[name][contenthash].css',
36
- allChunks: !isHotServer,
37
- ignoreOrder: true
17
+ filename: isHotServer ? 'css/[name].css' : 'css/[name][contenthash:8].css'
38
18
  })
39
19
  );
40
20
  }
41
21
 
42
- return merge(
43
- webpackCommon(appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCommonAlias }),
44
- result
45
- );
22
+ return merge(webpackCommon(appConfig, extendEnv, { isProd, isServer, isHotServer, isSetCommonAlias }), result);
46
23
  };
@@ -1,9 +1,9 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const LoadablePlugin = require('@loadable/webpack-plugin');
3
- const baseConfig = require('./webpack.base');
4
3
  const { getProjectPath } = require('../common/utils');
4
+ const baseConfig = require('./webpack.base');
5
5
 
6
- module.exports = function(appConfig, extendEnv) {
6
+ module.exports = function (appConfig, extendEnv) {
7
7
  return merge(
8
8
  baseConfig(appConfig, extendEnv, {
9
9
  isServer: false,
@@ -14,8 +14,10 @@ module.exports = function(appConfig, extendEnv) {
14
14
  {
15
15
  // 入口文件
16
16
  entry: getProjectPath(appConfig.hotSsrClientEntry),
17
- node: {
18
- fs: 'empty'
17
+ resolve: {
18
+ fallback: {
19
+ fs: false
20
+ }
19
21
  },
20
22
  // 输出信息
21
23
  output: {
@@ -1,13 +1,13 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const HtmlWebpackPlugin = require('html-webpack-plugin');
3
3
  const ip = require('ip');
4
- const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
5
- const baseConfig = require('./webpack.base');
4
+ const FriendlyErrorsPlugin = require('@soda/friendly-errors-webpack-plugin');
6
5
  const { getProjectPath } = require('../common/utils');
6
+ const baseConfig = require('./webpack.base');
7
7
 
8
8
  const HOST = process.env.HOST || ip.address() || 'localhost';
9
9
 
10
- module.exports = function(appConfig, extendEnv) {
10
+ module.exports = function (appConfig, extendEnv) {
11
11
  return merge(
12
12
  baseConfig(appConfig, extendEnv, {
13
13
  isServer: false,
@@ -21,8 +21,7 @@ module.exports = function(appConfig, extendEnv) {
21
21
  publicPath: appConfig.startOutput.publicPath || '/',
22
22
  path: appConfig.startOutput.path,
23
23
  pathinfo: true,
24
- futureEmitAssets: true,
25
- filename: 'bundle.js',
24
+ filename: '[name].js',
26
25
  chunkFilename: '[name].chunk.js'
27
26
  },
28
27
  plugins: [
@@ -42,8 +41,10 @@ module.exports = function(appConfig, extendEnv) {
42
41
  template: getProjectPath(appConfig.htmlPluginTemplate)
43
42
  })
44
43
  ],
45
- node: {
46
- fs: 'empty'
44
+ resolve: {
45
+ fallback: {
46
+ fs: false
47
+ }
47
48
  },
48
49
  optimization: {
49
50
  minimize: false,
@@ -1,11 +1,9 @@
1
- const webpack = require('webpack');
2
- // eslint-disable-next-line import/no-extraneous-dependencies
3
1
  const nodeExternals = require('webpack-node-externals');
4
- const merge = require('webpack-merge');
5
- const baseConfig = require('./webpack.base');
2
+ const { merge } = require('webpack-merge');
6
3
  const { getProjectPath } = require('../common/utils');
4
+ const baseConfig = require('./webpack.base');
7
5
 
8
- module.exports = function(appConfig, extendEnv) {
6
+ module.exports = function (appConfig, extendEnv) {
9
7
  return merge(
10
8
  baseConfig(appConfig, extendEnv, {
11
9
  isServer: true,
@@ -19,7 +17,7 @@ module.exports = function(appConfig, extendEnv) {
19
17
  // 避免把 node_modules包下的第三方模块中包含的 nodejs内置的模块打包到出书文件中
20
18
  externals: nodeExternals({
21
19
  // 当然外部的css还是可以打进来的
22
- whitelist: /\.(js|css|less|scss|png|jpg|jpeg)$/
20
+ allowlist: /\.(js|css|less|scss|png|jpg|jpeg)$/
23
21
  }),
24
22
  // 入口文件
25
23
  entry: getProjectPath(appConfig.hotSsrServerEntry),
@@ -39,7 +37,7 @@ module.exports = function(appConfig, extendEnv) {
39
37
  test: /\.(scss|css|sass)$/,
40
38
  use: [
41
39
  {
42
- loader: 'ignore-loader'
40
+ loader: require.resolve('ignore-loader')
43
41
  }
44
42
  ]
45
43
  }
@@ -47,7 +45,6 @@ module.exports = function(appConfig, extendEnv) {
47
45
  }
48
46
  ]
49
47
  },
50
- plugins: [new webpack.ContextReplacementPlugin(/any-promise/)],
51
48
  // 避免路径丢失
52
49
  node: {
53
50
  __filename: true,
@@ -1,16 +1,13 @@
1
- const merge = require('webpack-merge');
1
+ const { merge } = require('webpack-merge');
2
2
  const LoadablePlugin = require('@loadable/webpack-plugin');
3
3
  const TerserPlugin = require('terser-webpack-plugin');
4
- // eslint-disable-next-line import/no-extraneous-dependencies
5
- const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
6
- const safePostCssParser = require('postcss-safe-parser');
7
- const baseConfig = require('./webpack.base');
8
-
4
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
9
5
  const { getProjectPath } = require('../common/utils');
6
+ const baseConfig = require('./webpack.base');
10
7
 
11
8
  const isCommonBuild = process.env.REACT_APP_BUILD_TYPE === 'common';
12
9
 
13
- module.exports = function(appConfig, extendEnv) {
10
+ module.exports = function (appConfig, extendEnv) {
14
11
  return merge(
15
12
  baseConfig(appConfig, extendEnv, {
16
13
  isServer: false,
@@ -29,8 +26,10 @@ module.exports = function(appConfig, extendEnv) {
29
26
  // 非入口文件生产的js
30
27
  chunkFilename: `js/[name].js?v=${extendEnv.version}`
31
28
  },
32
- node: {
33
- fs: 'empty'
29
+ resolve: {
30
+ fallback: {
31
+ fs: false
32
+ }
34
33
  },
35
34
  plugins: [
36
35
  new LoadablePlugin({
@@ -44,21 +43,28 @@ module.exports = function(appConfig, extendEnv) {
44
43
  minimizer: [
45
44
  // 压缩js
46
45
  new TerserPlugin({
47
- cache: true,
48
- parallel: true,
49
- sourceMap: true
50
- }),
51
-
52
- // 压缩css
53
- new OptimizeCSSAssetsPlugin({
54
- cssProcessorOptions: {
55
- parser: safePostCssParser,
56
- map: {
57
- inline: false,
58
- annotation: false
46
+ terserOptions: {
47
+ parse: {
48
+ ecma: 8
49
+ },
50
+ compress: {
51
+ ecma: 5,
52
+ warnings: false,
53
+ comparisons: false,
54
+ inline: 2
55
+ },
56
+ mangle: {
57
+ safari10: true
58
+ },
59
+ output: {
60
+ ecma: 5,
61
+ comments: false,
62
+ ascii_only: true
59
63
  }
60
64
  }
61
- })
65
+ }),
66
+ // 压缩css
67
+ new CssMinimizerPlugin()
62
68
  ],
63
69
  splitChunks: {
64
70
  chunks: 'initial',
@@ -66,7 +72,6 @@ module.exports = function(appConfig, extendEnv) {
66
72
  maxAsyncRequests: 5,
67
73
  maxInitialRequests: 3,
68
74
  automaticNameDelimiter: '~',
69
- name: true,
70
75
  cacheGroups: {
71
76
  common: {
72
77
  chunks: 'async',
@@ -1,12 +1,11 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
1
  const nodeExternals = require('webpack-node-externals');
3
- const merge = require('webpack-merge');
4
- const baseConfig = require('./webpack.base');
2
+ const { merge } = require('webpack-merge');
5
3
  const { getProjectPath } = require('../common/utils');
4
+ const baseConfig = require('./webpack.base');
6
5
 
7
6
  const isCommonBuild = process.env.REACT_APP_BUILD_TYPE === 'common';
8
7
 
9
- module.exports = function(appConfig, extendEnv) {
8
+ module.exports = function (appConfig, extendEnv) {
10
9
  return merge(
11
10
  baseConfig(appConfig, extendEnv, {
12
11
  isServer: true,
@@ -32,7 +31,7 @@ module.exports = function(appConfig, extendEnv) {
32
31
  test: /\.(scss|css|sass)$/,
33
32
  use: [
34
33
  {
35
- loader: 'ignore-loader'
34
+ loader: require.resolve('ignore-loader')
36
35
  }
37
36
  ]
38
37
  }
@@ -43,7 +42,7 @@ module.exports = function(appConfig, extendEnv) {
43
42
  // 服务端打包的时候忽略外部的npm包
44
43
  externals: nodeExternals({
45
44
  // 当然外部的css还是可以打进来的
46
- whitelist: /\.(css|less|scss)$/
45
+ allowlist: /\.(css|less|scss)$/
47
46
  })
48
47
  }
49
48
  );