前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编写一个 Webpack 的 loader

编写一个 Webpack 的 loader

作者头像
EchoROne
发布2022-08-15 08:29:16
2600
发布2022-08-15 08:29:16
举报
文章被收录于专栏:玩转大前端

使用Webpack往往离不开loader的安装配置,手写一个loader其实非常简单,类似手写一个功能函数,下面我们来实现一个替换字符串的loader

初始化项目

创建一个根目录mack-loader,此目录下 npm init -y生成默认的package.json文件 ,在文件中配置打包命令

代码语言:javascript
复制
"scripts": {
  "build": "webpack"
}

之后npm i -D webpack webpack-cli,安装完webpack,在根目录 创建配置文件webpack.config.js

代码语言:javascript
复制
const path = require('path')

module.exports = {
  mode: 'development', // 先设置为development,不压缩代码,方便调试
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  }
}

在根目录创建一个src目录,里面创建index.js,输入console.log('hello, world')

之后运行npm run build即可打包项目,初始化项目完成

编写 replace-loader

根目录创建loaders文件夹,里面创建replaceLoader.js

代码语言:javascript
复制
const loaderUtils = require('loader-utils');

module.exports = function (source) {
  const options = loaderUtils.getOptions(this);
  const result = source.replace('world', options.name);
  return result;
}

这里我们采用官方推荐的loader-utils读取options配置,也可用this.query获取配置对象,name是我们在loader配置项输入的字段名,source是源文件内容,最后需要返回,注意这里不能使用箭头函数,否则this指向会有错误,之后便可在webpack.config.js配置文件使用这个loader

代码语言:javascript
复制
  module: {
    rules: [{
      test: /\.js$/,
      use: {
        loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
        options: {
          name: 'echo'
        }
      }
    }]
  }

效果是会把world替换为name中得字符串,npm run build 后在main.js里面则可以看到此效果

loader 返回更多内容

官方文档配置的 API 中loader的许多API ,除了this.query,常用的还有this.callback

代码语言:javascript
复制
this.callback(
  err: Error | null,
  content: string | Buffer,
  sourceMap?: SourceMap, // 可选参数,返回source-map
  meta?: any // 可选参数,返回meta
);

可使用此API替代return

代码语言:javascript
复制
const loaderUtils = require('loader-utils');

module.exports = function (source) {
  const options = loaderUtils.getOptions(this);
  const result = source.replace('world', options.name);
  // return result;
  this.callback(null, result);
}

loader 中编写异步代码

loader中编写异步代码需要用this.async,我们可以再实现一个异步loader,创建replaceLoderAsync.js

代码语言:javascript
复制
const loaderUtils = require('loader-utils');

module.exports = function (source) {
  const options = loaderUtils.getOptions(this);
  const callback = this.async()

  setTimeout(() => {
    const result = source.replace('world', options.name);
    callback(null, result)
  }, 1000)
}

其中this.async返回的是this.callback,因此可以当做return来使用,将replaceLoder.js中的代码改为

代码语言:javascript
复制
module.exports = function (source) {
  const result = source.replace('echo', 'world');
  this.callback(null, result)
}

我们实现先调用异步loader,将world改为echo,之后再调用同步loaderecho改为world,在配置文件的相应配置为

代码语言:javascript
复制
const path = require('path')

module.exports = {
  mode: 'development', // 先设置为development,不压缩代码,方便调试
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  resolveLoader: {
    // 会依次在node_modules、loaders文件夹中查找是否存在对应loader
    modules: ['node_modules', './loaders'] 
  },
  module: {
    rules: [{
      test: /\.js$/,
      use: [{
        loader: 'replaceLoader.js'
      },{
        loader: 'replaceLoaderAsync.js',
        options: {
          name: 'echo'
        }
      }]
    }]
  }
}

之后运行npm run build即可在distmain.js验证效果

编写loader的应用场景

  1. 监控前端方法错误:可以自己编写loader检测业务代码中含有function关键字时自动用try...catch...包含代码块捕获错误,可以避免自己手写try...catch...导致的业务代码的臃肿
  2. 实现网站的中英文替换:可以将文字用占位符包裹,检测到占位符则根据环境变量替换为中英文,伪代码如下
代码语言:javascript
复制
module.exports = function (source) {
  if(Node全局变量 === '中文') {
    source.replace('{{title}}', '中文标题')
  } else {
    source.replace('{{title}}', 'english title')
  }

  const result = source.replace('echo', 'world');
  this.callback(null, result)
}

总结

完整的代码可以参考我的github项目,欢迎starhttps://github.com/zyqq/make-loader

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化项目
  • 编写 replace-loader
  • loader 返回更多内容
  • loader 中编写异步代码
  • 编写loader的应用场景
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档