阅读webpack代码笔记:antd-layout的webpack.config.prod.js

  1 'use strict';
  2 
  3 const autoprefixer = require('autoprefixer');//自动补全css前缀
  4 const path = require('path');
  5 const webpack = require('webpack');
  6 //自动生成带有入口文件引用的index.html
  7 const HtmlWebpackPlugin = require('html-webpack-plugin');
  8 //ExtractTextPlugin将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件
  9 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 10 //ManifestPlugin用于生成manifest.json
 11 const ManifestPlugin = require('webpack-manifest-plugin');
 12 //InterpolateHtmlPlugin:和HtmlWebpackPlugin串行使用,允许在index.html中添加变量
 13 const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
 14 //用于使用service worker来缓存外部项目依赖项。 它将使用sw-precache生成service worker文件并将其添加到您的构建目录
 15 const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
 16 const eslintFormatter = require('react-dev-utils/eslintFormatter');
 17 const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
 18 const paths = require('./paths'); //获取paths对象
 19 const getClientEnvironment = require('./env');
 20 
 21 // Webpack uses `publicPath` to determine where the app is being served from.
 22 // It requires a trailing slash, or the file assets will get an incorrect path.
 23 const publicPath = paths.servedPath; //package.json所在的路径
 24 // Some apps do not use client-side routing with pushState.
 25 // For these, "homepage" can be set to "." to enable relative asset paths.
 26 const shouldUseRelativeAssetPaths = publicPath === './';
 27 // Source maps are resource heavy and can cause out of memory issue for large source files.
 28 const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
 29 // `publicUrl` is just like `publicPath`, but we will provide it to our app
 30 // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
 31 // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
 32 const publicUrl = publicPath.slice(0, -1);
 33 // Get environment variables to inject into our app.
 34 const env = getClientEnvironment(publicUrl);
 35 
 36 // Assert this just to be safe.
 37 // Development builds of React are slow and not intended for production.
 38 if (env.stringified['process.env'].NODE_ENV !== '"production"') {
 39     throw new Error('Production builds must have NODE_ENV=production.');
 40 }
 41 
 42 // Note: defined here because it will be used more than once.
 43 const cssFilename = 'static/css/[name].[contenthash:8].css';
 44 
 45 // ExtractTextPlugin expects the build output to be flat.
 46 // (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
 47 // However, our output is structured with css, js and media folders.
 48 // To have this structure working with relative paths, we have to use custom options.
 49 const extractTextPluginOptions = shouldUseRelativeAssetPaths
 50         ? // Making sure that the publicPath goes back to to build folder.
 51         { publicPath: Array(cssFilename.split('/').length).join('../') }
 52         : {};
 53  
 54 // This is the production configuration.
 55 // It compiles slowly and is focused on producing a fast and minimal bundle.
 56 // The development configuration is different and lives in a separate file.
 57  
 58 
 59 module.exports = {
 60     // Don't attempt to continue if there are any errors.
 61     bail: true,
 62     // We generate sourcemaps in production. This is slow but gives good results.
 63     // You can exclude the *.map files from the build during deployment.
 64     devtool: shouldUseSourceMap ? 'source-map' : false,
 65     // In production, we only want to load the polyfills and the app code.
 66     entry:{        // require.resolve('./polyfills'), 
 67         //paths.appIndexJs , 
 68         app:paths.appIndexJs , //src/index.js
 69         vendor:[ //把引用react的类提取出公共模块
 70           'react',
 71           'react-dom',
 72           'react-router'
 73         ],
 74         antd:[ //提取ant到公共模块
 75            'antd/lib/button',
 76            'antd/lib/icon'
 77          //'antd'
 78         ]
 79     },
 80     output: {
 81         // The build folder.
 82         path: paths.appBuild,
 83         // Generated JS file names (with nested folders).
 84         // There will be one main bundle, and one file per asynchronous chunk.
 85         // We don't currently advertise code splitting but Webpack supports it.
 86         filename: 'static/js/[name].[chunkhash:8].js',
 87         chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
 88         // We inferred the "public path" (such as / or /my-project) from homepage.
 89         publicPath: publicPath,
 90         // Point sourcemap entries to original disk location (format as URL on Windows)
 91         devtoolModuleFilenameTemplate: info =>
 92                 path
 93                         .relative(paths.appSrc, info.absoluteResourcePath)
 94                         .replace(/\\/g, '/'),
 95     },
 96     resolve: {//这些选项能设置模块如何被解析
 97         // This allows you to set a fallback for where Webpack should look for modules.
 98         // We placed these paths second because we want `node_modules` to "win"
 99         // if there are any conflicts. This matches Node resolution mechanism.
100         // https://github.com/facebookincubator/create-react-app/issues/253
101         //modules告诉 webpack 解析模块时应该搜索的目录
102         modules: ['node_modules', paths.appNodeModules].concat(
103                 // It is guaranteed to exist because we tweak it in `env.js`
104                 process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
105         ),
106         // These are the reasonable defaults supported by the Node ecosystem.
107         // We also include JSX as a common component filename extension to support
108         // some tools, although we do not recommend using it, see:
109         // https://github.com/facebookincubator/create-react-app/issues/290
110         // `web` extension prefixes have been added for better support
111         // for React Native Web.
112         //extensions:自动解析确定的扩展
113         extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
114         //alias: 创建 import 或 require 的别名
115         alias: {
116 
117             // Support React Native Web
118             // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
119             'react-native': 'react-native-web',
120         },
121         //plugin:应该使用的额外的解析插件列表
122         plugins: [
123             // Prevents users from importing files from outside of src/ (or node_modules/).
124             // This often causes confusion because we only process files within src/ with babel.
125             // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
126             // please link the files into your node_modules/ and let module-resolution kick in.
127             // Make sure your source files are compiled, as they will not be processed in any way.
128             new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
129         ],
130     },
131     //module:这些选项决定了如何处理项目中的不同类型的模块
132     module: {
133         strictExportPresence: true,
134         //每个规则可以分为三部分 - 条件(condition),结果(result)和嵌套规则(nested rule)
135         //创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。这些规则能够对模块(module)应用 loader,或者修改解析器(parser)。
136         rules: [
137             // TODO: Disable require.ensure as it's not a standard language feature.
138             // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
139             // { parser: { requireEnsure: false } },
140 
141             // First, run the linter.
142             // It's important to do this before Babel processes the JS.
143             {
144                 //test:匹配特定条件。一般是提供一个正则表达式或正则表达式的数组,但这不是强制的
145                 test: /\.(js|jsx|mjs)$/,
146                 enforce: 'pre',
147                 // use: [
148                 //     {
149                 //         options: {
150                 //             formatter: eslintFormatter,
151                 //             eslintPath: require.resolve('eslint'),
152 
153                 //         },
154                 //         loader: require.resolve('eslint-loader'),
155                 //     },
156                 // ],
157                 //loader是文件预处理器
158                 //使用babel-loader加载js,jsx,mjs
159                 //babel-loader用来处理ES6语法,将其编译为浏览器可以执行的js语法
160                 loader: require.resolve('babel-loader'), //resolve返回绝对路径
161                 include: paths.appSrc,
162             },
163             {
164                 // "oneOf" will traverse all following loaders until one will
165                 // match the requirements. When no loader matches it will fall
166                 // back to the "file" loader at the end of the loader list.
167                 //oneOf:当规则匹配时,只使用第一个匹配规则
168                 oneOf: [
169                     // "url" loader works just like "file" loader but it also embeds
170                     // assets smaller than specified size as data URLs to avoid requests.
171                     {
172                         test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
173                         loader: require.resolve('url-loader'),
174                         options: {
175                             limit: 10000,
176                             name: 'static/media/[name].[hash:8].[ext]',
177                         },
178                     },
179                     // Process JS with Babel.
180                     {
181                         test: /\.(js|jsx|mjs)$/,
182                         include: paths.appSrc,
183                         loader: require.resolve('babel-loader'),
184                         // options: {
185                         //     plugins: [
186                         //         ['import', [{ libraryName: "antd", style: 'css' }]],
187                         //     ],
188                         //     compact: true,
189                         // },
190                     },
191                     // The notation here is somewhat confusing.
192                     // "postcss" loader applies autoprefixer to our CSS.
193                     // "css" loader resolves paths in CSS and adds assets as dependencies.
194                     // "style" loader normally turns CSS into JS modules injecting <style>,
195                     // but unlike in development configuration, we do something different.
196                     // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
197                     // (second argument), then grabs the result CSS and puts it into a
198                     // separate file in our build process. This way we actually ship
199                     // a single CSS file in production instead of JS code injecting <style>
200                     // tags. If you use code splitting, however, any async bundles will still
201                     // use the "style" loader inside the async code so CSS from them won't be
202                     // in the main CSS file.
203                     {//定义如何加载css,scss,如果需要解析less要再次配置
204                         test: /\.(css|scss|styl)$/,
205                         loader: ExtractTextPlugin.extract(
206                                 Object.assign(
207                                         {
208                                             fallback: {
209                                                 loader: require.resolve('style-loader'),
210                                                 options: {
211                                                     hmr: false,
212                                                 },
213                                             },
214                                             use: [
215                                                 {
216                                                     loader: require.resolve('css-loader'),
217                                                     options: {
218                                                         importLoaders: 1,
219                                                         minimize: true,
220                                                         sourceMap: shouldUseSourceMap,
221                                                     },
222                                                 },
223                                                 {
224                                                     loader: require.resolve('postcss-loader'),
225                                                     options: {
226                                                         // Necessary for external CSS imports to work
227                                                         // https://github.com/facebookincubator/create-react-app/issues/2677
228                                                         ident: 'postcss',
229                                                         plugins: () => [
230                                                             require('postcss-flexbugs-fixes'),
231                                                             autoprefixer({
232                                                                 browsers: [
233                                                                     '>1%',
234                                                                     'last 4 versions',
235                                                                     'Firefox ESR',
236                                                                     'not ie < 9', // React doesn't support IE8 anyway
237                                                                 ],
238                                                                 flexbox: 'no-2009',
239                                                             }),
240                                                         ],
241                                                     },
242                                                 },
243                                                 {
244                                                     loader: require.resolve('sass-loader') // compiles Less to CSS
245                                                 },
246                                                 {
247                                                     loader: require.resolve('stylus-loader') // compiles stylus to CSS
248                                                 }
249                                             ],
250                                         },
251                                         extractTextPluginOptions
252                                 )
253                         ),
254                         // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
255                     },
256                     // "file" loader makes sure assets end up in the `build` folder.
257                     // When you `import` an asset, you get its filename.
258                     // This loader doesn't use a "test" so it will catch all modules
259                     // that fall through the other loaders.
260                     {
261                         loader: require.resolve('file-loader'),
262                         // Exclude `js` files to keep "css" loader working as it injects
263                         // it's runtime that would otherwise processed through "file" loader.
264                         // Also exclude `html` and `json` extensions so they get processed
265                         // by webpacks internal loaders.
266                         exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
267                         options: {
268                             name: 'static/media/[name].[hash:8].[ext]',
269                         },
270                     },
271                     // ** STOP ** Are you adding a new loader?
272                     // Make sure to add the new loader(s) before the "file" loader.
273                 ],
274             },
275         ],
276     },
277     //plugins定义使用的插件
278     plugins: [
279         new HelloWorldPlugin(),
280         // Makes some environment variables available in index.html.
281         // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
282         // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
283         // In production, it will be an empty string unless you specify "homepage"
284         // in `package.json`, in which case it will be the pathname of that URL.
285         new InterpolateHtmlPlugin(env.raw),
286         // Generates an `index.html` file with the <script> injected.
287         new HtmlWebpackPlugin({
288             inject: true,
289             template: paths.appHtml,
290             minify: {
291                 removeComments: true,
292                 collapseWhitespace: true,
293                 removeRedundantAttributes: true,
294                 useShortDoctype: true,
295                 removeEmptyAttributes: true,
296                 removeStyleLinkTypeAttributes: true,
297                 keepClosingSlash: true,
298                 minifyJS: true,
299                 minifyCSS: true,
300                 minifyURLs: true,
301             },
302         }),
303         //CommonsChunkPlugin,用于抽离代码
304         new webpack.optimize.CommonsChunkPlugin({
305           names: ['antd', 'vendor'],
306           minChunks: Infinity
307         }),
308         // Makes some environment variables available to the JS code, for example:
309         // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
310         // It is absolutely essential that NODE_ENV was set to production here.
311         // Otherwise React will be compiled in the very slow development mode.
312         new webpack.DefinePlugin(env.stringified),
313         // Minify the code.
314         new webpack.optimize.UglifyJsPlugin({
315             compress: {
316                 warnings: false,
317                 // Disabled because of an issue with Uglify breaking seemingly valid code:
318                 // https://github.com/facebookincubator/create-react-app/issues/2376
319                 // Pending further investigation:
320                 // https://github.com/mishoo/UglifyJS2/issues/2011
321                 comparisons: false,
322             },
323             mangle: {
324                 safari10: true,
325             },
326             output: {
327                 comments: false,
328                 // Turned on because emoji and regex is not minified properly using default
329                 // https://github.com/facebookincubator/create-react-app/issues/2488
330                 ascii_only: true,
331             },
332             sourceMap: shouldUseSourceMap,
333         }),
334         // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
335         new ExtractTextPlugin({
336             filename: cssFilename,
337         }),
338         // Generate a manifest file which contains a mapping of all asset filenames
339         // to their corresponding output file so that tools can pick it up without
340         // having to parse `index.html`.
341         new ManifestPlugin({
342             fileName: 'asset-manifest.json',
343         }),
344         // Generate a service worker script that will precache, and keep up to date,
345         // the HTML & assets that are part of the Webpack build.
346         new SWPrecacheWebpackPlugin({
347             // By default, a cache-busting query parameter is appended to requests
348             // used to populate the caches, to ensure the responses are fresh.
349             // If a URL is already hashed by Webpack, then there is no concern
350             // about it being stale, and the cache-busting can be skipped.
351             dontCacheBustUrlsMatching: /\.\w{8}\./,
352             filename: 'service-worker.js',
353             logger(message) {
354                 if (message.indexOf('Total precache size is') === 0) {
355                     // This message occurs for every build and is a bit too noisy.
356                     return;
357                 }
358                 if (message.indexOf('Skipping static resource') === 0) {
359                     // This message obscures real errors so we ignore it.
360                     // https://github.com/facebookincubator/create-react-app/issues/2612
361                     return;
362                 }
363                 console.log(message);
364             },
365             minify: true,
366             // For unknown URLs, fallback to the index page
367             navigateFallback: publicUrl + '/index.html',
368             // Ignores URLs starting from /__ (useful for Firebase):
369             // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
370             navigateFallbackWhitelist: [/^(?!\/__).*/],
371             // Don't precache sourcemaps (they're large) and build asset manifest:
372             staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
373         }),
374         // Moment.js is an extremely popular library that bundles large locale files
375         // by default due to how Webpack interprets its code. This is a practical
376         // solution that requires the user to opt into importing specific locales.
377         // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
378         // You can remove this if you don't use Moment.js:
379         new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
380     ],
381     // Some libraries import Node modules but don't use them in the browser.
382     // Tell Webpack to provide empty mocks for them so importing them works.
383     node: {
384         dgram: 'empty',
385         fs: 'empty',
386         net: 'empty',
387         tls: 'empty',
388         child_process: 'empty',
389     },
390 };
posted @ 2019-12-22 17:03  老愤猫  阅读(768)  评论(0)    收藏  举报