前端知识总结——webpack

276 阅读2分钟

webpack3与webpack4的区别

  1. mode
mode:'development' //process.env.NODE_ENV= 'development'
mode:'production' //process.env.NODE_ENV=production
  1. CommonsChunkPlugin

webpack4移除webpack.optimize.CommonsChunkPlugin,使用optimization.splitChunks进行模块划分(提取公用代码)。

//平时配置 CommonsChunkPlugin 如下
new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  // 引入node_modules的依賴全抽出來
  minChunks: function (module, count) {
    // any required modules inside node_modules are extracted to vendor
    return (
      module.resource &&
      /\.js$/.test(module.resource) &&
      module.resource.indexOf(
        path.join(__dirname, ‘../node_modules‘)
      ) === 0
    )
  }
  // 或者直接minChunks: 2,重復模塊大於2的全部抽出來
})
/********************webpack4***********************/
//默认配置只会对异步请求的模块进行提取拆分,如果要对entry进行拆分,需要设置optimization.splitChunks.chunks = 'all'。
module.exports = {
  optimization: {
    runtimeChunk: true,//自动拆分runtime文件
    splitChunks: {
      vendors: {
        name:  'venders',
        chunks:  'all',
        minChunks: 2
    }
  }
}
  1. mini-css-extract-plugin (CSS文件提取)

webpack 4 不再 支持 extract-css-chunks-webpack-plugin 使用 mini-css-extract-plugin 替代

-const ExtractCssChunks = require('extract-css-chunks-webpack-plugin')
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  name: 'client',
  target: 'web',
  module: {
    rules: [
      {
        test: /\.css$/,
-       use: ExtractCssChunks.extract({
-         use: 'css-loader'
-       })
+       use: [
+         {
+           loader: MiniCssExtractPlugin.loader,
+         },
+         "css-loader"
+       ]
      }
    ]
  },
// 
// other config........
//
   plugins: [
-    new ExtractCssChunks(),
+    new MiniCssExtractPlugin({
+        filename: `components/[name].css`
+    }),
     //
     // other config........
     //
   ]
  1. 安装依赖

新版babel使用新的命名空间@babel

  • @babel/core
  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-decorators
  • @babel/plugin-syntax-dynamic-import
  • @babel/plugin-transform-runtime
  • @babel/preset-env
  • @babel/runtime
  • babel-loader
  • @babel/polyfill
//.babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "targets": {
          "browsers": [
            "> 1%",
            "last 2 versions",
            "ie >= 11"
          ]
        },
        "useBuiltIns": "usage" // 按需引入 polyfill
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-syntax-dynamic-import",
    ["@babel/plugin-proposal-class-properties", { "loose": false }],
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ]
}
  1. vue-loader

vue-loader 15 注意要配合一个 webpack 插件才能正确使用

const { VueLoaderPlugin } = require('vue-loader') 
module.exports = {
  plugins: [ new VueLoaderPlugin() ]
}
  1. UglifyJsPlugin

只需要使用optimization.minimize为true就行,production mode下面自动为true

optimization.minimizer可以配置你自己的压缩程序

const TerserJSPlugin = require("terser-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")

module.exports = {
  optimization: {
    minimizer: [
      new TerserJSPlugin({
        parallel: true // 开启多线程压缩
      }),
      new OptimizeCSSAssetsPlugin({})
    ]
  }
}
  1. 移除loaders,必须使用rules(在3版本的时候loaders和rules 是共存的但是到4的时候只允许使用rules)
module: {
	rules: [
		{
			test: /\.(js|jsx)$/,
			exclude: /node_modules/,
			use: [
				{
					loader: 'babel-loader',
					options: {
						presets: [
							['env',
							{
								targets: {
								browsers: CSS_BROWSERS,
							},
						}],'react', 'es2015', 'stage-0'
						],
						plugins: [
							'transform-runtime',
							'add-module-exports',
						],
					},
				},
			],
		},
		{
			test: /\.(scss|css)$/,
			use: [
				'style-loader',
				{loader: 'css-loader',options:{plugins: [require('autoprefixer')({browsers: CSS_BROWSERS,}),],sourceMap: true}},
				{loader: 'postcss-loader',options:{plugins: [require('autoprefixer')({browsers: CSS_BROWSERS,}),],sourceMap: true}},
				{loader: 'sass-loader',options:{sourceMap: true}}
			]
		},
		{
			test: /\.(png|jpg|jpeg|gif)$/,
			exclude: /node_modules/,
			use: [
				{
					loader: 'url-loader?limit=12&name=images/[name].[hash:8].[ext]',
				},
			],
		},
		{
			test: /\.(woff|woff2|ttf|eot|svg)$/,
			exclude: /node_modules/,
			use: [
				{
					loader: 'file-loader?name=fonts/[name].[hash:8].[ext]',
				},
			],
		},
	],
}
  1. 支持es6的方式导入JSON文件,并且可以过滤无用的代码
let jsonData = require('./data.json')
import jsonData from './data.json'
import { first } from './data.json' // 打包时只会把first相关的打进去
  1. 升级happypack插件(happypack可以进行多线程加速打包)

运行在node.js之上的webpack时单线程模型,也就是只能一个一个文件进行处理,不能并行处理,happypack可以将任务分解给多个子进程,最后将结果发给主进程,js是单线程模型,只能通过这种多线程的方式提高性能 vue-loader 不支持 HappyPack,官方建议用 thread-loader

const HappyPack = require('happypack');

exports.module = {
  rules: [
    {
      test: /.js$/,
      use: ['happypack/loader?id=babel'],// 将对.js文件的处理转交给id为babel的HappyPack的实列
      exclude:/node_modules/
    }
  ]
};

exports.plugins = [
  new HappyPack({
    id: 'babel',// 用唯一的标识符id来代表当前的HappyPack 处理一类特定的文件
    loaders: [ 'babel-loader' ] // 如何处理.js文件,用法和Loader配置是一样的
  })
];  

基于webpack4搭建一个react脚手架