loader && plugins
2020-10-11
loader && plugins
loader:
- 像是一个个不同的车间 把我们的模块加工成可以使用的文件 loader只是加载模块的环节工作
loader 大概可以分为3类:
- 1、编译转换类 例如:css-loader 把css转换为 bundle.js 中的模块 从而实现以JS形式工作的css模块
- 2、文件操作类型的加载器 例如:file-loader 把加载到的资源模块拷贝到输出的目录 同时将这个文件的访问路径向外导出
- 3、代码检查类加载器 为了统一代码风格 例如:eslint-loader
plugin:
- plugins 解决除了资源加载以外 其他的自动化工作
- 例如 打包之前清除dist目录 或者 拷贝静态文件至输出目录 或是 压缩输出的代码
- plugin 触及到webpack工作的每一个环节 有点像生命周期函数 或者说 钩子函数
- webpack在执行的每一个环节都设置了一个钩子 plugin就是往这些钩子上去挂载任务
手写plugin:
- plugin 的格式通常是一个class类 里面有一个apply方法
- apply方法接收一个参数 compiler 就是此次webpack工作中最核心的对象
- 包含了此次webpack构建任务的所有配置信息 以及所有的钩子
// 手写一个plugin plugin 的格式是一个class类 里面有一个apply方法 // apply方法接收一个参数 class MyPlugin { // compiler 就是此次webpack工作中最核心的对象 // 包含了此次webpack构建任务的所有配置信息 // 以及所有的钩子 apply(compiler) { // emit 钩子就是在即将往 目标目录输出文件时 的钩子 // .tap 就是往这个钩子上挂载任务 compiler.hooks.emit.tap('MyPlugin', compilation => { // compilation 可以理解为此次打包过程中的上下文 // 其中assets里就是所有文件的内容的对象 key是文件名 // val中有一个source方法可以拿到文件内容 for (const name in compilation.assets) { if (name.endsWith('.js')) { // 判断文件名是否是js结尾 // val中有一个source方法可以拿到文件内容 const contents = compilation.assets[name].source(); // 将js中以 /***...**/ 开头的注释删掉 const withoutContents = contents.replace(/\/\*\*+\*\//g, ''); compilation.assets[name] = { source: () => withoutContents, // val中还必须包含一个size方法得到文件内容的长度 size: () => withoutContents.length } } } }); } }