摘要:本次介绍的则是用来解决这类问题的。实现模块实现思路将配置内的命令的的内联从前至后组成一个数组。所有字符串内部又可以截取,获取完整的。分析并解析该数组内的字符串,获取各个的绝对路径。
前言
在webpack特性里面,它可以支持将非javaScript文件打包,但前面写到webpack的模块化打包只能应用于含有特定规范的JavaScript文件。本次介绍的loader则是用来解决这类问题的。本文章loader的实现基于code-splitting
功能分析举个例子:
webpack.config.js中的配置loader
module: { rules: [ { test: /.js$/, loader: "test-loader!test-loader2" } ] }
业务代码中的内联loader
require("d!c");
分析:
我们需要将这些loader解析成可运行的函数,并在parse模块解析语法树之前运行掉这些loader函数
所以我们需要:
resolve模块:分析出module对应的loader字符串,并解析出各个loader的绝对路径
buildDeps模块:通过文件路径获取需要运行的loader函数,将其压入队列,之后再依次按序递归出loader函数运行,如果是异步loader,则要通过回调函数来递归下一个loader函数。
实现 resolve 模块实现思路:
将配置内的loaders,shell命令的loaders,require/import的内联loader从前至后组成一个数组。配置内的loaders需要正则匹配test属性,来获取配置内的loader字符串。所有loader字符串内部又可以截取"!",获取完整的loader。
分析并解析该数组内的字符串,获取各个loader的绝对路径。并返回解析好的字符串。这块的实现和文件打包类似。
最终require内的字符串如下
/Users/zhujian/Documents/workspace/webpack/simple-webpack/example/node_modules/d.js! /Users/zhujian/Documents/workspace/webpack/simple-webpack/example/node_modules/test-loader/index.js! /Users/zhujian/Documents/workspace/webpack/simple-webpack/example/node_modules/test-loader2/index.js! /Users/zhujian/Documents/workspace/webpack/simple-webpack/example/node_modules/c.jsbuildDeps模块
实现思路:
解析文件路径,并获取需要运行的loader函数,存入数组
数组在通过pop函数一个个递归,考虑到存在异步loader函数的情况,需要为运行函数提供async,以及callback的上下文。具体的上下文可参考Loader API
loader递归逻辑如下:
nextLoader.apply(null, content); function nextLoader() { const args = Array.prototype.slice.apply(arguments); if (loaderFunctions.length > 0) { const loaderFunction = loaderFunctions.pop(); let async = false; const context = { fileName, options, debug: options.debug, async: function () { async = true; return nextLoader; }, callback: function () { async = true; nextLoader.apply(null, arguments) } }; const resVal = loaderFunction.apply(context, args); if (!async) { nextLoader(resVal); } } else { callback(null, args[0]) } }测试
将以上3个loader,test-loader,test-loader2,异步loader d.js,打包c.js
test-loader
module.exports = function(content) { return content+" exports.answer = 42; " }
test-loader2
module.exports = function(content) { return content+" exports.test2 = test2; " }
异步loader d.js
module.exports = function (content) { const d = "d"; this.async(); const b = content + " exports.d = 2000; "; setTimeout(this.callback.bind(this, b), 2000); }
c.js
const c = "c"; module.exports = c;
最终打包出来的c.js的代码如下
.... /* 1 */ /***/(function(module, exports,__webpack_require__) { const c = "c"; module.exports = c; exports.test2 = test2; exports.answer = 42; exports.d = 2000; /***/} ....代码实现
本人的简易版webpack实现simple-webpack
(完)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108049.html
摘要:笔者系贡献者之一官方说明简单来说就是将文件变成,然后放入浏览器运行。部分首先分析部分从做右到左,也就是被先后被和处理过了。源码解析之二源码解析之三写作中源码解析之四写作中作者博客作者微博 笔者系 vue-loader 贡献者(#16)之一 官方说明 vue-loader is a loader for Webpack that can transform Vue components ...
摘要:当前正在处理的节点,以及该节点的和等信息。源码解析之一整体分析源码解析之三写作中源码解析之四写作中作者博客作者作者微博 笔者系 vue-loader 贡献者之一(#16) 前言 vue-loader 源码解析系列之一,阅读该文章之前,请大家首先参考大纲 vue-loader 源码解析系列之 整体分析 selector 做了什么 const path = require(path) co...
摘要:流程划分纵观整个打包过程,可以流程划分为四块。核心类关系图功能实现模块通过将源码解析为树并拆分,以及直至基础模块。通过的依赖和切割文件构建出含有和包含关系的对象。通过模版完成主入口文件的写入,模版完成切割文件的写入。 前言 插件plugin,webpack重要的组成部分。它以事件流的方式让用户可以直接接触到webpack的整个编译过程。plugin在编译的关键地方触发对应的事件,极大的...
摘要:引言通过前面几张的铺垫下面开始分析源码核心流程大体上可以分为初始化编译输出三个阶段下面开始分析初始化这个阶段整体流程做了什么启动构建,读取与合并配置参数,加载,实例化。推荐源码之源码之机制源码之简介源码之机制参考源码 引言 通过前面几张的铺垫,下面开始分析webpack源码核心流程,大体上可以分为初始化,编译,输出三个阶段,下面开始分析 初始化 这个阶段整体流程做了什么? 启动构建,读...
摘要:执行完成后会返回如下图的结果,根据返回数据把源码和存储在的属性上的回调函数中调用类生成,并根据生成依赖后回调方法返回类。 webpack设计模式 一切资源皆Module Module(模块)是webpack的中的关键实体。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块. 通过Loaders(模块转换器),用于把模块原内容按照需求转换成新模块内容. 事件驱动架构 we...
阅读 1420·2023-04-25 19:00
阅读 4103·2021-11-17 17:00
阅读 1732·2021-11-11 16:55
阅读 1493·2021-10-14 09:43
阅读 3084·2021-09-30 09:58
阅读 824·2021-09-02 15:11
阅读 2092·2019-08-30 12:56
阅读 1372·2019-08-30 11:12