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
          }
        }
      }
    });
  }
}

 

posted @ 2020-10-11 20:29  蓝小胖纸  阅读(115)  评论(0编辑  收藏  举报