loader和plugin区别
- loader : 文件加载器、告诉webpack如何转化和处理某一类型文件、并引入到打包处的文件当中
- plugin : 自定义打包过程的方式、webpack提供了非常多的生命周期钩子我们可以在钩子函数里吗做一些我们想处理的逻辑、比如我想在输出文件的时候添加一段js、在或者我想在指定文件当中删除某些代码、都是可以的
开始
webpack插件可以是一个构造器或者一个对象、但是里面必须要有一个apply方法、apply方法会被webpack compiler调用、apply方法接收一个compiler对象、你可以往该对象挂在一些生命周期的callback 在不同的生命周期的钩子里面我们可以处理不同事情、所以我们只需要了解不同生命周期的方法和方法对应给到的参数就可以做业务逻辑处理了、说到底还是:增删改查
学习compiler & compilation钩子流程
先了解compiler和compilation是什么东西、有什么关联!
- Compiler 对象包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;
- Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。
webpack基础搭建
```javascript // 第一步创建文件夹webpack-test yarn init //初始化 yarn add webpack webpack-cli webpack-dev-server -D // 安装必须要的插件
// 第二步 创建src文件夹 下面main.js console.log(‘2222’)
// 第三步根节点创建webpack.config.js const path = require(‘path’); module.exports = { entry: ‘./src/main.js’, devtool: ‘inline-source-map’, devServer: { static: ‘dist’, compress: true, port: 9000, }, mode: ‘development’, plugins: [], output: { filename: ‘[name].bundle.js’, path: path.resolve(__dirname, ‘dist’), clean: true, }, };
// 第四步配置script脚本命令 “scripts”: { “build”: “webpack —config webpack.config.js”, “start”: “webpack serve” }
// 启动 yarn start
> 正常情况下你就能够看到启动成功的日志、在浏览器访问[http://localhost:9000](http://localhost:9000/) 就能正常的访问、这样基础cli就完成了、现在开始插件的基础使用
<a name="a5OU0"></a>
### 插件的基础使用
- 根节点创建build文件夹、并创建plugins文件夹
- 创建webpack-plugin-test 、然后在当前文件夹创建index.js
```javascript
// /build/plugins/webpack-plugin-test/index.js
class WebpackPluginTest{
constructor(){}
apply(compiler){
console.log(compiler)
}
}
module.exports = WebpackPluginTest
// webpack.config.js
const WebpackPluginTest = require("./build/plugins/webpack-plugin-test/index");
// 使用插件
plugins: [
new WebpackPluginTest({
type:"dev",
number:1
})
]
启动打包执行插件
yarn build 能发现我们这个compiler对象输出还是挺多的内容的
打包流程的生命周期
我们需要先了解下webpack不同的生命周期钩子、钩子的用法、文档在开头、可以自行查看
class WebpackPluginTest{
constructor(options){
console.log('test',options);
}
apply(compiler){
// 输出 asset 到 output 目录之前执行、更多生命周期请查阅官网:https://webpack.docschina.org/api/compiler-hooks/#emit
compiler.hooks.emit.tap("WebpackPluginTest", (compilation) =>{
})
}
}
module.exports = WebpackPluginTest
在 emit 钩子事件发生时,代表源文件的转换和组装已经完成,在这里可以读取到最终将输出的资源、代码块、模块及其依赖,并且可以修改输出资源的内容
常用的生命周期钩子
- entryOption : 在 webpack 选项中的 entry 配置项 处理过之后,执行插件。
- afterPlugins : 设置完初始插件之后,执行插件。
- compilation : 编译创建之后,生成文件之前,执行插件。。
- emit : 生成资源到 output 目录之前。
- done : 编译完成。
读取输出资源、代码块、模块及其依赖
在增删改查前、我们需要先了解下compilation 里面有那些属性是我们常用到的、和可能用到的
compilation
chunks
entry 入口文件配置了几个就会有几个对象包信息,根据若干个module依赖打包生成的一个包、每个chunk管理最终渲染资源的组合
{
id: 0,
rendered: true,
initial: false,
//是否含有 Webpack 的 runtime 环境,通过 CommonChunkPlugin 处理后,runtime 环境被提到最高层级的 chunk
entry: false,
recorded: undefined,
extraAsync: false,
size: 296855,
//require.ensure 不是通过 Webpack 配置的,所以 chunk 的 names 是空
names: [],
//该 chunk 产生的输出文件,即输出到特定文件路径下的文件名称
files: [ '0.bundle.js' ],
//chunk 的 hash,即 chunkHash
hash: '42fbfbea594ba593e76a',
//父级 chunk 的 id 值
parents: [ 2 ],
//该 chunk 是如何产生的
origins: [ [Object] ]
}