webpack

流程
  • 合并参数:从shell等命令中合并参数
  • 执行编译:初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
  • 入口:根据配置的 entry 找出所有的入口
  • 编译模块:根据入口,利用 loader 编译依赖的模块,找出依赖模块依赖的模块(套娃递归),完成后,得到了编译完成的模块和依赖关系
  • 输出:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
  • 输出完成:根据配置 output,将文件写入文件系统
入口 (entry)
单入口

通常的,只有一个入口文件,是 webpack 用来编译的起点,从此文件一步步找到所依赖的模块依次进行编译

示例:

module.exports = {
  entry: './src/index.js'
}
多入口

当然,也可以设置多个入口

  • 示例 1:

    module.exports = {
      entry:{
        demo1: './src/demo1.js',
        demo2: './src/demo2.js'
      }
    }
    
  • 示例 2:

    // 也可以根据传入的路径数组进行动态配置
    const path = require('path');
    module.exports = (env, args) => {
      const pages = env.pages.split(","); // 传入的数组
      const srcPagesDir = path.resolve(__dirname, "src/pages/");
      const entry = {};
      pages.forEach(
        (el) => (entry[el] = path.resolve(srcPagesDir, el, "index.js"))
      );
      return {
        entry
      }
    }
    
输出 (output)

最终的产物输出,无论单入口还是多入口,只能有一个 output

示例:

const path = require('path');
module.exports = {
  output: {
    // filename: 'main.js' // 输出的文件名
    filename: '[name].js' // 也可以进行动态配置
    path: path.resolve(__dirname, 'dist') // 输出的路径,默认为 dist
  	clean: true // 可以在每次编译或打包时将上次的产物清除
  	publicPath: '/'
  }
}
chunk
loader

用来处理各种文件,指定 rules规则,loader 的执行顺序为自下而上、从右至左

js
rules: [
  {
    test: /\.js|jsx$/, // 匹配的文件格式
    include: path.resolve(__dirname, "../src"), // 指定处理文件夹
    use: [
      {
        loader: 'babel-loader',
        options: {
           presets: ["@babel/preset-env"], // es6 => es5
        }
      }
    ]  
  }
]
css
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 抽离为单独的 css 文件
// postcss: 一个用 js 处理 css 的工具,拥有丰富的 API 和插件 (https://www.postcss.com.cn/)
const postcssLoader = {
  loader: "postcss-loader",
  options: {
    postcssOptions: {
      plugins: [
        [
          'postcss-preset-env',
          {
            // 其他选项
          },
        ],
      ],
    },
};
  
rules: [
  {
    test: /\.css$/,
    use: [
      MiniCssExtractPlugin.loader,
      'css-loader',
      postcssLoader
    ]
  },
  {
	test: /\.less$/,
    use: [
      MiniCssExtractPlugin.loader,
      "css-loader",
      postcssLoader,
      "less-loader",
    ]
  }
]

html
rules: [{
  test: /\.html$ /,
  exclude: /node_modules/, // 忽略处理
  loader: "html-loader",
  options: {
  	esModule: false,
  },
}]
图片
rules: [{
  test: /\.(jpg|png|jpeg|gif)$/,
  exclude: /node_modules/,
  use: [
    {
      loader: "url-loader",
      options: {
        limit: 1024 * 8,
        name: "[name].[ext]",
        esModule: false,
        outputPath: "static/assets/images",
      },
    },
  ]
}]
其他文件

处理其他的文件,例如 vue

rules: [
  {
    test: /\.vue$/,
    use: {
      loader: "vue-loader",
    },
  }
]

还有引入的其他类型的文件,可以使用 file-loader 等插件进行处理

当然,如果没有满足个人需要的 loader,还可以进行自定义 loader

plugin

目的在于解决 loader 解决不了的事

示例:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const path = require('path');

module.exports = (env, args) =>  {
  const pages = env.pages.split(",");
  return {
    plugins: [
      // 处理 html
      new HtmlWebpackPlugin({
        filename: 'index.html',
        template: path.resolve(__dirname, "src/index.html")
      });
      // 如果需要做静态化,处理 html 时也可以参考下面的代码
      // ...pages.map((pageName) => {
      //    return new HtmlWebpackPlugin({
      //      filename: `${pageName}/index.html`,
      //      chunks: [pageName],
      //      template: path.resolve(__dirname, "src/index.html"),
      //    });
      // }),
    
      // 提取单独的CSS
      new MiniCssExtractPlugin({
        filename: "[name]/main.[contenthash:10].css",
      }),
      // 压缩css
      new CssMinimizerPlugin(),
    ]
  }
}

外部扩展 (externals)

防止将某些 import 的包打包到 bundle 中,一般使用CDN引入,可以有效减小打包文件的大小

示例:

// 在 index.html 中需引入相应的 CDN 包
module.exports = {
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
    'antd': 'antd',
    'mobx': 'mobx',
    'mobx-react': 'mobxReact'
  }
}
调试

在 webpack 5.x 版本中,所提供的属性已经满足大部分的调试需求

// # npm i webpack-dev-server --save-dev 
module.exports = {
  devServer: {
    hot: true // 开启热更新
  },
  devtool: 'eval-source-map' // 使用源码还是编译后的 (https://webpack.docschina.org/configuration/devtool)
}
HMR

本质上是客户端拉取服务端的文件,可以理解为维护了一个websocket,本地监听文件改动时,会改变文件的hash, 客户端与上次进行对比,不同时则会发起请求重新读取文件列表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值