UNPKG

7.19 kBJavaScriptView Raw
1'use strict'
2
3const fs = require('fs')
4const webpack = require('webpack')
5const merge = require('webpack-merge')
6const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
7const CopyWebpackPlugin = require('copy-webpack-plugin-hash')
8const { SinaHybridPlugin } = require('../libs/hybrid')
9const HtmlWebpackPlugin = require('sina-html-webpack-plugin')
10const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
11
12const config = require('../config')
13const { banner, rootPath } = require('../libs/utils')
14
15const maraConf = require(config.paths.marauder)
16const shouldUseSourceMap = !!maraConf.sourceMap
17
18function getLibraryConf() {
19 const pkgName = require(config.paths.packageJson).name
20
21 return pkgName
22}
23
24module.exports = function({ entry, cmd }) {
25 const distPageDir = `${config.paths.dist}/${entry}`
26 const baseWebpackConfig = require('./webpack.base.conf')(entry, 'mc')
27 const hasHtml = fs.existsSync(`${config.paths.page}/${entry}/index.html`)
28
29 const webpackConfig = merge(baseWebpackConfig, {
30 // 在第一个错误出错时抛出,而不是无视错误
31 bail: true,
32 // entry: getEntries(`src/view/${entry}/index.@(ts|js)`),
33 devtool: shouldUseSourceMap ? 'source-map' : false,
34 output: {
35 path: distPageDir,
36 publicPath: config.build.assetsPublicPath,
37 filename: maraConf.hash
38 ? 'static/js/[name].[chunkhash:8].min.js'
39 : 'static/js/[name].min.js',
40 library: entry,
41 // https://doc.webpack-china.org/configuration/output/#output-librarytarget
42 libraryTarget: 'umd'
43 },
44 plugins: [
45 new webpack.DefinePlugin(config.build.env.stringified),
46 new UglifyJsPlugin({
47 uglifyOptions: {
48 ecma: 5,
49 compress: {
50 warnings: false,
51 // Disabled because of an issue with Uglify breaking seemingly valid code:
52 // https://github.com/facebook/create-react-app/issues/2376
53 // Pending further investigation:
54 // https://github.com/mishoo/UglifyJS2/issues/2011
55 comparisons: false
56 },
57 mangle: {
58 safari10: true
59 },
60 output: {
61 comments: false,
62 // Turned on because emoji and regex is not minified properly using default
63 // https://github.com/facebook/create-react-app/issues/2488
64 ascii_only: true
65 }
66 },
67 // Use multi-process parallel running to improve the build speed
68 // Default number of concurrent runs: os.cpus().length - 1
69 parallel: true,
70 // Enable file caching
71 cache: true,
72 sourceMap: shouldUseSourceMap
73 }),
74 new webpack.BannerPlugin({
75 banner: banner(), // 其值为字符串,将作为注释存在
76 entryOnly: true // 如果值为 true,将只在入口 chunks 文件中添加
77 }),
78 new OptimizeCssAssetsPlugin({
79 // cssnano 中自带 autoprefixer,在压缩时会根据配置去除无用前缀
80 // 为保持统一,将其禁用,在 4.0 版本后将会默认禁用
81 // safe: true 禁止计算 z-index
82 cssProcessorOptions: Object.assign(
83 { autoprefixer: false, safe: true },
84 shouldUseSourceMap
85 ? {
86 map: { inline: false }
87 }
88 : {}
89 ),
90 canPrint: false // 不显示通知
91 }),
92 // Moment.js is an extremely popular library that bundles large locale files
93 // by default due to how Webpack interprets its code. This is a practical
94 // solution that requires the user to opt into importing specific locales.
95 // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
96 // You can remove this if you don't use Moment.js:
97 new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
98 hasHtml &&
99 new HtmlWebpackPlugin({
100 // 生成出来的html文件名
101 filename: rootPath(`dist/${entry}/index.html`),
102 // 每个html的模版,这里多个页面使用同一个模版
103 template: `${config.paths.page}/${entry}/index.html`,
104 minify: false,
105 // 自动将引用插入html
106 inject: true,
107 collapseWhitespace: true,
108 removeRedundantAttributes: true,
109 useShortDoctype: true,
110 removeEmptyAttributes: true,
111 removeStyleLinkTypeAttributes: true,
112 keepClosingSlash: true
113 }),
114 // 确保在 copy Files 之前
115 maraConf.hybrid && new SinaHybridPlugin({ entry }),
116 ...copyPublicFiles(entry, distPageDir)
117 ].filter(Boolean)
118 })
119
120 function copyPublicFiles(entry, distPageDir) {
121 const pagePublicDir = rootPath(`${config.paths.page}/${entry}/public`)
122 const plugins = []
123
124 function getCopyOption(src) {
125 return {
126 from: src,
127 // 放置于根路径
128 to: distPageDir,
129 ignore: ['.*']
130 }
131 }
132
133 // 全局 public
134 if (fs.existsSync(config.paths.public)) {
135 plugins.push(new CopyWebpackPlugin([getCopyOption(config.paths.public)]))
136 }
137
138 // 页面级 public,能够覆盖全局 public
139 if (fs.existsSync(pagePublicDir)) {
140 plugins.push(new CopyWebpackPlugin([getCopyOption(pagePublicDir)]))
141 }
142
143 return plugins
144 }
145
146 // 重要:确保 zip plugin 在插件列表末尾
147 if (maraConf.zip === true || maraConf.hybrid) {
148 const ZipPlugin = require('zip-webpack-plugin')
149 webpackConfig.plugins.push(
150 new ZipPlugin({
151 // OPTIONAL: defaults to the Webpack output filename (above) or,
152 // if not present, the basename of the path
153 filename: entry,
154 // OPTIONAL: defaults to 'zip'
155 // the file extension to use instead of 'zip'
156 // 对 hybrid 项目使用 php 后缀,防止 CDN 劫持(?)
157 extension: maraConf.hybrid ? 'php' : 'zip',
158 // OPTIONAL: defaults to including everything
159 // can be a string, a RegExp, or an array of strings and RegExps
160 // include: [/\.js$/],
161 // OPTIONAL: defaults to excluding nothing
162 // can be a string, a RegExp, or an array of strings and RegExps
163 // if a file matches both include and exclude, exclude takes precedence
164 exclude: maraConf.debug
165 ? [
166 /__MACOSX$/,
167 /.DS_Store$/,
168 /dependencyGraph.json$/,
169 /debug.css$/,
170 /build.json$/,
171 /js.map$/,
172 /css.map$/
173 ]
174 : [
175 /__MACOSX$/,
176 /.DS_Store$/,
177 /dependencyGraph.json$/,
178 /debug.js$/,
179 /debug.css$/,
180 /build.json$/,
181 /js.map$/,
182 /css.map$/
183 ],
184
185 // yazl Options
186 // OPTIONAL: see https://github.com/thejoshwolfe/yazl#addfilerealpath-metadatapath-options
187 fileOptions: {
188 mtime: new Date(),
189 mode: 0o100664,
190 compress: true,
191 forceZip64Format: false
192 },
193 // OPTIONAL: see https://github.com/thejoshwolfe/yazl#endoptions-finalsizecallback
194 zipOptions: {
195 forceZip64Format: false
196 }
197 })
198 )
199 }
200
201 return webpackConfig
202}