akfun 1.5.13 → 1.5.15

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 CHANGED
@@ -1,13 +1,14 @@
1
1
  # AKFun 前端脚手架
2
2
  > AKFun 是一个基于 Webpack4.0 和 rollup 的前端多场景打包工具,支持多种技术栈:Vue技术栈、React技术栈、React&TS技术栈
3
- - 技术栈:node/webpack4.0/rollup/express/babel/eslint/stylelint
3
+ - 核心理念:提供完整&全面的前端工程能力,并尽可能屏蔽掉前端工程相关配置,让开发者更专注业务研发工作。
4
+ - 技术栈:node/webpack4.0/rollup/babel/eslint/stylelint
4
5
 
5
6
  ## 特性
6
7
  - ⚡️ 零配置,开箱即用
7
8
  - 👏 支持Vue和React项目的调试和构建
8
9
  - 📤 支持单页面和多页面
9
- - 💪 提供三种构建场景: 本地开发调试模式(包含热更新、接口代理等功能)、构建生产环境代码、library库的构建(支持umd和esm的打包能力)
10
- - ❤️ 开放配置能力: 可配置构建入口文件、是否开启ESLint代码规范检测、接口代理配置等
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,31 @@ 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. 项目源码环境变量批量替换
249
274
  > [关于params-replace-loader的使用方法](https://www.npmjs.com/package/params-replace-loader)
250
275
  ```bash
251
276
  module.exports = {
@@ -264,7 +289,7 @@ module.exports = {
264
289
  }
265
290
  ```
266
291
 
267
- 7. 接口代理配置:目前只有dev本地开发调试模式下会启动
292
+ 10. 接口代理配置:目前只有dev本地开发调试模式下会启动
268
293
  > [关于proxyTable的配置方法](https://www.webpackjs.com/configuration/dev-server/#devserver-proxy)
269
294
  ```bash
270
295
  module.exports = {
@@ -277,7 +302,7 @@ module.exports = {
277
302
  }
278
303
  ```
279
304
 
280
- 8、用于开启本地调试模式的相关配置信息
305
+ 11. 用于开启本地调试模式的相关配置信息
281
306
  ```bash
282
307
  module.exports = {
283
308
  ...
@@ -301,7 +326,7 @@ module.exports = {
301
326
  }
302
327
  ```
303
328
 
304
- 9、用于构建生产环境代码的相关配置信息
329
+ 12. 用于构建生产环境代码的相关配置信息
305
330
  ```bash
306
331
  module.exports = {
307
332
  ...
@@ -319,7 +344,7 @@ module.exports = {
319
344
  }
320
345
  ```
321
346
 
322
- 10、用于构建第三方功能包的配置(以umd格式输出)
347
+ 13. 用于构建第三方功能包的配置(以umd格式输出)
323
348
  ```bash
324
349
  module.exports = {
325
350
  ...
@@ -338,7 +363,7 @@ module.exports = {
338
363
  }
339
364
  ```
340
365
 
341
- 11、用于构建esm格式的第三方功能包配置
366
+ 14. 用于构建esm格式的第三方功能包配置
342
367
  ```bash
343
368
  module.exports = {
344
369
  ...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akfun",
3
- "version": "1.5.13",
3
+ "version": "1.5.15",
4
4
  "description": "前端脚手架:支持Vue技术栈和react技术栈",
5
5
  "keywords": [
6
6
  "前端工程",
@@ -10,7 +10,7 @@
10
10
  "vue项目脚手架",
11
11
  "lib库构建工具"
12
12
  ],
13
- "author": "ldan@wibetter",
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",
@@ -7,7 +7,7 @@ const getConfigObj = require('../utils/getConfigObj');
7
7
  /** akfun脚手架赋予当前项目的默认配置
8
8
  * 备注:项目根目录的akfun.config.js的配置内容优先级高于defultAKFunConfig
9
9
  */
10
- const defultAKFunConfig = {
10
+ const defaultAKFunConfig = {
11
11
  settings: {
12
12
  enableESLint: false, // 是否开启ESLint,默认开启ESLint检测代码格式
13
13
  enableESLintFix: false, // 是否ESLint自动修正代码格式
@@ -26,6 +26,8 @@ const defultAKFunConfig = {
26
26
  $utils: resolve('src/utils')
27
27
  }
28
28
  },
29
+ createDeclaration: false, // 打包时是否创建ts声明文件
30
+ ignoreNodeModules: false, // 打包时是否忽略 node_modules
29
31
  externals: [], // 从输出的 bundle 中排除依赖
30
32
  sassResources: []
31
33
  },
@@ -99,10 +101,10 @@ const defultAKFunConfig = {
99
101
  };
100
102
 
101
103
  // 从项目根目录获取当前项目的配置文件
102
- const curProjectConfg = getConfigObj(resolve('akfun.config.js'));
104
+ const curProjectConfig = getConfigObj(resolve('akfun.config.js'));
103
105
 
104
- // module.exports = Object.assign(defultAKFunConfig, curProjectConfg);
106
+ // module.exports = Object.assign(defaultAKFunConfig, curProjectConfig);
105
107
 
106
108
  const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
107
109
  // 备注:数组类型则直接覆盖
108
- module.exports = deepMerge(defultAKFunConfig, curProjectConfg, { arrayMerge: overwriteMerge });
110
+ module.exports = deepMerge(defaultAKFunConfig, curProjectConfig, { arrayMerge: overwriteMerge });
@@ -2,7 +2,7 @@ const glob = require('glob');
2
2
 
3
3
  const fileExists = function (fileDir) {
4
4
  let exists = false;
5
- const files = glob.sync(fileDir);
5
+ const files = glob.sync(fileDir); // 同步读取本地文件
6
6
  if (files.length > 0) {
7
7
  exists = true;
8
8
  }
@@ -28,7 +28,12 @@ const BannerPack = new webpack.BannerPlugin({
28
28
  entryOnly: true // 只在入口 chunks 文件中添加
29
29
  });
30
30
 
31
- module.exports = () => {
31
+ /**
32
+ * webpack.base.conf.js
33
+ * 主要用于设置 rules 和 通用插件
34
+ */
35
+ module.exports = (option) => {
36
+ const curEnvConfig = option || {}; // 用于接收当前运行环境配置变量
32
37
  const webpackConfig = {
33
38
  entry: config.webpack.entry,
34
39
  /*
@@ -66,8 +71,14 @@ module.exports = () => {
66
71
  options: babelConfig
67
72
  },
68
73
  {
69
- loader: 'ts-loader'
70
- // options: { configFile: path.resolve(__dirname, '../config/tsconfig.json') }
74
+ loader: 'ts-loader',
75
+ options: {
76
+ // configFile: path.resolve(__dirname, '../config/tsconfig.json')
77
+ compilerOptions: {
78
+ declaration: config.webpack.createDeclaration || false,
79
+ outDir: curEnvConfig.assetsRoot || './dist'
80
+ }
81
+ }
71
82
  }
72
83
  ],
73
84
  include: [resolve('src')],
@@ -135,7 +146,6 @@ module.exports = () => {
135
146
  new VueLoaderPlugin()
136
147
  ]
137
148
  };
138
-
139
149
  // 是否开启ESLint
140
150
  if (config.settings.enableESLint) {
141
151
  // ts类型
@@ -13,8 +13,9 @@ const entrys2htmlWebpackPlugin = require('../utils/entrys2htmlWebpackPlugin');
13
13
  const { isArray } = require('../utils/typeof');
14
14
 
15
15
  module.exports = () => {
16
+ const curEnvConfig = config.dev || {}; // 当前执行环境配置
16
17
  // 获取webpack基本配置
17
- const baseWebpackConfig = getBaseWebpackConfig();
18
+ const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
18
19
 
19
20
  // 获取页面模板地址
20
21
  let curHtmlTemplate = path.resolve(__dirname, '../initData/template/index.html');
@@ -23,21 +24,21 @@ module.exports = () => {
23
24
  }
24
25
 
25
26
  const webpackDevConfig = merge(baseWebpackConfig, {
26
- mode: config.dev.NODE_ENV, // development模式,会启动NamedChunksPlugin、NamedModulesPlugin服务
27
+ mode: curEnvConfig.NODE_ENV, // development模式,会启动NamedChunksPlugin、NamedModulesPlugin服务
27
28
  output: {
28
- publicPath: config.dev.assetsPublicPath // 引用地址:配置发布到线上资源的URL前缀
29
+ publicPath: curEnvConfig.assetsPublicPath // 引用地址:配置发布到线上资源的URL前缀
29
30
  },
30
31
  module: {
31
32
  rules: utils.styleLoaders({
32
- sourceMap: config.dev.cssSourceMap,
33
+ sourceMap: curEnvConfig.cssSourceMap,
33
34
  environment: 'dev'
34
35
  })
35
36
  },
36
37
  // cheap-module-eval-source-map is faster for development
37
- devtool: '#cheap-module-eval-source-map',
38
+ devtool: '#source-map', // '#cheap-module-eval-source-map',
38
39
  plugins: [
39
40
  new webpack.DefinePlugin({
40
- 'process.env.NODE_ENV': JSON.stringify(config.dev.NODE_ENV) // vue-router中根据此变量判断执行环境
41
+ 'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV) // vue-router中根据此变量判断执行环境
41
42
  }),
42
43
  // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
43
44
  new webpack.HotModuleReplacementPlugin(),
@@ -48,8 +49,8 @@ module.exports = () => {
48
49
  });
49
50
 
50
51
  // 集成dev配置中的构建入口(优先级高于config.webpack.entry)
51
- if (config.dev.entry) {
52
- webpackDevConfig.entry = config.dev.entry; // 备注:会覆盖config.webpack.entry的配置
52
+ if (curEnvConfig.entry) {
53
+ webpackDevConfig.entry = curEnvConfig.entry; // 备注:会覆盖config.webpack.entry的配置
53
54
  }
54
55
 
55
56
  // 多页面多模板支持能力
@@ -6,6 +6,7 @@ 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
  // 引入当前项目配置文件
@@ -13,30 +14,33 @@ const config = require('../config/index');
13
14
  const getBaseWebpackConfig = require('./webpack.base.conf');
14
15
 
15
16
  module.exports = () => {
17
+ const curEnvConfig = config.build2lib || {}; // 当前执行环境配置
16
18
  // 获取webpack基本配置
17
- const baseWebpackConfig = getBaseWebpackConfig();
19
+ const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
18
20
 
19
21
  const webpackLibConfig = merge(baseWebpackConfig, {
20
- mode: config.build2lib.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
22
+ mode: curEnvConfig.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
21
23
  output: {
22
- path: config.build2lib.assetsRoot, // 输出文件的存放在本地的目录
24
+ path: curEnvConfig.assetsRoot, // 输出文件的存放在本地的目录
23
25
  filename: '[name].umd.js',
24
26
  publicPath: '',
25
- library: config.build2lib.libraryName, // 指定类库名,主要用于直接引用的方式(比如使用script 标签)
27
+ library: curEnvConfig.libraryName, // 指定类库名,主要用于直接引用的方式(比如使用script 标签)
26
28
  globalObject: 'this', // 定义全局变量,兼容node和浏览器运行,避免出现"window is not defined"的情况
27
29
  libraryTarget: 'umd' // 定义打包方式Universal Module Definition,同时支持在CommonJS、AMD和全局变量使用
28
30
  },
29
31
  module: {
30
32
  rules: utils.styleLoaders({
31
- sourceMap: config.build2lib.productionSourceMap,
33
+ sourceMap: curEnvConfig.productionSourceMap,
32
34
  environment: 'prod'
33
35
  })
34
36
  },
35
- devtool: config.build2lib.productionSourceMap ? '#source-map' : false, // '#source-map': 源码,false:压缩代码
36
- externals: config.webpack.externals,
37
+ devtool: curEnvConfig.productionSourceMap ? '#source-map' : false, // '#source-map': 源码,false:压缩代码
38
+ externals: config.webpack.ignoreNodeModules
39
+ ? [nodeExternals()].concat(config.webpack.externals)
40
+ : config.webpack.externals,
37
41
  plugins: [
38
42
  new webpack.DefinePlugin({
39
- 'process.env.NODE_ENV': JSON.stringify(config.build2lib.NODE_ENV)
43
+ 'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV)
40
44
  }),
41
45
  new MiniCssExtractPlugin({
42
46
  filename: utils.assetsPath('index.css'),
@@ -53,10 +57,10 @@ module.exports = () => {
53
57
  });
54
58
 
55
59
  // 是否开启Gzip
56
- if (config.build2lib.productionGzip) {
60
+ if (curEnvConfig.productionGzip) {
57
61
  webpackLibConfig.plugins.push(
58
62
  new CompressionWebpackPlugin({
59
- test: new RegExp(`\\.(${config.build2lib.productionGzipExtensions.join('|')})$`),
63
+ test: new RegExp(`\\.(${curEnvConfig.productionGzipExtensions.join('|')})$`),
60
64
  filename: '[path].gz[query]',
61
65
  algorithm: 'gzip',
62
66
  threshold: 240,
@@ -65,13 +69,13 @@ module.exports = () => {
65
69
  );
66
70
  }
67
71
 
68
- if (config.build2lib.bundleAnalyzerReport) {
72
+ if (curEnvConfig.bundleAnalyzerReport) {
69
73
  webpackLibConfig.plugins.push(new BundleAnalyzerPlugin());
70
74
  }
71
75
 
72
76
  // 集成构建入口相关的配置
73
- if (config.build2lib.entry) {
74
- webpackLibConfig.entry = config.build2lib.entry; // 会覆盖config.webpack.entry的配置
77
+ if (curEnvConfig.entry) {
78
+ webpackLibConfig.entry = curEnvConfig.entry; // 会覆盖config.webpack.entry的配置
75
79
  }
76
80
 
77
81
  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'); // 统一路径解析
@@ -21,8 +22,9 @@ const config = require('../config/index');
21
22
  const getBaseWebpackConfig = require('./webpack.base.conf');
22
23
 
23
24
  module.exports = () => {
25
+ const curEnvConfig = config.build || {}; // 当前执行环境配置
24
26
  // 获取webpack基本配置
25
- const baseWebpackConfig = getBaseWebpackConfig();
27
+ const baseWebpackConfig = getBaseWebpackConfig(curEnvConfig);
26
28
  // 获取页面模板地址
27
29
  let curHtmlTemplate = path.resolve(__dirname, '../initData/template/index.html');
28
30
  if (config.webpack.template) {
@@ -30,21 +32,32 @@ module.exports = () => {
30
32
  }
31
33
 
32
34
  const webpackProdConfig = merge(baseWebpackConfig, {
33
- mode: config.build2lib.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
35
+ mode: curEnvConfig.NODE_ENV, // production 模式,会启动UglifyJsPlugin服务
36
+ /*
37
+ 内置变量列表:
38
+ id: chunk的唯一标识,从0开始;
39
+ name: chunk的名称;
40
+ hash: chunk的唯一标识的Hash值;
41
+ chunkhash: chunk内容的Hash值;
42
+ 其中hash和chunkhash的长度是可以指定的,[hash:8]代表取8位的Hash值,默认是20位。
43
+ */
34
44
  output: {
35
- path: config.build.assetsRoot, // 输出文件的存放在本地的目录
36
- publicPath: config.build.assetsPublicPath, // 引用地址:配置发布到线上资源的URL前缀
45
+ path: curEnvConfig.assetsRoot, // 输出文件的存放在本地的目录
46
+ publicPath: curEnvConfig.assetsPublicPath, // 引用地址:配置发布到线上资源的URL前缀
37
47
  filename: utils.assetsPath('scripts/chunk/[name].[contenthash:8].js'),
38
48
  chunkFilename: utils.assetsPath('scripts/chunk/[name].[contenthash:8].js')
39
49
  },
40
50
  module: {
41
51
  rules: utils.styleLoaders({
42
- sourceMap: config.build.productionSourceMap,
52
+ sourceMap: curEnvConfig.productionSourceMap,
43
53
  environment: 'prod'
44
54
  })
45
55
  },
56
+ externals: config.webpack.ignoreNodeModules
57
+ ? [nodeExternals()].concat(config.webpack.externals)
58
+ : config.webpack.externals,
46
59
  // devtool: '#cheap-module-eval-source-map', // 本地开发环境中的取值
47
- devtool: config.build.productionSourceMap ? '#source-map' : false, // 线上开发环境中的取值
60
+ devtool: curEnvConfig.productionSourceMap ? '#source-map' : false, // 线上开发环境中的取值
48
61
  optimization: {
49
62
  splitChunks: {
50
63
  cacheGroups: {
@@ -67,7 +80,7 @@ module.exports = () => {
67
80
  plugins: [
68
81
  // http://vuejs.github.io/vue-loader/en/workflow/production.html
69
82
  new webpack.DefinePlugin({
70
- 'process.env.NODE_ENV': JSON.stringify(config.build.NODE_ENV) // vue-router中根据此变量判断执行环境
83
+ 'process.env.NODE_ENV': JSON.stringify(curEnvConfig.NODE_ENV) // vue-router中根据此变量判断执行环境
71
84
  }),
72
85
  new MiniCssExtractPlugin({
73
86
  filename: utils.assetsPath('css/[name].[contenthash:8].css'),
@@ -94,9 +107,9 @@ module.exports = () => {
94
107
  });
95
108
 
96
109
  // 集成build配置中的构建入口
97
- if (config.build.entry) {
110
+ if (curEnvConfig.entry) {
98
111
  // 会覆盖config.webpack.entry的配置
99
- webpackProdConfig.entry = config.build.entry;
112
+ webpackProdConfig.entry = curEnvConfig.entry;
100
113
  }
101
114
 
102
115
  // 多页面支持能力
@@ -143,7 +156,7 @@ module.exports = () => {
143
156
  patterns: [
144
157
  {
145
158
  from: resolve('public'), // 从这里拷贝
146
- to: config.build.assetsSubDirectory // 将根目录下的public内的资源复制到指定文件夹
159
+ to: curEnvConfig.assetsSubDirectory // 将根目录下的public内的资源复制到指定文件夹
147
160
  }
148
161
  ]
149
162
  })
@@ -151,10 +164,10 @@ module.exports = () => {
151
164
  }
152
165
 
153
166
  // 是否要进行压缩工作
154
- if (config.build.productionGzip) {
167
+ if (curEnvConfig.productionGzip) {
155
168
  webpackProdConfig.plugins.push(
156
169
  new CompressionWebpackPlugin({
157
- test: new RegExp(`\\.(${config.build.productionGzipExtensions.join('|')})$`),
170
+ test: new RegExp(`\\.(${curEnvConfig.productionGzipExtensions.join('|')})$`),
158
171
  filename: '[path].gz[query]',
159
172
  algorithm: 'gzip',
160
173
  threshold: 240,
@@ -163,7 +176,7 @@ module.exports = () => {
163
176
  );
164
177
  }
165
178
 
166
- if (config.build.bundleAnalyzerReport) {
179
+ if (curEnvConfig.bundleAnalyzerReport) {
167
180
  webpackProdConfig.plugins.push(new BundleAnalyzerPlugin());
168
181
  }
169
182