写一个简单的webpack-loader

172 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

前言

面试经常会被问到webpack的loader和plugin,咱们今天来写一个简单的webpack-loader,理解一下loader这个过程。

webpack loader

loader其实可以理解为一个转换器,把某类特定的文件转成loader对应的文件。

举个例子:

{
  module: {
    rules: [
      {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader']
      }
    ]
  }
}

上面这个loader,对css文件进行转换

注意:loader是从右往左执行的。所以是先执行css-loader,再执行style-loader。

先使用css-loader转换css文件的语法

接着使用style-loader把上一步的转换的结果生成style样式,插入到head标签中。

配置项除了使用loaders,还可以使用loader,use。loader一般是配置单个loader,字符串类型,use和loaders是跟着数组。

除了css的loader,还有sass的loader,file的loader等等。

写一个简单的loader

下面我是在vue项目演示写一个loader,我是想针对txt文件,把它导出的变量名给修改了,达到了转换的结果。

正常在vue组件中引入一个txt文件(需要export导出)

// test.txt
export default '答案cp3'
// Home.vue
import test from '@/assets/test.txt'
console.log(test)

组件执行的时候会打印答案cp3

image.png

下面我们通过编写一个loader来把这个导出的变量名给修改了

定一个loader文件夹,里面是一个changeName.js

主要是把答案cp3替换成hello wolrd

module.exports = function (src) {
  const content = src.replace('答案cp3', 'hello wolrd')
  return content
}

然后在vue.config.js配置这个loader

要使用到chainWebpack这个选项,可以链式操作webpack的配置

module.exports = {
  chainWebpack: config => {
    config.module.rule('changeName').test(/\.txt$/)
      .use('changeName').loader(require.resolve('./src/loader/changeName.js')).end()
  }
}

rule就是规则的名称,test就是匹配的正则,use就是使用哪个loader, loader的参数就是我们定义的loader的文件夹地址,end就是这个loader调用结束。

跑一下项目,yarn run serve

查看一下控制台的打印

image.png

可以看到生效了。

这个loader就是编写成功了。

注意,如果是多个loader的话,它是从后往前的顺序执行。

举个例子:

module.exports = {
  chainWebpack: config => {
    config.module.rule('changeName').test(/\.txt$/)
      .use('changeName').loader(require.resolve('./src/loader/changeName.js')).end()
      .use('changeName1').loader(require.resolve('./src/loader/changeName1.js')).end()
  }
}

loader先执行changeName1,再执行changeName