1 |
|
2 |
|
3 | const webpack = require('webpack')
|
4 | const merge = require('webpack-merge')
|
5 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
6 | const TerserPlugin = require('terser-webpack-plugin')
|
7 | const safePostCssParser = require('postcss-safe-parser')
|
8 | const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
9 |
|
10 | const config = require('../config')
|
11 | const { GLOB } = require('../config/const')
|
12 | const { getLibraryExportName } = require('../lib/getLibraryExportName')
|
13 | const { banner, getEntries } = require('../lib/utils')
|
14 | const shouldUseSourceMap = config.build.sourceMap
|
15 |
|
16 | /**
|
17 | * 生成生产配置
|
18 | * @param {String} options lib 打包配置
|
19 | * @param {String} context 构建上下文
|
20 | * @return {Object} webpack 配置对象
|
21 | */
|
22 | module.exports = function(options, context) {
|
23 | const baseWebpackConfig = require('./webpack.base.conf')(context, 'lib')
|
24 | const { name: pkgName, version: pkgVersion } = require(config.paths
|
25 | .packageJson)
|
26 |
|
27 | // 优先取外部注入的 version
|
28 | const buildVersion = context.version || pkgVersion
|
29 | const libraryName = getLibraryExportName(
|
30 | options.format,
|
31 | config.library || pkgName
|
32 | )
|
33 |
|
34 | const webpackConfig = merge(baseWebpackConfig, {
|
35 | mode: options.mode || 'production',
|
36 | // 在第一个错误出错时抛出,而不是无视错误
|
37 | bail: true,
|
38 | entry: getEntries(GLOB.LIB_ENTRY),
|
39 | devtool: shouldUseSourceMap ? 'source-map' : false,
|
40 | output: {
|
41 | path: config.paths.lib,
|
42 | filename: options.filename,
|
43 | library: libraryName,
|
44 | // https://doc.webpack-china.org/configuration/output/#output-librarytarget
|
45 | libraryTarget: options.format
|
46 | },
|
47 | optimization: {
|
48 | minimizer: [
|
49 | options.minify &&
|
50 | new TerserPlugin({
|
51 | terserOptions: {
|
52 | parse: {
|
53 | // we want terser to parse ecma 8 code. However, we don't want it
|
54 | // to apply any minfication steps that turns valid ecma 5 code
|
55 | // into invalid ecma 5 code. This is why the 'compress' and 'output'
|
56 | // sections only apply transformations that are ecma 5 safe
|
57 | // https://github.com/facebook/create-react-app/pull/4234
|
58 | ecma: 8
|
59 | },
|
60 | compress: {
|
61 | ecma: 5,
|
62 | warnings: false,
|
63 | // Disabled because of an issue with Uglify breaking seemingly valid code:
|
64 | // https://github.com/facebook/create-react-app/issues/2376
|
65 | // Pending further investigation:
|
66 | // https://github.com/mishoo/UglifyJS2/issues/2011
|
67 | comparisons: false,
|
68 | // Disabled because of an issue with Terser breaking valid code:
|
69 | // https://github.com/facebook/create-react-app/issues/5250
|
70 | // Pending futher investigation:
|
71 | // https://github.com/terser-js/terser/issues/120
|
72 | inline: 2
|
73 | },
|
74 | mangle: {
|
75 | safari10: true
|
76 | },
|
77 | output: {
|
78 | ecma: 5,
|
79 | comments: false,
|
80 | // Turned on because emoji and regex is not minified properly using default
|
81 | // https://github.com/facebook/create-react-app/issues/2488
|
82 | ascii_only: true
|
83 | }
|
84 | },
|
85 | // Use multi-process parallel running to improve the build speed
|
86 | // Default number of concurrent runs: os.cpus().length - 1
|
87 | parallel: true,
|
88 | // Enable file caching
|
89 | cache: true,
|
90 | sourceMap: shouldUseSourceMap
|
91 | }),
|
92 | new OptimizeCSSAssetsPlugin({
|
93 | cssProcessorOptions: {
|
94 | parser: safePostCssParser,
|
95 | map: shouldUseSourceMap
|
96 | ? {
|
97 | // `inline: false` forces the sourcemap to be output into a
|
98 | // separate file
|
99 | inline: false,
|
100 | // `annotation: true` appends the sourceMappingURL to the end of
|
101 | // the css file, helping the browser find the sourcemap
|
102 | annotation: true
|
103 | }
|
104 | : false
|
105 | },
|
106 | canPrint: false // 不显示通知
|
107 | })
|
108 | ].filter(Boolean)
|
109 | },
|
110 | plugins: [
|
111 | new webpack.BannerPlugin({
|
112 | banner: banner(buildVersion), // 其值为字符串,将作为注释存在
|
113 | entryOnly: true // 如果值为 true,将只在入口 chunks 文件中添加
|
114 | }),
|
115 | new MiniCssExtractPlugin({
|
116 | filename: options.minify ? 'style.min.css' : 'style.css'
|
117 | })
|
118 | ].filter(Boolean),
|
119 | // lib 打包排除第三方库
|
120 | externals: {
|
121 | jquery: 'jQuery',
|
122 | vue: 'Vue',
|
123 | zepto: 'Zepto',
|
124 | react: 'React',
|
125 | 'react-dom': 'ReactDom'
|
126 | }
|
127 | })
|
128 |
|
129 | return webpackConfig
|
130 | }
|