首页 > 其他分享 >Webpack中手动实现Loader与Plugin

Webpack中手动实现Loader与Plugin

时间:2023-04-17 15:10:00浏览次数:31  
标签:function index Plugin webpack js loader Webpack module Loader

Loader

loader 是一个转换器,用于对源代码进行转换。

工作流程

  1. webpack.config.js 里配置了一个 模块 的 Loader;
    2.遇到 相应模块 文件时,触发了 该模块的 loader;
    3.loader 接受了一个表示该 模块 文件内容的 source;
    4.loader 使用 webapck 提供的一系列 api 对 source 进行转换,得到一个 result;
    5.将 result 返回或者传递给下一个 Loader,直到处理完毕。

举个例子。

loader.js (将所有含有“小明”字符串 全都改为“老王”)

module.exports = function (source){
  return source.replace('小明','老王')
}

webpack.config.js

const path = require('path')

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js' //入口文件
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: path.resolve('./src/loader.js'), //我们自己实现的loader
                    },
                ]
            }
        ]
    },
}

index.js(入口文件)

function test() {
  console.log('你好我是小明')
}
test()

编译后等待输出结果:
bound.js

/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/***/ (() => {

eval("function test() {\n  console.log('你好我是老王')\n}\n\ntest()\n\n\n//# sourceURL=webpack:///./src/index.js?"); //小明变成老王了

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module can't be inlined because the eval devtool is used.
/******/ 	var __webpack_exports__ = {};
/******/ 	__webpack_modules__["./src/index.js"]();
/******/ 	
/******/ })()
;

上述打包耗时:77ms

异步Loader

loader.js如下

module.exports = function (source) {
  const callback = this.async()

  // 由于有 3 秒延迟,所以打包时需要 3+ 秒的时间
  setTimeout(() => {
    callback(null, `${source.replace('小明', '老王')}`)
  }, 3000)
}

上述打包耗时:3083ms

Plugin

webpack 在整个编译周期中会触发很多不同的事件,plugin 可以监听这些事件,并且可以调用 webpack 的 API 对输出资源进行处理。这是它和 loader 的不同之处,loader 一般只能对源文件代码进行转换,而 plugin 可以做得更多。plugin 在整个编译周期中都可以被调用,只要监听事件。

名词解释

对于 webpack 编译,有两个重要的对象需要了解一下:

Compiler 和 Compilation
在插件开发中最重要的两个资源就是 compiler 和 compilation 对象。理解它们的角色是扩展 webpack 引擎重要的第一步。
compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。

组成部分:

  1. 一个 JavaScript 命名函数。
  2. 在插件函数的 prototype 上定义一个 apply 方法。
  3. 指定一个绑定到 webpack 自身的事件钩子。
  4. 处理 webpack 内部实例的特定数据。
  5. 功能完成后调用 webpack 提供的回调

举个例子

plugin.js

function Plugin(options) { }

Plugin.prototype.apply = function (compiler) {
    // 所有文件资源都被 loader 处理后触发这个事件
    compiler.plugin('emit', function (compilation, callback) {
        // 功能完成后调用 webpack 提供的回调
        console.log('Hello World')
        callback()
    })
}

module.exports = Plugin

使用:

const Plugin = require('./src/plugin')

module.exports = {
	...
    plugins: [
        new Plugin()
    ]
}

更复杂的例子:
经过 loader 处理后的打包文件 bundle.js 引入到 index.html 中:

function Plugin(options) { }

