webpack5——基础篇

132 阅读4分钟

常用配置

module.exports = {
  mode: 'none/development/production',
  devtool: 'eval-cheap-module-source-map/none',
  entry: './src/index.js/',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].bundle.js',
    chunkFilename: '[name].chunk.js',
    // publicPath: '/build/'
  },
  devServer: {
    hot: true, // 开启热更新
    port: 'port number/auto',
    // proxy: {}
    static: {
      directory: path.resolve(__dirname, 'build'),
    }
  },
  module: {
    noParse: /jquery|lodash/,
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
      {
        test: /\.(jpg|png|jpeg|gif|svg)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024,
          },
        },
        generator: {
          filename: "assets/imgs/[hash:6][ext][query]",
        },
      },
    ],
  },
  plugins: [...],
  resolve: {
    alias: {
      $imgs: path.resolve(__dirname, "./src/assets/imgs/"),
    },
    extensions: [".js", "jsx", ".ts", ".tsx"],
    modules: [path.resolve(__dirname, "node_modules")],
  },
  cache: {
    type: "memory/filesystem", // 临时/持久化
    buildDependencies: {
      config: [__filename]
    },
    // version: process.env.NODE_ENV,
    // name: process.env.NODE_ENV,
  }
  // snapshot: { // 大部分情况使用默认
  //   managedPaths: [path.resolve(__dirname, '../node_modules')],
  //   immutablePaths: [],
  //   buildDependencies: {
  //     hash: true,
  //     timestamp: true,
  //   },
  //   module: {
  //     timestamp: true,
  //   },
  //   resolve: {
  //     timestamp: true,
  //   },
  //   resolveBuildDependencies: {
  //     hash: true,
  //     timestamp: true,
  //   },
  // },
  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
        lodash: {
          name: 'lodash-vendor',
          test: /[\\/]lodash[\\/]/,
          priority: 0,
          reuseExistingChunk: true,
        },
      },
    },
    minimize: true,
    minimizer: [new TerserWebpackPlugin()],
    sideEffects: 'true',
  }
}

entry

  1. 单页面只有一个入口文件

output

  1. path: 打包后输出文件位置
  2. filename:打包生成 bundle 文件名称
  3. chunkFilename: chunk 包名称
  4. publicPath:打包后 html 加载资源文件前缀;未找到时,报 404

module

loader

  1. 图片、字体 —— 采用 assetModuleFilename
    • asset/resource:将资源分割为单独的文件,并导出 url,类似之前的 file-loader 的功能.
    • asset/inline:将资源导出为 dataUrl 的形式,类似之前的 url-loader 的小于 limit 参数时功能
    • asset:会根据文件大小来选择使用哪种类型,当文件小于 8 KB(默认) 的时候会使用 asset/inline,否则会使用 asset/resource
  2. test、include、exclude 对匹配到的文件进行 loader
    • 优先级:exclude > include > test
  3. options:提供 loader 特有的属性值(参考对应的 loader)

其他

  1. noParse:不解析正则表达式匹配到的文件

resolve:如何正确的找到对应的文件

  1. alias:对常用模板进行别名,有利于代码简洁
  2. extensions:支持文件后缀匹配的缩写;支持多种类型,命名不可相同
  3. modules
    • 相对路径:对 module 的 resolve 过程中,会依次查找 ./node_modules、../node_modules、../../node_modules 等,即沿着路径一层一层往上找,直到找到 node_modules
    • 绝对路径:只找给定路径下
  4. unsafeCache:针对常用模板进行缓存处理;再次解析时,直接用缓存

plugins

  • 熟悉常用的 plugin
  1. 打包分析:webpack-bundle-analyzer

optimization

