webpack打包原理的思考

webpack 是一个前端资源加载/打包的工具。 其根据模块的依赖关系进行静态分析,找到js模块以及一些浏览器不能直接运行的语言(less sass TypeScript等)将这些模块转化打包成合适的格式供浏览器使用


几个关键词

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,来找出直接或者间接依赖的文件。
  • Output: 出口,规定webpack输出的bundles的路径以及文件名,默认为 ./dist
  • Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
  • Loader:模块转换器,用于把模块原内容按照需求转换成 webpack 能处理的有效模块
  • Plugin:扩展插件,在 webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量,可扩展功能丰富。

Webpack 的构建流程:

  1. 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler。
  2. 编译:从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理。
  3. 输出:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统。

loader

loader是用来处理各种形式的资源,本质上是一个函数, 接受文件作为参数,返回转化后的结构

一个loader只做一种转换,比如解析less文件,less建立在css基础上,先解析less,再转为css,再插入到head

注意:loader 的调用是链式调用,从后往前,所以先写 style-loader 再写 css-loaderless-loader 在最后,执行时先用less-loader将less文件转化为css,再由 css-loader 解析css文件转成对象,传递给 style-loader 插入到 head
配置如下

module.exports={
    entry:{...},
    outpath:{path:...,filename:...},
    mode:'production',
    module:{
        rules:[
            {
                test:/\.less$/,
                use:[
                'style-loader',
                'css-loader',
                'less-loader'
                ]
            },
        ]
    }
}

Plugin

plugin 可以监听 webpack 处理过程中的关键事件,深度集成进 webpack 的编译器,可以说 plugin 的执行层面是整个构建过程。用户也可以自定义插件。

比如在webpack4中可以使用 mini-css-extract-plugin 插件来分离css文件,此插件为每个包含 CSS 的 JS 文件(打包之后的js文件)创建一个单独的 CSS 文件,并支持 CSS 和 SourceMap 的按需加载

MiniCssExtractPlugin和style-loader对比

MiniCssExtractPlugin 提取 JS 中引入的 CSS 打包到单独文件中,然后通过标签 添加到头部;style-loader 则是通过