Plugin.prototype.apply = function (compiler) {
    // 所有文件资源经过不同的 loader 处理后触发这个事件
    compiler.plugin('emit', function (compilation, callback) {
        // 获取打包后的 js 文件名
        const filename = compiler.options.output.filename
        // 生成一个 index.html 并引入打包后的 js 文件
        const html = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="${filename}"></script>
</head>
<body>
    
</body>
</html>`
        // 所有处理后的资源都放在 compilation.assets 中
        // 添加一个 index.html 文件
        compilation.assets['index.html'] = {
            source: function () {
                return html
            },
            size: function () {
                return html.length
            }
        }

        // 功能完成后调用 webpack 提供的回调
        callback()
    })
}

module.exports = Plugin

使用方式如上
结果:会生成一个html并且自动引入了bound.js

长风破浪会有时,直挂云帆济沧海



标签:function,index,Plugin,webpack,js,loader,Webpack,module,Loader
From: https://blog.51cto.com/u_15726982/6195159

相关文章

  • Splunk DB Connect 连接MySQL报错CLIENT_PLUGIN_AUTH is required
    01、问题描述使用SplunkDBConnect连接MySQL数据库读库时,报错CLIENT_PLUGIN_AUTHisrequired,如下图:02、原因分析根据报错信息,查阅相关资料,了解到报错原因:目标数据库为MySQL5.7,使用的mysql-connector-java-8.0.28.jar,mysql的jar包版本过高。JDBC数据库驱动程序:mysql-connector-......
  • MySQL McAfee审计插件Audit Plugin安装
     MySQLMcAfee审计插件AuditPlugin安装 官网下载:https://github.com/trellix-enterprise/mysql-audit/releases官方文档:https://github.com/trellix-enterprise/mysql-audit/wiki防爬虫:https://www.cnblogs.com/PiscesCanon/p/17324406.html  注意要对应你的数据库软......
  • webpack处理环境变量
    1、问题:布置一个koa上传文件服务时,在线上报错,但是本地运行没问题2、思路:经检查是路径问题,项目上传服务器的时候经过webpack打包后,文件的上传的路径出现变化,这时需要本地和线上配置不同的路径,也就是说需要布置环境development和production3、解决:设置环境变量,需要用到cro......
  • Jenkins: Kubernetes Plugin
     envinjenkinscontroller  Jenkinsdynamicslaveagent      PodTemplateinJenkinsUI    Examplefromgitpipeline{agent{kubernetes{cloud'kubernetes'defaultContainer'mav......
  • java maven-plugin-shade插件 Maven生成的jar运行出现“没有主清单属性”
    命令窗口运行jar,提示“没有主清单属性”  2.1分析问题在打包构建的jar目录内,可以看到有一个MANIFEST.MF文件,如图所示:该文件就是jar运行时要查找的清单目录,其中主清单数据,就是我们要运行的主类(函数入口main所在的类);提示缺少主清单属性,就是文件中少了主清单属性如下所示:正......
  • 给webpack提了一个pr之后......
    前言我不是标题党啊,是真的给webpack提了一个pr,提交之后,脑子里就是一句话:“纸上学来终觉浅,绝知此事要躬行”。欲知来龙去脉,听我娓娓道来。pr如下,<https://github.com/webpack/webpack/pull/16292>,目前还是unreviewed状态。\\阅读此文章你将会了解以下知识点,webstrom调试webpack源......
  • Dynamics 365 安装插件注册工具 PluginRegistration
    1.创建文件夹,例:D:\Dynamics_365_Development_Tools\pluginsTool2.powershell进入D:\Dynamics_365_Development_Tools\pluginsTool3.运行下面指令(直接复制粘贴到PowerShell即可),运行完成后按回车[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::T......
  • Plugin 'maven-surefire-plugin:2.12.4' not found(已解决)
    今天按照视频教程配置maven插件(maven-surefire-plugin)时,老师说这是maven内部的插件,可以不用写<groupId></groupId>标签,然后就报红:Plugin'maven-surefire-plugin:2.12.4'notfound也就是说这个插件找不到,于是添加<groupId>org.apache.maven.plugins</groupId>,刷新maven即可解决,......
  • 使用appuploader工具发布证书和描述性文件教程
    使用APPuploader工具发布证书和描述性文件教程之前用AppCan平台开发了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到AppStore试试,于是找同学借了个苹果开发者账号,但没那么简单,还要用到Mac电脑的钥匙串申请发布证书和上传ipa,可没有Mac,同学的大老远的也不方便拿过来......
  • 使用appuploader工具发布证书和描述性文件教程
     使用APPuploader工具发布证书和描述性文件教程之前用AppCan平台开发了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到AppStore试试,于是找同学借了个苹果开发者账号,但没那么简单,还要用到Mac电脑的钥匙串申请发布证书和上传ipa,可没有Mac,同学的大老远的也不方......