实现一个webpack的 loader和plugin

90 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

实现一个webpack loader

开始之前我们先把webpack官网的介绍链接放上来

官网编写loader文档

感兴趣的同学可以直接阅读官方文档。

loader 是导出为一个函数的 node 模块。该函数在 loader 转换资源的时候调用。给定的函数将调用 Loader API,并通过 this 上下文访问。

这是官方文档对loader的介绍,简单来说就是loader是一个函数,这个函数在webpack编译过程中执行,并通过this上下文访问webpack编译过程中的产物,因为要通过this来访问上下文,所以loader不能是前头函数

实现一个简单的loader

 module.exports = function(source) {
   console.log(source,this)
   return source.replace('hellow webpack','你好呀,webpack')
}

使用loader

{
  test:/\.js$/,
  use: path.resolve(__dirname,'./loader/replaceLoader.js)
}

index.js中的内容

console.log('hellow webpack')

我们来看一下使用结果

可以看到console函数中的hellow已经被替换成了 你好

在使用loader时我们应该注意loader的调用顺序

loader总是从下到上,从右到左的调用,也就是先注册的后调用,后注册的先调用

实现一个plugin

同样的,我们先放上官网对于plugin的介绍

官网编写plugin文档

感兴趣的同学可以自己查看

插件向第三方开发者提供了 webpack 引擎中完整的能力。使用阶段式的构建回调,开发者可以在 webpack 构建流程中引入自定义的行为。创建插件比创建 loader 更加高级,因为你需要理解 webpack 底层的特性来处理相应的钩子

很显然,我们每次调用plugin都需要new一下,因为plugin是一个构造函数。

class  customPlugin {
   constructor (options) {}
   apply(compiler) {}
}

这是plugin的基本格式

有以下几个注意点:

  • 必须有apply函数,webpack会通过apply启动函数
  • plugin也可以写成普通函数的形式,但是apply必须挂载到函数的原型对象上
  • class类中的apply不能为箭头函数
  • 指定一个绑定到 webpack 自身的事件钩子。钩子决定了你的插件需要的webpack编译的什么阶段做什么事情

实现一个plugin

class customPluin {
  constructor (options) {}
  apply(compiler) {
   compiler.hooks.emit.tap('customPlugin', (compolation) => {
  const content = '<html><body>fake html</body></html>'
   compolation.assets['fake.html] = {
   source: function() {
     return content
 },
 size: function() {
  return content.length
}
}
})
  
  }
}

module.exports = customPlugin

使用这个plugin

plugins: [
  new HtmlPlugin()
]

运行一下,成功输出了fake.html, plugin编写成功