webpack(二)

144 阅读4分钟

2-2-2-2 webpack增强开发体验

1) 自动编译

watch工作模式 ---> 监听文件变化,自动重新打包

npx webpack --watch
或者 把watch属性设置为true

2) 自动刷新浏览器

1. npm i browser-sync -g
2. browser-sync dist --files '**/*'

3) Webpack Dev Server

集成自动编译和自动刷新浏览器,打包结果暂时保存在内存中未输出到dist

1. npm i webpack-dev-server
2. npx webpack-dev-server --open
  • contentBase 额外为开发服务器指定查找资源目录
  • 代理API
devServer: {
        // 额外为开发服务器指定查找资源目录
        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,
            }
        }
    },

4) Source Map

解决了源代码与运行代码不一致所产生 的(调试)问题

5) webpack 配置 Source Map(共12种方式)

devtool 注解

  • source-map 原始源代码
devtool: 'source-map',
  • eval 模式(速度最快,只能定位文件名称,不能定位到具体错误行数信息) 生成后的代码
devtool: 'eval',
  • eval-source-map 原始源代码
  • cheap-eval-source-map 转换过的代码(仅限行)
  • cheap-module-eval-source-map 原始源代码(仅限行)

  • eval - 是否使用eval 执行模块代码
  • cheap - Source Map 是否包含行信息
  • module - 是否能够得到Loader处理之前的源代码

6)webpack 选择 Source Map 模式

  • 开发模式 cheap-module-eval-source-map
    • 代码每行基本不会超过80个字符,定位到行已足够
    • 代码经过Loader转换过后的差异较大(调试转换前的源代码更优)
    • 首次打包速度慢无所谓,重写打包相对较快
  • 生产模式 none/nosources-source-map
    • Source Map 会暴露源代码

7) HMR 热更新、热替换

集成在webpack-dev-server中,使用通过webpack-dev-server --hot启用,或者通过配置文件开启

// 1. devServer 里设置 hot 为 true
hot: true,

// 2. 使用webpack内置插件HotModuleReplacementPlugin
    const { HotModuleReplacementPlugin } = require('webpack');
// HMR
        new HotModuleReplacementPlugin()

8)webpack 使用 HMR API

  • 注意事项
    • hotOnly
    • 未开启HMR
    • 代码中多了很多与业务无关的代码(无影响)

9)生成环境优化

生成环境注重运行效率,开发环境注重开发效率

  • 不同环境下的配置(两种方式)

    • 配置文件根据环境不同导出不同配置

    • 一个环境对应一个配置文件(多配置文件)

      • webpack.dev.js 开发环境
      • webpack.prod.js 生产环境
      • webpack.common.js 公共配置
      webpack --config webpack.dev.js  指定打包时的配置文件
      
  • DefinePlugin

    • process.end.NODE_ENV
    • 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。
    • 每个传进 DefinePlugin 的键值都是一个标志符或者多个用 . 连接起来的标志符。
      • 如果这个值是一个字符串,它会被当作一个代码片段来使用。
      • 如果这个值不是字符串,它会被转化为字符串(包括函数)。
      • 如果这个值是一个对象,它所有的 key 会被同样的方式定义。
      • 如果在一个 key 前面加了 typeof,它会被定义为 typeof 调用。
  • Tree Shaking 摇掉未引用代码

    • 生产环境默认开启
    • 其他环境手动配置
    optimization: {
        // 模块只导出被使用的成员
        usedExports: true,
        // 尽可能合并每一个模块到一个函数中
        concatenateModules: true,
        // 压缩输出结果
        minimize: true
      }
    
  • sideEffects 副作用 (生产环境默认开启)

optimization: {
    sideEffects: true,
  }

10) 代码分割

  • 多入口打包
    • 适用于多页面应用
  • 动态导入

11)MiniCssExtractPlugin

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')

module.exports = {
  mode: 'none',
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].bundle.js'
  },
  optimization: {
    minimizer: [
      new TerserWebpackPlugin(), // js压缩插件
      new OptimizeCssAssetsWebpackPlugin() // css压缩插件
    ]
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', // 将样式通过 style 标签注入
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Dynamic import',
      template: './src/index.html',
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin()
  ]
}

12)输出文件名Hash

  • hash 项目层面
  • chunkhash 同一路(比如多入口文件时某一入口所影响的)
  • contenthash 文件层面 控制缓存的最优选择(8位)