如何编写一个 Webpack Loader的实现

前言

在平时自己由零搭建项目时,虽然基础配置都比较熟悉,比如配置 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) // replaceString
 const 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 应用场景

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

到此这篇关于如何编写一个 Webpack Loader的实现的文章就介绍到这了,更多相关Webpack Loader实现内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解webpack进阶之loader篇

    webpack的loaders是一大特色,也是很重要的一部分.这遍博客我将分类讲解一些常用的laoder 一.loaders之 预处理 css-loader 处理css中路径引用等问题 style-loader 动态把样式写入css sass-loader scss编译器 less-loader less编译器 postcss-loader scss再处理 npm install --save -dev css-loader style-loader sass-loader less-loade

  • webpack源码之loader机制详解

    loader概念 loader是用来加载处理各种形式的资源,本质上是一个函数, 接受文件作为参数,返回转化后的结构. loader 用于对模块的源代码进行转换.loader 可以使你在 import 或"加载"模块时预处理文件.因此,loader 类似于其他构建工具中"任务(task)",并提供了处理前端构建步骤的强大方法.loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL.loader

  • webpack3之loader全解析

    首先亮出webpack官方网站,webpack能干什么?官网给出的答案就是,一句话,让一切变得简单! 各式各样的loader层出不穷,让我们在构建时不知所措,于此,总结下loader的全解析. 概念 loader,顾名思义,加载器,英文的解释如下: Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you impor

  • 详解webpack自定义loader初探

    最近负责的Weex项目涉及到一些构建上的问题,需要通过自定义webpack的loader去实现,于是学习了一下这方面的知识,写一篇文章做个总结,以免遗忘. webpack想必前端圈的人都知道了,大多数人也都或多或少的用过.简单的说就是它能够加载资源文件,并对这些文件进行一些处理,诸如编译.压缩等,最终一起打包到指定的文件中.可以说,它作为一个打包工具,在前端工程化浪潮中,起到了中流砥柱的作用. 那webpack其中非常重要的一环就是,能够对加载的资源文件,进行一些处理.比如把less.sass文

  • 详解webpack loader和plugin编写

    1 基础回顾 首先我们先回顾一下webpack常见配置,因为后面会用到,所以简单介绍一下. 1.1 webpack常见配置 // 入口文件 entry: { app: './src/js/index.js', }, // 输出文件 output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), publicPath: '/' //确保文件资源能够在 http://localhost:3000 下正确访问

  • 如何编写一个 Webpack Loader的实现

    前言 在平时自己由零搭建项目时,虽然基础配置都比较熟悉,比如配置 file-loader, url-loader, css-loader 等,配置不难,但究竟是怎么起作用的呢,今天就来说说如何编写一个 Webpack Loader. Loader 作用 按我自己的简单理解,loader 通常指打包的方案,即按什么方式来处理打包,打包的时候它可以拿到模块源代码,经过特定 loader 的转换后返回新的结果. 比如 sass-loader 可以把 SCSS 代码转换成 CSS 代码 编写 Loade

  • 详解使用webpack打包编写一个vue-toast插件

    本文介绍了使用webpack打包编写一个vue插件,分享给大家.具体如下: 一.说明: 需求:创建一个toast插件 思路:利用vue组件创建模板,使用webpack打包生成插件再全局使用. # 项目目录: |_ package.json |_ webpack.config.js |_ .babelrc |_ dist |_ src |_ index.html |_ lib |_ index.js |_ vue-toast.vue 1.1 webpack基础 1.基础插件 - html-webp

  • 详解Webpack loader 之 file-loader

    简介 安装 npm install --save-dev file-loader 用法 默认情况下,生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名. import img from './webpack-logo.png' webpack.config.js module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', option

  • 利用yarn实现一个webpack+react种子

    一.初始化项目 首先确保你的node 版本 >=4.0.并且确保yarn可以正常工作,关于安装yarn,你可以看这里 我们先创建个空文件夹 比如yarn-react-webpack-seed,然后输入命令: yarn init yarn 如果没有安装,全程用 npm代替也没问题. 项目会初始化 package.json ,然后填写一些基本信息即可. 接下来我们开始安装依赖项,再 package.json 的添加下面内容 "dependencies": { "react&

  • 80行代码写一个Webpack插件并发布到npm

    1. 前言 最近在学习 Webpack 相关的原理,以前只知道 Webpack 的配置方法,但并不知道其内部流程,经过一轮的学习,感觉获益良多,为了巩固学习的内容,我决定尝试自己动手写一个插件. 这个插件实现的功能比较简单: 默认清除 js 代码中的 console.log 的打印输出: 可通过传入配置,实现移除 console 的其它方法,如 console.warn.console.error 等: 2. Webpack 的构建流程以及 plugin 的原理 2.1 Webpack 构建流程

  • 如何编写一个创建FTP站点的函数?

    如何编写一个创建FTP站点的函数?Function ASTCreateFtpSite(IPAddress, RootDirectory, ServerComment, HostName, PortNum, Computer, Start,LogFileDirectory)    Dim MSFTPSVC, FtpServer, NewFtpServer, NewDir    Dim Bindings, BindingString, NewBindings, Index, SiteObj, bDo

  • 如何编写一个过滤掉HTML代码的函数?

    如何编写一个过滤掉HTML代码的函数?<%Function Filterhtml(strToFilter)  Dim strTemp  strTemp = strToFilter  While Instr(1,strTemp,"<") AND Instr(1, strTemp, ">")    strTemp = Left(strTemp, Instr(1, strTemp, "<")-1) & Right(str

  • JQuery入门—编写一个简单的JQuery应用案例

    一.官方网站下载:http://jquery.com 二.引入JQuery文件库 下载完后不用安装,只需将文件导入页面中即可,即在<head></head>中加入如下代码:<script language="javascript" type="text/javascript" src="jquery-1.8.3.min.js"></script> 三.编写一个弹出对话框的简单应用. 复制代码 代码如

  • 使用vue编写一个点击数字计时小游戏

    使用vue编写一个点击数字计时小游戏,列入你在文本框中输入3,点击开始会生成一个3行3列的表格,表格数据为1-9随机排列,这时候从1开始点击,按顺序点到9,当按正确顺序点击完毕,会提示所用的时间,如果顺序没有按对,会提示游戏结束. 1.首先下载vue源码,下载地址http://cn.vuejs.org 2.jquery是在面向dom操作,而vue是面向数据操作的,所以使用vue最好不要去操作dom,尽量发挥出vue的独到之处,(如果使用过angularjs可能更容易理解) 3.建立一个普通的ht

  • Bootstrap编写一个同时适用于PC、平板、手机的登陆页面

    Bootstrap如同前台框架,它已经布置好不少的CSS,前端开发的使用需要则直接调用即可.其网站的网址就是http://www.bootcss.com.使用Bootstrap能减少前端开发时候在CSS样子的布置时间 需要使用Bootstrap先在官网(点击打开链接)下载组件即可,用于生产环境的Bootstrap版本(点击打开链接),Bootstrap3对2并不兼容,建议直接根据其开发文档使用Bootstrap3. 将Bootstrap解压之后把得到的3个文件夹css,fonts,js拷贝到站点

随机推荐