前言

在平时自己由零搭建项目时,虽然基础配置都比较熟悉,比如配置 file-loader, url-loader, css-loader 等,配置不难,但究竟是怎么起作用的呢,今天就来说说如何编写一个 Webpack Loader。

Loader 作用

按我自己的简单理解,loader 通常指打包的方案,即按什么方式来处理打包,打包的时候它可以拿到模块源代码,经过特定 loader 的转换后返回新的结果。

比如 sass-loader 可以把 SCSS 代码转换成 CSS 代码

编写 Loader

保持功能单一

我们项目中可能会配置很多,但要记住,要保持一个 Loader 的功能单一,避免做多种功能,只需完成一种功能转换即可。

所以如 less 文件转换成 css 文件,也不是一步到位,而是 less-loader, css-loader, style-loader 几个 loader 的链式调用才能完成转换。

模块

因为 Webpack 本身是运行在 Node.js 之上的,一个 loader 其实就是一个 node 模块,这个模块导出的是一个函数,即:

module.exports = function (source) {// source 为 compiler 传递给 Loader 的一个文件的原内容// 处理...return source // 需要返回处理后的内容
}
复制代码

这个导出的函数的工作就是获得处理前的原内容,对原内容执行处理后,返回处理后的内容。

替换字符串的 loader

比如我们打包时,想要替换源文件的字符串,这时可以考虑使用 Loader,因为 loader 就是获得源文件内容然后对其进行处理,再返回。

比如 src 目录下有三个文件:

src/msg1.js

export const msg1 = '学习框架'
复制代码

src/msg2.js

export const msg2 = '深入理解JS'
复制代码

src/index.js

import { msg1 } from './msg1'
import { msg2 } from './msg2'function print() {console.log(`输出:${msg1}, ${msg2}`)
}print()
复制代码

做的事情则是把 msg1 和 msg2 两个文件导入,然后输出两个字符串。

我们要做的事也很简单,把"框架"转为"React 框架", "JS"转为"JavaScript"。

新建 src/loaders/replaceLoader.js文件,

module.exports = function (source) {const handleContent = source.replace('框架', 'React框架').replace('JS', 'JavaScript')return handleContent
}
复制代码

就这样,loader 写完了!!!

上面我们讲到,source 是源文件内容,如果打印的话,则是:

使用 Loader

接下来,我们要来使用它,在根目录下新建文件 webpack.config.js

const path = require('path')module.exports = {mode: 'production',entry: './src/index.js',module: {rules: [{test: /\.js$/,use: './src/loaders/replaceLoader.js',},],},output: {path: path.resolve(__dirname, 'dist'),filename: '[name].js',},
}
复制代码

执行npx webpack, 查看打包结果dist/main.js

(()=>{"use strict";console.log("输出:学习React框架, 深入理解JavaScript")})();
复制代码

替换成功!

需要注意的是,use里面填写的 loader 是去node_modules目录里面找的,由于我们是自定义的 loader,所以不能直接写use: 'replaceLoader',但直接写路径的方式未免难看点,我们可以通过 webpack 来配置:

module.exports = {resolveLoader: {modules: ['node_modules', './src/loaders'], // node_modules找不到,就去./src/loaders找},module: {rules: [{test: /\.js$/,use: 'replaceLoader',},],},
}
复制代码

获取 loader 的 options

写完之后,让我们来想想,其实就是写一个功能函数嘛。

当然,这只是最简单的例子,如果 loader 可以传入参数呢,比如:

module: {rules: [{test: /\.js$/,use: {loader: 'replaceLoader',options: {params: 'replaceString',},},},],
},
复制代码

这个时候可以使用this.query来获取,通过this.query.params就能拿到,这里需要注意的是,this 上下文是有用的,所以这个 loader 导出函数不能是箭头函数。

但 webpack 更推荐loader-utils模块来获取,它提供了许多有用的工具,最常用的一种工具是获取传递给 loader 的选项。

首先要安装

npm i -D loader-utils
复制代码

修改src/loaders/replaceLoader.js

const { getOptions } = require('loader-utils')module.exports = function (source) {console.log(getOptions(this)) // { params: 'replaceString' }console.log(this.query.params) // replaceStringconst handleContent = source.replace('框架', 'React框架').replace('JS', 'JavaScript')return handleContent
}
复制代码

这里需要注意的是,getOptions(this)参数传入的是 this,也就是说

打印结果:

{ params: 'replaceString' }
{ params: 'replaceString' }
{ params: 'replaceString' }
复制代码

this.callback()

上面都是返回原来内容转换后的内容,但有些场景下还需要返回其他东西比如 sourceMap

module.exports = function (source) {// 告诉 Webpack 返回的结果this.callback(null, source, sourceMaps)
}
复制代码

另外也不需要 return 了,所以也可使用此 API 替代 return

const { getOptions } = require('loader-utils')module.exports = function (source) {const handleContent = source.replace('框架', 'React框架').replace('JS', 'JavaScript')this.callback(null, handleContent)
}
复制代码

自定义 loader 应用场景

  1. 在所有 function 外面加一层 try catch 代码块捕获错误,避免手动繁琐添加。
  2. 实现中英文替换:可以将文字用占位符如{{ title }}包裹,检测到占位符则根据环境变量替换为中英文。

如何编写一个 Webpack Loader相关推荐

  1. 实现一个 webpack loader

    官网上的定义:loader 是一个转换器,用于对源代码进行转换. 例如 babel-loader 可以将 ES6 代码转换为 ES5 代码.sass-loader 将 sass 代码转换为 css 代 ...

  2. 如何编写一个webpack插件

    放个链接: https://segmentfault.com/a/1190000012840742 转载于:https://www.cnblogs.com/xuzishuai/p/9066021.ht ...

  3. Webpack: Loader 开发分享

    Webpack: Loader 开发分享 文章目录 Webpack: Loader 开发分享 正文 1. Concept 概念 2. Configuration 配置实例 3. Custom 自定义 ...

  4. loader 编写一个android_Android之Loader理解

    关于我: 90后全栈独立开发者,18 年至今为一名自由职业者,19年成立AgileStudio工作室,提供靠谱的软件定制服务. 在看Android的文档时,看到了这么一个东西: Loader 究竟是什 ...

  5. webpack loader的套路

    学习webpack loader,最后模拟style-loader.less-loader 什么是loader loader是一个函数,用来把文件转换成webpack识别的模块. loader API ...

  6. 一次搞懂Webpack Loader

    50 亿观众的 "云上奥运",顶级媒体背后的数智化力量 东京 2020 奥运会即将闭幕,本届奥运会由于疫情限制,东京地区赛事以无观众的空场形式举行,在无法亲临现场的情况下,全球观众 ...

  7. 【javascript】手写一个webpack loder

    [javascript]手写一个webpack loder 手写一个loader 为什么需要loader?  webpack 实际上只能处理js文件,那么对于除了js文件的其他类型的文件 比如 css ...

  8. 用 TypeScript 编写一个 React 服务端渲染库(1)

    前言 代码都甩在 Github 上面了,欢迎随手 star ? 踩坑的过程大概都在 TypeScript + Webpack + Koa 搭建 React 服务端渲染 这篇文章里面 踩坑的 DEMO ...

  9. 从零开始编写一个vue插件

    title: 从零开始编写一个vue插件 toc: true date: 2018-12-17 10:54:29 categories: Web tags: vue mathjax 写毕设的时候需要一 ...

最新文章

  1. 重要通知:招募200程序员,免费培训金融知识,不限年龄,有意者进!
  2. 巴蒂电信在泰米尔纳德邦推出4G Advanced网络
  3. spring in action 7.1 小结
  4. 3、HTML导入外部样式表(HTML导入CSS文件)
  5. 程序运行的时间的估算
  6. 2006年上海交通大学计算机研究生机试真题
  7. 学习进度(2016.3.13)
  8. 分布式监控系统Zabbix-3.0.3-完整安装记录(4)-解决zabbix监控图中出现中文乱码问题...
  9. 『总结』CSS/CSS3常用样式与web移动端资源
  10. Ubuntu16.04_Anaconda_TensorFlow(CPU)_py2.7及conda相关操作
  11. Java入门:JDK与Eclipse之类的集成开发工具的关系
  12. 如何通过Geth、Node.js和UNIX/PHP访问以太坊节点 1
  13. NVIDIA Nsight Compute 界面认识
  14. win10系统怎么把语言栏弄回去
  15. 关于@Result注解的说明
  16. 不会吧,你还以为微信分账能解决“二清”?
  17. 围观知乎真福利话题,放松一下。
  18. 经济学原理上中国故事2019尔雅满分答案
  19. Mac电脑如何实现Word一键转PPT
  20. RobotStudio 建立机器人模型和虚拟示教器的使用

热门文章

  1. Java JDK API文档下载
  2. 王垠:我为什么不在乎人工智能
  3. shiro系列-1.总览
  4. ArcSDE 注册与压缩
  5. 如何形象地理解四元数?
  6. [C语言]宏定义#define的使用详解
  7. RFID智能书柜的功能与应用
  8. Android Studio—单击定位打开
  9. springboot+redis实现热搜
  10. 百度杯WriteUp