split chunk

  • 目的:减少请求资源的大小和请求次数

  • 源码

     splitChunks: {
       chunks: 'all',
       minSize: 20000, // 打包前文件大小
       maxSize: 0, // 打包后文件大小
       minRemainingSize: 0,
       minChunks: 1, // 引用次数
       maxAsyncRequests: 30, // 最大的按需(异步)加载次数
       maxInitialRequests: 30, // 打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件)
       enforceSizeThreshold: 50000,
       cacheGroups: {
         defaultVendors: {
           name: 'vendors', // 自定义打包的文件名
           test: /[\\/]node_modules[\\/]/,
           priority: -10,  // 优先级
           reuseExistingChunk: true,
         },
         default: {
           minChunks: 2,
           priority: -20,
           reuseExistingChunk: true,
         },
         ... 自定义多个groups,减小首屏的文件的加载资源文件的大小
       },
     }
    
     // 优先级: minSize > maxSize > maxInitialRequests / maxAsyncRequests
     // 满足上面一个条件都会进行模版拆分
     // cacheGroups里面没有定义,使用外面的配置
     // 拆分chunk包,防止某个包过大;使减少请求资源的大小和请求次数达到平衡
    
  • 懒加载:通过 import 动态引入,实现懒加载(webpackPrefetch、webpackPreload)

  • split chunk 资料

tree shaking

  • 目的:移除 JavaScript 上下文中的未引用代码
  1. sideEffects
  • 需要再 package.js 配置 sideEffects: [], 不需要 tree shaking 的正则表达式
  • 模式:生产模式生效 —— mode: "production"

minimize、minimizer

  • terser-webpack-plugin:js 压缩
  • css-minimizer-webpack-plugin:css 压缩

cache

  • 作用:持久化缓存主要解决的就是优化编译流程(resolve,build),减少编译耗时的问题
  • 缓存失效策略 —— 当模块代码没有发生变化,但是构建处理过程本身发生变化时(例如升级了 Webpack 版本、修改了配置文件、改变了环境变量等),也可能对构建后的产物代码产生影响
    1. buildDependencies:业务中依赖模块改变时
    2. version
    3. name:利用 name 保留多套缓存
  • 资料:缓存讲解

snapshot

  • 作用:配置决定了缓存内存生成 snapshot 时所采用的策略,策略最终会影响到缓存是否失效,即 webpack 是否决定来使用缓存
  • 策略:timestamps(时间戳) | content hash(hash 值) | timestamps + content hash(时间戳+hash 值)
  • 源码
    snapshot: {
      managedPaths: [path.resolve(__dirname, '../node_modules')], // 被信任的路径,
      immutablePaths: [],
      buildDependencies: {  // 依赖项
        hash: true,
        timestamp: true,
      },
      module: { // 构建的module
        timestamp: true,
      },
      // 在 resolve request 的时候创建 snapshot 的方式
      resolve: {
        timestamp: true,
      },
      // 在 resolve buildDependencies 的时候创建 snapshot 的方式
      resolveBuildDependencies: {
        hash: true,
        timestamp: true,
      },
    },
    

devServer

  • 作用:开发环境使用
  1. hot: 开启热更新
  2. port:端口;自定义/auto:自动
  3. static
    • directory:devServer 启动后,文件路径;类似 output.publicPath
    • TODO publicPath

other config

  1. mode:环境
  2. devtool:利用 SourceMap 反向定位到源码位置
    • eval-cheap-module-source-map:dev
    • none —— prod;理由:就是不想别人看到我的源代码

优化

  • 步骤:resolve - build - generator
  • 优化主要针对前面两个步骤
  1. loader
    • 减少不必要的解析文件;noParse
    • exclude、include、test 减小范围
    • webpack4:cache-loader
    • thread-loader:多线程
  2. resolve
    • 减少不必要的查找;避免了层层寻找 node_modules 的开销
    • 针对常用的进行缓存处理:unsafeCache
    • 简化整个 resolve 过程
  3. cache
    • webpack5:持久化缓存
  4. plugin
    • webpack4:DllPlugin
    • 压缩:css、js 代码压缩
  5. optimization
    1. split chunks: 拆分 chunk 包,减小首屏加载无用资源
    2. 懒加载