akfun 1.5.13 → 1.5.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -9
- package/module/index.js +1 -1
- package/package.json +4 -3
- package/src/build.js +9 -4
- package/src/config/default.config.js +102 -0
- package/src/config/index.js +4 -96
- package/src/dev-server.js +9 -3
- package/src/utils/deepMergeConfig.js +9 -0
- package/src/utils/getConfigObj.js +1 -1
- package/src/utils/getProjectDir.js +16 -0
- package/src/webpack/webpack.base.conf.js +23 -10
- package/src/webpack/webpack.dev.conf.js +12 -10
- package/src/webpack/webpack.library.conf.js +23 -16
- package/src/webpack/webpack.prod.conf.js +29 -15
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# AKFun 前端脚手架
|
|
2
2
|
> AKFun 是一个基于 Webpack4.0 和 rollup 的前端多场景打包工具,支持多种技术栈:Vue技术栈、React技术栈、React&TS技术栈
|
|
3
|
-
-
|
|
3
|
+
- 核心理念:提供完整&全面的前端工程能力,并尽可能屏蔽掉前端工程相关配置,让开发者更专注业务研发工作。
|
|
4
|
+
- 技术栈:node/webpack4.0/rollup/babel/eslint/stylelint
|
|
4
5
|
|
|
5
6
|
## 特性
|
|
6
7
|
- ⚡️ 零配置,开箱即用
|
|
7
8
|
- 👏 支持Vue和React项目的调试和构建
|
|
8
9
|
- 📤 支持单页面和多页面
|
|
9
|
-
- 💪 提供三种构建场景:
|
|
10
|
-
- ❤️ 开放配置能力:
|
|
10
|
+
- 💪 提供三种构建场景: 本地开发模式(包含热更新、接口代理等功能)、生产环境代码构建、library库构建(支持umd和esm的打包能力)
|
|
11
|
+
- ❤️ 开放配置能力: 可配置构建入口文件、开启ESLint代码检测、接口代理等
|
|
11
12
|
- 👍 支持 [Autoprefixer](https://github.com/postcss/autoprefixer#readme)、[Sass](https://sass-lang.com/)、[PostCSS](https://postcss.org/)、[ESLint](http://eslint.cn/)、[StyleLint](https://stylelint.io/)
|
|
12
13
|
- ❤️ 支持项目系统参数自动批量替换 [params-replace-loader](https://www.npmjs.com/package/params-replace-loader)
|
|
13
14
|
- 😀 提供完整的Vue和React项目模板
|
|
@@ -245,7 +246,43 @@ module.exports = {
|
|
|
245
246
|
}
|
|
246
247
|
```
|
|
247
248
|
|
|
248
|
-
7.
|
|
249
|
+
7. 打包忽略node_modules配置项: ignoreNodeModules(默认为false)
|
|
250
|
+
> 打包过程中,忽略node_modules中的依赖文件,不注入到bundle中,减少最后生成代码体积
|
|
251
|
+
```bash
|
|
252
|
+
module.exports = {
|
|
253
|
+
...
|
|
254
|
+
webpack: {
|
|
255
|
+
ignoreNodeModules: true,
|
|
256
|
+
}
|
|
257
|
+
...
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
8. 是否生成ts声明文件配置项: createDeclaration(默认为false)
|
|
262
|
+
> 构建ts项目中,可以选择是否生成ts声明文件
|
|
263
|
+
```bash
|
|
264
|
+
module.exports = {
|
|
265
|
+
...
|
|
266
|
+
webpack: {
|
|
267
|
+
createDeclaration: true,
|
|
268
|
+
}
|
|
269
|
+
...
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
9. 配置项目源码目录(工程有效目录范围): projectDir
|
|
274
|
+
> 构建项目中,设置生效的目录(可同时设置多个目录),用于提高前端工程执行效率。可以不配置,默认为['./src']
|
|
275
|
+
```bash
|
|
276
|
+
module.exports = {
|
|
277
|
+
...
|
|
278
|
+
webpack: {
|
|
279
|
+
projectDir: ['./src'],
|
|
280
|
+
}
|
|
281
|
+
...
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
10. 项目源码环境变量批量替换
|
|
249
286
|
> [关于params-replace-loader的使用方法](https://www.npmjs.com/package/params-replace-loader)
|
|
250
287
|
```bash
|
|
251
288
|
module.exports = {
|
|
@@ -264,7 +301,7 @@ module.exports = {
|
|
|
264
301
|
}
|
|
265
302
|
```
|
|
266
303
|
|
|
267
|
-
|
|
304
|
+
11. 接口代理配置:目前只有dev本地开发调试模式下会启动
|
|
268
305
|
> [关于proxyTable的配置方法](https://www.webpackjs.com/configuration/dev-server/#devserver-proxy)
|
|
269
306
|
```bash
|
|
270
307
|
module.exports = {
|
|
@@ -277,7 +314,7 @@ module.exports = {
|
|
|
277
314
|
}
|
|
278
315
|
```
|
|
279
316
|
|
|
280
|
-
|
|
317
|
+
12. 用于开启本地调试模式的相关配置信息
|
|
281
318
|
```bash
|
|
282
319
|
module.exports = {
|
|
283
320
|
...
|
|
@@ -301,7 +338,7 @@ module.exports = {
|
|
|
301
338
|
}
|
|
302
339
|
```
|
|
303
340
|
|
|
304
|
-
|
|
341
|
+
13. 用于构建生产环境代码的相关配置信息
|
|
305
342
|
```bash
|
|
306
343
|
module.exports = {
|
|
307
344
|
...
|
|
@@ -319,7 +356,7 @@ module.exports = {
|
|
|
319
356
|
}
|
|
320
357
|
```
|
|
321
358
|
|
|
322
|
-
|
|
359
|
+
14. 用于构建第三方功能包的配置(以umd格式输出)
|
|
323
360
|
```bash
|
|
324
361
|
module.exports = {
|
|
325
362
|
...
|
|
@@ -338,7 +375,7 @@ module.exports = {
|
|
|
338
375
|
}
|
|
339
376
|
```
|
|
340
377
|
|
|
341
|
-
|
|
378
|
+
15. 用于构建esm格式的第三方功能包配置
|
|
342
379
|
```bash
|
|
343
380
|
module.exports = {
|
|
344
381
|
...
|
package/module/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akfun",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.18",
|
|
4
4
|
"description": "前端脚手架:支持Vue技术栈和react技术栈",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"前端工程",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"vue项目脚手架",
|
|
11
11
|
"lib库构建工具"
|
|
12
12
|
],
|
|
13
|
-
"author": "
|
|
13
|
+
"author": "wibetter",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"bin": {
|
|
16
16
|
"akfun": "./bin/akfun.js"
|
|
@@ -152,7 +152,8 @@
|
|
|
152
152
|
"webpack-dev-middleware": "^3.7.2",
|
|
153
153
|
"webpack-hot-middleware": "^2.25.0",
|
|
154
154
|
"webpack-merge": "^4.2.2",
|
|
155
|
-
"yargs": "^12.0.2"
|
|
155
|
+
"yargs": "^12.0.2",
|
|
156
|
+
"webpack-node-externals": "^3.0.0"
|
|
156
157
|
},
|
|
157
158
|
"devDependencies": {
|
|
158
159
|
"@commitlint/cli": "^8.3.5",
|
package/src/build.js
CHANGED
|
@@ -4,10 +4,15 @@ const path = require('path');
|
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const webpack = require('webpack');
|
|
6
6
|
const checkVersion = require('./check-versions');
|
|
7
|
-
const
|
|
7
|
+
const projectConfig = require('./config/index'); // 引入当前项目配置文件
|
|
8
|
+
const deepMergeConfig = require('./utils/deepMergeConfig');
|
|
8
9
|
|
|
9
10
|
// 构建脚本:一般用于构建生产环境的代码
|
|
10
|
-
module.exports = function (BuildType) {
|
|
11
|
+
module.exports = function (BuildType, akfunConfig) {
|
|
12
|
+
let config = projectConfig; // 默认使用执行命令目录下的配置数据
|
|
13
|
+
if (akfunConfig) {
|
|
14
|
+
config = deepMergeConfig(defaultConfig, akfunConfig);
|
|
15
|
+
}
|
|
11
16
|
// 检查当前npm版本号是否匹配
|
|
12
17
|
checkVersion();
|
|
13
18
|
const spinner = ora('[akfun]开启AKFun构建能力...').start();
|
|
@@ -16,10 +21,10 @@ module.exports = function (BuildType) {
|
|
|
16
21
|
// 根据BuildType判断是否引用专用于第三方功能包的webpack配置
|
|
17
22
|
if (BuildType && BuildType === 'lib') {
|
|
18
23
|
spinner.start('[akfun]开始构建第三方功能包...');
|
|
19
|
-
webpackConfig = require('./webpack/webpack.library.conf')();
|
|
24
|
+
webpackConfig = require('./webpack/webpack.library.conf')(config);
|
|
20
25
|
} else {
|
|
21
26
|
spinner.start('[akfun]开始构建生产环境的代码...');
|
|
22
|
-
webpackConfig = require('./webpack/webpack.prod.conf')();
|
|
27
|
+
webpackConfig = require('./webpack/webpack.prod.conf')(config);
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
/**
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// 统一路径解析:
|
|
3
|
+
const { resolve } = require('../utils/pathUtils');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* akfun脚手架赋予当前项目的默认配置
|
|
7
|
+
*/
|
|
8
|
+
const defaultAKFunConfig = {
|
|
9
|
+
settings: {
|
|
10
|
+
enableESLint: false, // 是否开启ESLint,默认开启ESLint检测代码格式
|
|
11
|
+
enableESLintFix: false, // 是否ESLint自动修正代码格式
|
|
12
|
+
enableStyleLint: false, // 是否开启StyleLint,默认开启ESLint检测代码格式
|
|
13
|
+
enableStyleLintFix: false // 是否需要StyleLint自动修正代码格式
|
|
14
|
+
},
|
|
15
|
+
webpack: {
|
|
16
|
+
resolve: {
|
|
17
|
+
// webpack的resolve配置
|
|
18
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue', '.json'], // 用于配置webpack在尝试过程中用到的后缀列表
|
|
19
|
+
alias: {
|
|
20
|
+
'@': resolve('src'),
|
|
21
|
+
$components: resolve('src/components'),
|
|
22
|
+
$pages: resolve('src/pages'),
|
|
23
|
+
$plugins: resolve('src/plugins'),
|
|
24
|
+
$utils: resolve('src/utils')
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
createDeclaration: false, // 打包时是否创建ts声明文件
|
|
28
|
+
ignoreNodeModules: false, // 打包时是否忽略 node_modules
|
|
29
|
+
externals: [], // 从输出的 bundle 中排除依赖
|
|
30
|
+
sassResources: []
|
|
31
|
+
},
|
|
32
|
+
envParams: {
|
|
33
|
+
// 项目系统环境变量
|
|
34
|
+
common: {
|
|
35
|
+
// 通用参数
|
|
36
|
+
'#version#': '20200810.1'
|
|
37
|
+
},
|
|
38
|
+
local: {
|
|
39
|
+
// 本地开发环境
|
|
40
|
+
'#dataApiBase#': 'http://localhost:1024', // 数据接口根地址
|
|
41
|
+
'#assetsPublicPath#': 'http://localhost:1024', // 静态资源根地址
|
|
42
|
+
'#routeBasePath#': '/' // 路由根地址
|
|
43
|
+
},
|
|
44
|
+
online: {
|
|
45
|
+
// 线上正式环境配置参数
|
|
46
|
+
'#dataApiBase#': '/', // 数据接口根地址 "//xxx.cn/"格式
|
|
47
|
+
'#assetsPublicPath#': '', // 静态资源根地址 "//xxx.cn/_spa/projectName"格式
|
|
48
|
+
'#routeBasePath#': '/' // 路由根地址 "/_spa/projectName/"格式
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
dev: {
|
|
52
|
+
// 用于开启本地调试模式的相关配置信息
|
|
53
|
+
NODE_ENV: 'development',
|
|
54
|
+
port: 80,
|
|
55
|
+
autoOpenBrowser: true,
|
|
56
|
+
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
57
|
+
assetsSubDirectory: '',
|
|
58
|
+
hostname: 'localhost',
|
|
59
|
+
proxyTable: {},
|
|
60
|
+
/** CSS Sourcemaps off by default because relative paths are "buggy"
|
|
61
|
+
* with this option, according to the CSS-Loader README
|
|
62
|
+
* (https://github.com/webpack/css-loader#sourcemaps)
|
|
63
|
+
* In our experience, they generally work as expected,
|
|
64
|
+
* just be aware of this issue when enabling this option.
|
|
65
|
+
*/
|
|
66
|
+
cssSourceMap: false
|
|
67
|
+
},
|
|
68
|
+
build: {
|
|
69
|
+
// 用于构建生产环境代码的相关配置信息
|
|
70
|
+
NODE_ENV: 'production', // production 模式,会启动UglifyJsPlugin服务
|
|
71
|
+
assetsRoot: resolve('dist'), // 编译完成的文件存放路径
|
|
72
|
+
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
73
|
+
assetsSubDirectory: '', // 资源引用二级路径
|
|
74
|
+
productionSourceMap: false,
|
|
75
|
+
// Gzip off by default as many popular public hosts such as
|
|
76
|
+
// Surge or Netlify already gzip all public assets for you.
|
|
77
|
+
// Before setting to `true`, make sure to:
|
|
78
|
+
// npm install --save-dev compression-webpack-plugin
|
|
79
|
+
productionGzip: false,
|
|
80
|
+
productionGzipExtensions: ['js', 'css', 'json'],
|
|
81
|
+
// Run the build command with an extra argument to
|
|
82
|
+
// View the bundle analyzer report after build finishes:
|
|
83
|
+
// `npm run build --report`
|
|
84
|
+
// Set to `true` or `false` to always turn it on or off
|
|
85
|
+
bundleAnalyzerReport: false
|
|
86
|
+
},
|
|
87
|
+
build2lib: {
|
|
88
|
+
// 用于构建第三方功能包的配置文件
|
|
89
|
+
NODE_ENV: 'production',
|
|
90
|
+
libraryName: '', // 构建第三方功能包时最后导出的引用变量名
|
|
91
|
+
assetsRoot: resolve('dist'), // 编译完成的文件存放路径
|
|
92
|
+
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
93
|
+
assetsSubDirectory: '', // 资源引用二级路径
|
|
94
|
+
productionSourceMap: false,
|
|
95
|
+
productionGzip: false,
|
|
96
|
+
productionGzipExtensions: ['js', 'css', 'json'],
|
|
97
|
+
bundleAnalyzerReport: false
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// 备注:数组类型则直接覆盖
|
|
102
|
+
module.exports = defaultAKFunConfig;
|
package/src/config/index.js
CHANGED
|
@@ -1,108 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const deepMerge = require('deepmerge');
|
|
3
2
|
// 统一路径解析:
|
|
4
3
|
const { resolve } = require('../utils/pathUtils');
|
|
4
|
+
const defaultAKFunConfig = require('./default.config');
|
|
5
5
|
const getConfigObj = require('../utils/getConfigObj');
|
|
6
|
+
const deepMergeConfig = require('../utils/deepMergeConfig');
|
|
6
7
|
|
|
7
8
|
/** akfun脚手架赋予当前项目的默认配置
|
|
8
9
|
* 备注:项目根目录的akfun.config.js的配置内容优先级高于defultAKFunConfig
|
|
9
10
|
*/
|
|
10
|
-
const defultAKFunConfig = {
|
|
11
|
-
settings: {
|
|
12
|
-
enableESLint: false, // 是否开启ESLint,默认开启ESLint检测代码格式
|
|
13
|
-
enableESLintFix: false, // 是否ESLint自动修正代码格式
|
|
14
|
-
enableStyleLint: false, // 是否开启StyleLint,默认开启ESLint检测代码格式
|
|
15
|
-
enableStyleLintFix: false // 是否需要StyleLint自动修正代码格式
|
|
16
|
-
},
|
|
17
|
-
webpack: {
|
|
18
|
-
resolve: {
|
|
19
|
-
// webpack的resolve配置
|
|
20
|
-
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue', '.json'], // 用于配置webpack在尝试过程中用到的后缀列表
|
|
21
|
-
alias: {
|
|
22
|
-
'@': resolve('src'),
|
|
23
|
-
$components: resolve('src/components'),
|
|
24
|
-
$pages: resolve('src/pages'),
|
|
25
|
-
$plugins: resolve('src/plugins'),
|
|
26
|
-
$utils: resolve('src/utils')
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
externals: [], // 从输出的 bundle 中排除依赖
|
|
30
|
-
sassResources: []
|
|
31
|
-
},
|
|
32
|
-
envParams: {
|
|
33
|
-
// 项目系统环境变量
|
|
34
|
-
common: {
|
|
35
|
-
// 通用参数
|
|
36
|
-
'#version#': '20200810.1'
|
|
37
|
-
},
|
|
38
|
-
local: {
|
|
39
|
-
// 本地开发环境
|
|
40
|
-
'#dataApiBase#': 'http://localhost:1024', // 数据接口根地址
|
|
41
|
-
'#assetsPublicPath#': 'http://localhost:1024', // 静态资源根地址
|
|
42
|
-
'#routeBasePath#': '/' // 路由根地址
|
|
43
|
-
},
|
|
44
|
-
online: {
|
|
45
|
-
// 线上正式环境配置参数
|
|
46
|
-
'#dataApiBase#': '/', // 数据接口根地址 "//xxx.cn/"格式
|
|
47
|
-
'#assetsPublicPath#': '', // 静态资源根地址 "//xxx.cn/_spa/projectName"格式
|
|
48
|
-
'#routeBasePath#': '/' // 路由根地址 "/_spa/projectName/"格式
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
dev: {
|
|
52
|
-
// 用于开启本地调试模式的相关配置信息
|
|
53
|
-
NODE_ENV: 'development',
|
|
54
|
-
port: 80,
|
|
55
|
-
autoOpenBrowser: true,
|
|
56
|
-
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
57
|
-
assetsSubDirectory: '',
|
|
58
|
-
hostname: 'localhost',
|
|
59
|
-
proxyTable: {},
|
|
60
|
-
/** CSS Sourcemaps off by default because relative paths are "buggy"
|
|
61
|
-
* with this option, according to the CSS-Loader README
|
|
62
|
-
* (https://github.com/webpack/css-loader#sourcemaps)
|
|
63
|
-
* In our experience, they generally work as expected,
|
|
64
|
-
* just be aware of this issue when enabling this option.
|
|
65
|
-
*/
|
|
66
|
-
cssSourceMap: false
|
|
67
|
-
},
|
|
68
|
-
build: {
|
|
69
|
-
// 用于构建生产环境代码的相关配置信息
|
|
70
|
-
NODE_ENV: 'production', // production 模式,会启动UglifyJsPlugin服务
|
|
71
|
-
assetsRoot: resolve('dist'), // 编译完成的文件存放路径
|
|
72
|
-
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
73
|
-
assetsSubDirectory: '', // 资源引用二级路径
|
|
74
|
-
productionSourceMap: false,
|
|
75
|
-
// Gzip off by default as many popular public hosts such as
|
|
76
|
-
// Surge or Netlify already gzip all public assets for you.
|
|
77
|
-
// Before setting to `true`, make sure to:
|
|
78
|
-
// npm install --save-dev compression-webpack-plugin
|
|
79
|
-
productionGzip: false,
|
|
80
|
-
productionGzipExtensions: ['js', 'css', 'json'],
|
|
81
|
-
// Run the build command with an extra argument to
|
|
82
|
-
// View the bundle analyzer report after build finishes:
|
|
83
|
-
// `npm run build --report`
|
|
84
|
-
// Set to `true` or `false` to always turn it on or off
|
|
85
|
-
bundleAnalyzerReport: false
|
|
86
|
-
},
|
|
87
|
-
build2lib: {
|
|
88
|
-
// 用于构建第三方功能包的配置文件
|
|
89
|
-
NODE_ENV: 'production',
|
|
90
|
-
libraryName: '', // 构建第三方功能包时最后导出的引用变量名
|
|
91
|
-
assetsRoot: resolve('dist'), // 编译完成的文件存放路径
|
|
92
|
-
assetsPublicPath: '/', // 设置静态资源的引用路径(根域名+路径)
|
|
93
|
-
assetsSubDirectory: '', // 资源引用二级路径
|
|
94
|
-
productionSourceMap: false,
|
|
95
|
-
productionGzip: false,
|
|
96
|
-
productionGzipExtensions: ['js', 'css', 'json'],
|
|
97
|
-
bundleAnalyzerReport: false
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
11
|
|
|
101
12
|
// 从项目根目录获取当前项目的配置文件
|
|
102
|
-
const
|
|
13
|
+
const curProjectConfig = getConfigObj(resolve('akfun.config.js'));
|
|
103
14
|
|
|
104
|
-
// module.exports = Object.assign(defultAKFunConfig, curProjectConfg);
|
|
105
|
-
|
|
106
|
-
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
|
|
107
15
|
// 备注:数组类型则直接覆盖
|
|
108
|
-
module.exports =
|
|
16
|
+
module.exports = deepMergeConfig(defaultAKFunConfig, curProjectConfig);
|
package/src/dev-server.js
CHANGED
|
@@ -7,11 +7,17 @@ const checkVersion = require('./check-versions');
|
|
|
7
7
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
8
8
|
const { resolve } = require('./utils/pathUtils');
|
|
9
9
|
// 引入当前项目配置文件
|
|
10
|
-
const
|
|
10
|
+
const projectConfig = require('./config/index');
|
|
11
|
+
const defaultConfig = require('./config/default.config');
|
|
11
12
|
const getDevWebpackConfig = require('./webpack/webpack.dev.conf');
|
|
13
|
+
const deepMergeConfig = require('./utils/deepMergeConfig');
|
|
12
14
|
|
|
13
15
|
// 构建脚本:一般用于构建开发环境的代码(包含热更新、接口代理等功能)
|
|
14
|
-
module.exports = function () {
|
|
16
|
+
module.exports = function (akfunConfig) {
|
|
17
|
+
let config = projectConfig; // 默认使用执行命令目录下的配置数据
|
|
18
|
+
if (akfunConfig) {
|
|
19
|
+
config = deepMergeConfig(defaultConfig, akfunConfig);
|
|
20
|
+
}
|
|
15
21
|
// 检查当前npm版本号是否匹配
|
|
16
22
|
checkVersion();
|
|
17
23
|
const spinner = ora('[akfun]开启调试模式...').start();
|
|
@@ -35,7 +41,7 @@ module.exports = function () {
|
|
|
35
41
|
// 使用 express 启动一个服务
|
|
36
42
|
const app = express();
|
|
37
43
|
// 获取开发环境的webpack基本配置
|
|
38
|
-
const webpackConfig = getDevWebpackConfig();
|
|
44
|
+
const webpackConfig = getDevWebpackConfig(config);
|
|
39
45
|
const compiler = webpack(webpackConfig); // 启动 webpack 进行编译
|
|
40
46
|
|
|
41
47
|
// 启动 webpack-dev-middleware,将编译后的文件暂存到内存中
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const deepMerge = require('deepmerge');
|
|
2
|
+
|
|
3
|
+
const deepMergeConfig = function (defaultConfig, curConfig) {
|
|
4
|
+
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
|
|
5
|
+
|
|
6
|
+
return deepMerge(defaultConfig, curConfig, { arrayMerge: overwriteMerge });
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports = deepMergeConfig;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { resolveToCurrentRoot } = require('./pathUtils');
|
|
2
|
+
const { isArray, isString } = require('../utils/typeof');
|
|
3
|
+
|
|
4
|
+
module.exports = (_projectDir) => {
|
|
5
|
+
const curProjectDir = [];
|
|
6
|
+
if (!_projectDir) {
|
|
7
|
+
curProjectDir.push(resolveToCurrentRoot('./src'));
|
|
8
|
+
} else if (isArray(_projectDir)) {
|
|
9
|
+
_projectDir.forEach((dir) => {
|
|
10
|
+
curProjectDir.push(resolveToCurrentRoot(dir));
|
|
11
|
+
});
|
|
12
|
+
} else if (isString(_projectDir)) {
|
|
13
|
+
curProjectDir.push(resolveToCurrentRoot(_projectDir));
|
|
14
|
+
}
|
|
15
|
+
return curProjectDir;
|
|
16
|
+
};
|
|
@@ -7,6 +7,7 @@ const utils = require('./loaderUtils');
|
|
|
7
7
|
const vueLoaderConfig = require('./vue-loader.conf');
|
|
8
8
|
const { resolve, resolveToCurrentRoot, catchCurPackageJson } = require('../utils/pathUtils');
|
|
9
9
|
const getConfigObj = require('../utils/getConfigObj');
|
|
10
|
+
const getProjectDir = require('../utils/getProjectDir');
|
|
10
11
|
const catchVuePages = require('../utils/catchVuePages'); // 用于获取当前项目中的vue单文件
|
|
11
12
|
// 引入当前项目配置文件
|
|
12
13
|
const config = require('../config/index');
|
|
@@ -28,7 +29,14 @@ const BannerPack = new webpack.BannerPlugin({
|
|
|
28
29
|
entryOnly: true // 只在入口 chunks 文件中添加
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
/**
|
|
33
|
+
* webpack.base.conf.js
|
|
34
|
+
* 主要用于设置 rules 和 通用插件
|
|
35
|
+
*/
|
|
36
|
+
module.exports = (option) => {
|
|
37
|
+
const curEnvConfig = option || {}; // 用于接收当前运行环境配置变量
|
|
38
|
+
// 获取当前项目目录
|
|
39
|
+
const curProjectDir = getProjectDir(config.webpack.projectDir);
|
|
32
40
|
const webpackConfig = {
|
|
33
41
|
entry: config.webpack.entry,
|
|
34
42
|
/*
|
|
@@ -66,11 +74,17 @@ module.exports = () => {
|
|
|
66
74
|
options: babelConfig
|
|
67
75
|
},
|
|
68
76
|
{
|
|
69
|
-
loader: 'ts-loader'
|
|
70
|
-
|
|
77
|
+
loader: 'ts-loader',
|
|
78
|
+
options: {
|
|
79
|
+
// configFile: path.resolve(__dirname, '../config/tsconfig.json')
|
|
80
|
+
compilerOptions: {
|
|
81
|
+
declaration: config.webpack.createDeclaration || false,
|
|
82
|
+
outDir: curEnvConfig.assetsRoot || './dist'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
71
85
|
}
|
|
72
86
|
],
|
|
73
|
-
include: [resolve('src')],
|
|
87
|
+
include: curProjectDir, // [resolve('src')],
|
|
74
88
|
exclude: /node_modules/
|
|
75
89
|
},
|
|
76
90
|
{
|
|
@@ -81,7 +95,7 @@ module.exports = () => {
|
|
|
81
95
|
options: babelConfig
|
|
82
96
|
}
|
|
83
97
|
],
|
|
84
|
-
include: [resolve('src')],
|
|
98
|
+
include: curProjectDir, // [resolve('src')],
|
|
85
99
|
exclude: /node_modules/
|
|
86
100
|
},
|
|
87
101
|
{
|
|
@@ -123,7 +137,7 @@ module.exports = () => {
|
|
|
123
137
|
{
|
|
124
138
|
test: /\.(js|ts|tsx|jsx|vue|css|html)$/,
|
|
125
139
|
loader: 'params-replace-loader',
|
|
126
|
-
include: [resolve('src')],
|
|
140
|
+
include: curProjectDir, // [resolve('src')],
|
|
127
141
|
exclude: [/node_modules/, resolve('src/mock/data')], // 排除不需要进行校验的文件夹
|
|
128
142
|
options: config.envParams
|
|
129
143
|
}
|
|
@@ -135,7 +149,6 @@ module.exports = () => {
|
|
|
135
149
|
new VueLoaderPlugin()
|
|
136
150
|
]
|
|
137
151
|
};
|
|
138
|
-
|
|
139
152
|
// 是否开启ESLint
|
|
140
153
|
if (config.settings.enableESLint) {
|
|
141
154
|
// ts类型
|
|
@@ -143,7 +156,7 @@ module.exports = () => {
|
|
|
143
156
|
test: /\.tsx?$/,
|
|
144
157
|
loader: 'eslint-loader',
|
|
145
158
|
enforce: 'pre',
|
|
146
|
-
include: [resolve('src')],
|
|
159
|
+
include: curProjectDir, // [resolve('src')],
|
|
147
160
|
exclude: /node_modules/,
|
|
148
161
|
options: {
|
|
149
162
|
cache: true,
|
|
@@ -157,7 +170,7 @@ module.exports = () => {
|
|
|
157
170
|
test: /\.jsx?$/,
|
|
158
171
|
loader: 'eslint-loader',
|
|
159
172
|
enforce: 'pre',
|
|
160
|
-
include: [resolve('src')],
|
|
173
|
+
include: curProjectDir, // [resolve('src')],
|
|
161
174
|
exclude: /node_modules/,
|
|
162
175
|
options: {
|
|
163
176
|
cache: true, // the cache is written to the ./node_modules/.cache/eslint-loader director
|
|
@@ -171,7 +184,7 @@ module.exports = () => {
|
|
|
171
184
|
test: /\.vue$/,
|
|
172
185
|
loader: 'eslint-loader',
|
|
173
186
|
enforce: 'pre',
|
|
174
|
-
include: [resolve('src')],
|
|
187
|
+
include: curProjectDir, // [resolve('src')],
|
|
175
188
|
exclude: /node_modules/,
|
|
176
189
|
options: {
|
|
177
190
|
cache: true,
|
|
@@ -6,15 +6,17 @@ const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
|
|
|
6
6
|
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
|
7
7
|
const utils = require('./loaderUtils');
|
|
8
8
|
// 引入当前项目配置文件
|
|
9
|
-
const
|
|
9
|
+
const projectConfig = require('../config/index');
|
|
10
10
|
const getBaseWebpackConfig = require('./webpack.base.conf');
|
|
11
11
|
const getJsEntries = require('../utils/jsEntries');
|
|
12
12
|
const entrys2htmlWebpackPlugin = require('../utils/entrys2htmlWebpackPlugin');
|
|
13
13
|
const { isArray } = require('../utils/typeof');
|
|
14
14
|
|
|
15
|
-
module.exports = () => {
|
|
15
|
+
module.exports = (akfunConfig) => {
|
|
16
|
+
let config = akfunConfig || projectConfig; // 默认使用执行命令目录下的配置数据
|
|
17
|
+
const curEnvConfig = config.dev || {}; // 当前执行环境配置
|
|
16
18
|
// 获取webpack基本配置
|
|
17
|
-
const baseWebpackConfig = getBaseWebpackConfig();
|
|
19
|
+
const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
|
|
18
20
|
|
|
19
21
|
// 获取页面模板地址
|
|
20
22
|
let curHtmlTemplate = path.resolve(__dirname, '../initData/template/index.html');
|
|
@@ -23,21 +25,21 @@ module.exports = () => {
|
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
const webpackDevConfig = merge(baseWebpackConfig, {
|
|
26
|
-
mode:
|
|
28
|
+
mode: curEnvConfig.NODE_ENV, // development模式,会启动NamedChunksPlugin、NamedModulesPlugin服务
|
|
27
29
|
output: {
|
|
28
|
-
publicPath:
|
|
30
|
+
publicPath: curEnvConfig.assetsPublicPath // 引用地址:配置发布到线上资源的URL前缀
|
|
29
31
|
},
|
|
30
32
|
module: {
|
|
31
33
|
rules: utils.styleLoaders({
|
|
32
|
-
sourceMap:
|
|
34
|
+
sourceMap: curEnvConfig.cssSourceMap,
|
|
33
35
|
environment: 'dev'
|
|
34
36
|
})
|
|
35
37
|
},
|
|
36
38
|
// cheap-module-eval-source-map is faster for development
|
|
37
|
-
devtool: '#cheap-module-eval-source-map',
|
|
39
|
+
devtool: '#source-map', // '#cheap-module-eval-source-map',
|
|
38
40
|
plugins: [
|
|
39
41
|
new webpack.DefinePlugin({
|
|
40
|
-
'process.env.NODE_ENV': JSON.stringify(
|
|
42
|
+
'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV) // vue-router中根据此变量判断执行环境
|
|
41
43
|
}),
|
|
42
44
|
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
|
|
43
45
|
new webpack.HotModuleReplacementPlugin(),
|
|
@@ -48,8 +50,8 @@ module.exports = () => {
|
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
// 集成dev配置中的构建入口(优先级高于config.webpack.entry)
|
|
51
|
-
if (
|
|
52
|
-
webpackDevConfig.entry =
|
|
53
|
+
if (curEnvConfig.entry) {
|
|
54
|
+
webpackDevConfig.entry = curEnvConfig.entry; // 备注:会覆盖config.webpack.entry的配置
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
// 多页面多模板支持能力
|
|
@@ -6,40 +6,47 @@ const CompressionWebpackPlugin = require('compression-webpack-plugin');
|
|
|
6
6
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
7
7
|
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
|
|
8
8
|
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
|
9
|
+
const nodeExternals = require('webpack-node-externals');
|
|
9
10
|
|
|
10
11
|
const utils = require('./loaderUtils');
|
|
11
12
|
// 引入当前项目配置文件
|
|
12
|
-
const
|
|
13
|
+
const projectConfig = require('../config/index');
|
|
13
14
|
const getBaseWebpackConfig = require('./webpack.base.conf');
|
|
14
15
|
|
|
15
|
-
module.exports = () => {
|
|
16
|
+
module.exports = (akfunConfig) => {
|
|
17
|
+
let config = akfunConfig || projectConfig; // 默认使用执行命令目录下的配置数据
|
|
18
|
+
const curEnvConfig = config.build2lib || {}; // 当前执行环境配置
|
|
16
19
|
// 获取webpack基本配置
|
|
17
|
-
const baseWebpackConfig = getBaseWebpackConfig();
|
|
20
|
+
const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
|
|
18
21
|
|
|
19
22
|
const webpackLibConfig = merge(baseWebpackConfig, {
|
|
20
|
-
mode:
|
|
23
|
+
mode: curEnvConfig.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
|
|
21
24
|
output: {
|
|
22
|
-
path:
|
|
25
|
+
path: curEnvConfig.assetsRoot, // 输出文件的存放在本地的目录
|
|
23
26
|
filename: '[name].umd.js',
|
|
24
27
|
publicPath: '',
|
|
25
|
-
library:
|
|
28
|
+
library: curEnvConfig.libraryName, // 指定类库名,主要用于直接引用的方式(比如使用script 标签)
|
|
26
29
|
globalObject: 'this', // 定义全局变量,兼容node和浏览器运行,避免出现"window is not defined"的情况
|
|
27
30
|
libraryTarget: 'umd' // 定义打包方式Universal Module Definition,同时支持在CommonJS、AMD和全局变量使用
|
|
28
31
|
},
|
|
29
32
|
module: {
|
|
30
33
|
rules: utils.styleLoaders({
|
|
31
|
-
sourceMap:
|
|
34
|
+
sourceMap: curEnvConfig.productionSourceMap,
|
|
32
35
|
environment: 'prod'
|
|
33
36
|
})
|
|
34
37
|
},
|
|
35
|
-
devtool:
|
|
36
|
-
externals: config.webpack.
|
|
38
|
+
devtool: curEnvConfig.productionSourceMap ? '#source-map' : false, // '#source-map': 源码,false:压缩代码
|
|
39
|
+
externals: config.webpack.ignoreNodeModules
|
|
40
|
+
? [nodeExternals()].concat(config.webpack.externals)
|
|
41
|
+
: config.webpack.externals,
|
|
37
42
|
plugins: [
|
|
38
43
|
new webpack.DefinePlugin({
|
|
39
|
-
'process.env.NODE_ENV': JSON.stringify(
|
|
44
|
+
'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV)
|
|
40
45
|
}),
|
|
41
46
|
new MiniCssExtractPlugin({
|
|
42
|
-
filename: utils.assetsPath('index.css'),
|
|
47
|
+
// filename: utils.assetsPath('index.css'),
|
|
48
|
+
filename: "[name].css",
|
|
49
|
+
chunkFilename: "[id].css",
|
|
43
50
|
ignoreOrder: false
|
|
44
51
|
}),
|
|
45
52
|
new OptimizeCSSPlugin({
|
|
@@ -53,10 +60,10 @@ module.exports = () => {
|
|
|
53
60
|
});
|
|
54
61
|
|
|
55
62
|
// 是否开启Gzip
|
|
56
|
-
if (
|
|
63
|
+
if (curEnvConfig.productionGzip) {
|
|
57
64
|
webpackLibConfig.plugins.push(
|
|
58
65
|
new CompressionWebpackPlugin({
|
|
59
|
-
test: new RegExp(`\\.(${
|
|
66
|
+
test: new RegExp(`\\.(${curEnvConfig.productionGzipExtensions.join('|')})$`),
|
|
60
67
|
filename: '[path].gz[query]',
|
|
61
68
|
algorithm: 'gzip',
|
|
62
69
|
threshold: 240,
|
|
@@ -65,13 +72,13 @@ module.exports = () => {
|
|
|
65
72
|
);
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
if (
|
|
75
|
+
if (curEnvConfig.bundleAnalyzerReport) {
|
|
69
76
|
webpackLibConfig.plugins.push(new BundleAnalyzerPlugin());
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
// 集成构建入口相关的配置
|
|
73
|
-
if (
|
|
74
|
-
webpackLibConfig.entry =
|
|
80
|
+
if (curEnvConfig.entry) {
|
|
81
|
+
webpackLibConfig.entry = curEnvConfig.entry; // 会覆盖config.webpack.entry的配置
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
return webpackLibConfig;
|
|
@@ -10,6 +10,7 @@ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPl
|
|
|
10
10
|
const CompressionWebpackPlugin = require('compression-webpack-plugin');
|
|
11
11
|
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
|
|
12
12
|
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
|
13
|
+
const nodeExternals = require('webpack-node-externals');
|
|
13
14
|
|
|
14
15
|
const utils = require('./loaderUtils');
|
|
15
16
|
const { resolve } = require('../utils/pathUtils'); // 统一路径解析
|
|
@@ -17,12 +18,14 @@ const getJsEntries = require('../utils/jsEntries');
|
|
|
17
18
|
const entrys2htmlWebpackPlugin = require('../utils/entrys2htmlWebpackPlugin');
|
|
18
19
|
const { isArray } = require('../utils/typeof');
|
|
19
20
|
// 引入当前项目配置文件
|
|
20
|
-
const
|
|
21
|
+
const projectConfig = require('../config/index');
|
|
21
22
|
const getBaseWebpackConfig = require('./webpack.base.conf');
|
|
22
23
|
|
|
23
|
-
module.exports = () => {
|
|
24
|
+
module.exports = (akfunConfig) => {
|
|
25
|
+
let config = akfunConfig || projectConfig; // 默认使用执行命令目录下的配置数据
|
|
26
|
+
const curEnvConfig = config.build || {}; // 当前执行环境配置
|
|
24
27
|
// 获取webpack基本配置
|
|
25
|
-
const baseWebpackConfig = getBaseWebpackConfig();
|
|
28
|
+
const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
|
|
26
29
|
// 获取页面模板地址
|
|
27
30
|
let curHtmlTemplate = path.resolve(__dirname, '../initData/template/index.html');
|
|
28
31
|
if (config.webpack.template) {
|
|
@@ -30,21 +33,32 @@ module.exports = () => {
|
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
const webpackProdConfig = merge(baseWebpackConfig, {
|
|
33
|
-
mode:
|
|
36
|
+
mode: curEnvConfig.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
|
|
37
|
+
/*
|
|
38
|
+
内置变量列表:
|
|
39
|
+
id: chunk的唯一标识,从0开始;
|
|
40
|
+
name: chunk的名称;
|
|
41
|
+
hash: chunk的唯一标识的Hash值;
|
|
42
|
+
chunkhash: chunk内容的Hash值;
|
|
43
|
+
其中hash和chunkhash的长度是可以指定的,[hash:8]代表取8位的Hash值,默认是20位。
|
|
44
|
+
*/
|
|
34
45
|
output: {
|
|
35
|
-
path:
|
|
36
|
-
publicPath:
|
|
46
|
+
path: curEnvConfig.assetsRoot, // 输出文件的存放在本地的目录
|
|
47
|
+
publicPath: curEnvConfig.assetsPublicPath, // 引用地址:配置发布到线上资源的URL前缀
|
|
37
48
|
filename: utils.assetsPath('scripts/chunk/[name].[contenthash:8].js'),
|
|
38
49
|
chunkFilename: utils.assetsPath('scripts/chunk/[name].[contenthash:8].js')
|
|
39
50
|
},
|
|
40
51
|
module: {
|
|
41
52
|
rules: utils.styleLoaders({
|
|
42
|
-
sourceMap:
|
|
53
|
+
sourceMap: curEnvConfig.productionSourceMap,
|
|
43
54
|
environment: 'prod'
|
|
44
55
|
})
|
|
45
56
|
},
|
|
57
|
+
externals: config.webpack.ignoreNodeModules
|
|
58
|
+
? [nodeExternals()].concat(config.webpack.externals)
|
|
59
|
+
: config.webpack.externals,
|
|
46
60
|
// devtool: '#cheap-module-eval-source-map', // 本地开发环境中的取值
|
|
47
|
-
devtool:
|
|
61
|
+
devtool: curEnvConfig.productionSourceMap ? '#source-map' : false, // 线上开发环境中的取值
|
|
48
62
|
optimization: {
|
|
49
63
|
splitChunks: {
|
|
50
64
|
cacheGroups: {
|
|
@@ -67,7 +81,7 @@ module.exports = () => {
|
|
|
67
81
|
plugins: [
|
|
68
82
|
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
|
69
83
|
new webpack.DefinePlugin({
|
|
70
|
-
'process.env.NODE_ENV': JSON.stringify(
|
|
84
|
+
'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV) // vue-router中根据此变量判断执行环境
|
|
71
85
|
}),
|
|
72
86
|
new MiniCssExtractPlugin({
|
|
73
87
|
filename: utils.assetsPath('css/[name].[contenthash:8].css'),
|
|
@@ -94,9 +108,9 @@ module.exports = () => {
|
|
|
94
108
|
});
|
|
95
109
|
|
|
96
110
|
// 集成build配置中的构建入口
|
|
97
|
-
if (
|
|
111
|
+
if (curEnvConfig.entry) {
|
|
98
112
|
// 会覆盖config.webpack.entry的配置
|
|
99
|
-
webpackProdConfig.entry =
|
|
113
|
+
webpackProdConfig.entry = curEnvConfig.entry;
|
|
100
114
|
}
|
|
101
115
|
|
|
102
116
|
// 多页面支持能力
|
|
@@ -143,7 +157,7 @@ module.exports = () => {
|
|
|
143
157
|
patterns: [
|
|
144
158
|
{
|
|
145
159
|
from: resolve('public'), // 从这里拷贝
|
|
146
|
-
to:
|
|
160
|
+
to: curEnvConfig.assetsSubDirectory // 将根目录下的public内的资源复制到指定文件夹
|
|
147
161
|
}
|
|
148
162
|
]
|
|
149
163
|
})
|
|
@@ -151,10 +165,10 @@ module.exports = () => {
|
|
|
151
165
|
}
|
|
152
166
|
|
|
153
167
|
// 是否要进行压缩工作
|
|
154
|
-
if (
|
|
168
|
+
if (curEnvConfig.productionGzip) {
|
|
155
169
|
webpackProdConfig.plugins.push(
|
|
156
170
|
new CompressionWebpackPlugin({
|
|
157
|
-
test: new RegExp(`\\.(${
|
|
171
|
+
test: new RegExp(`\\.(${curEnvConfig.productionGzipExtensions.join('|')})$`),
|
|
158
172
|
filename: '[path].gz[query]',
|
|
159
173
|
algorithm: 'gzip',
|
|
160
174
|
threshold: 240,
|
|
@@ -163,7 +177,7 @@ module.exports = () => {
|
|
|
163
177
|
);
|
|
164
178
|
}
|
|
165
179
|
|
|
166
|
-
if (
|
|
180
|
+
if (curEnvConfig.bundleAnalyzerReport) {
|
|
167
181
|
webpackProdConfig.plugins.push(new BundleAnalyzerPlugin());
|
|
168
182
|
}
|
|
169
183
|
|