webpack4 学习

51 阅读3分钟
1 hash 解决缓存
output: {
    filename: '[name]-[contenthash:8].bundle.js'
    // contenthash:8限制hash长度
      // 1hash 文件任何地方改动 打包的hash值都会发生变化
      // 2chunkhash 同一路的打包,chunkhash都是相同的,例如:每个懒加载的组件都是同一路 同一个模块,都会有一个
      // 2chunkhash,只有文件内容发生变化,属于该模块的hash都会变化,同时引入该模块的main.js也会变化。该模块也引入了
      // 2css文件,他们是同一路了,都会变化,也就是它引入的模块的hash也会变化
      // 3contenthash 内容发生变化,hash才会变化,引入它的模块的hash也会变化,
      // 3但它引入的模块的hash不会变化,这也是它和chunkhash的区别
      // 3推荐使用,解决缓存最好的方式,他精确定位到了文件级别,
2 css提取
如果css文件大于150kb,提取效果更好,减少一次请求

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 将样式通过 style 标签注入
          MiniCssExtractPlugin.loader,//link标签引入
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Dynamic import',
      template: './src/index.html',
      filename: 'index.html'
    }),
    // 提取css插件,但配置他的loader,以link标签引入
    new MiniCssExtractPlugin()
 
  ]
  
  
  

MiniCssExtractPlugin 只是提取,并没有压缩,webpack默认之压缩js,其它资源需要额外配置

 optimization: {
    minimizer: [
      // 使用minimizer 表示使用自定义压缩,它内置的压缩就会被覆盖
      // 所以要用TerserWebpackPlugin 压缩js
      new TerserWebpackPlugin(),
      // 在这里配置 压缩css
      new OptimizeCssAssetsWebpackPlugin()
    ]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 将样式通过 style 标签注入
          MiniCssExtractPlugin.loader,//以link标签引入
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Dynamic import',
      template: './src/index.html',
      filename: 'index.html'
    }),
    // 提取css插件,但配置他的loader,以link标签引入
    new MiniCssExtractPlugin()
// 压缩css,在任何情况下都会压缩,正常一配在optimization中,只有开启optimization时,在生成模式自动开启,
// 才会压缩,统一管理
    // new OptimizeCssAssetsWebpackPlugin()
  ]
魔法注释
// import() 异步加载 使用注释 /* webpackChunkName: 'components' */ 打包时,该文件的名字会是components
    import(/* webpackChunkName: 'components' */'./posts/posts').then(({ default: posts }) => {
      mainElement.appendChild(posts())
    })

公共代码提取

optimization: {
    splitChunks: {
      // 自动提取所有公共模块到单独 bundle
      chunks: 'all'
    }
  },

多个入口

entry: {
    index: './src/index.js',
    album: './src/album.js'
  },
  output: {
    filename: '[name].bundle.js'
  },
  
   plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Multi Entry',
      template: './src/index.html',
      filename: 'index.html',
      chunks: ['index']
    }),
    new HtmlWebpackPlugin({
      title: 'Multi Entry',
      template: './src/album.html',
      filename: 'album.html',
      chunks: ['album']
    })
  ]

副作用

optimization: {
    // 开启是否有副作用,副作用是指有些代码被导入了,虽然没有被使用,依然有用,比如:一个模块在Number的原型
    // 上写方法,还有引入的全局css样式,
    //  还需要在package中指定哪些文件有副作用,都没有可以设为false,
    // 这两个加在一起才会清楚没有副作用的代码,只开启,只会标识
    sideEffects: true,
    // 模块只导出被使用的成员
    // usedExports: true,
    // 尽可能合并每一个模块到一个函数中
    // concatenateModules: true,
    // 压缩输出结果
    // minimize: true,
  }

image.png

tree shaking 摇树:摇晃大树,不好的树叶就会落下。在代码中指剔除未被使用的代码 production 模式会自动开启tree shaking

optimization: {
    // 模块只导出被使用的成员
    usedExports: true,
    // 压缩输出结果 他们两个结合可以实现tree shaking
    // minimize: true
    
    // 尽可能合并每一个模块到一个函数中,减小代码体积,默认一个模块对应一个函数
    concatenateModules: true,
    
  }

loader 返回的必须js代码字符串,因为要在函数中执行,非js代码会报错。

dev-serve指定静态目录

devServer: {
//配置后可以通过浏览器访问public目录下的所有文件
    contentBase: './public',
    proxy: {
      '/api': {
        // http://localhost:8080/api/users -> https://api.github.com/api/users
        target: 'https://api.github.com',
        // http://localhost:8080/api/users -> https://api.github.com/users
        pathRewrite: {
          '^/api': ''
        },
        // 不能使用 localhost:8080 作为请求 GitHub 的主机名
        changeOrigin: true
      }
    }
  },

合并配置项

const merge = require('webpack-merge')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const common = require('./webpack.common')
//plugins会合并到一起,而Object.assign()合并后面的会把前面的覆盖掉
module.exports = merge(common, {
  mode: 'production',
  plugins: [
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin(['public'])
  ]
})