webpack图解指南(模块化部分),前端开发工作

因此这里 webpack 利用 CommonJS/ ES Modules 规范进行了处理。使得各个模块之间相互引用无需考虑最终实际呈现的顺序。最终会被打包为一个 bunlde 模块,无需按照顺序手动引入。

baz.js

const bar = require(‘./bar.js’);

module.exports = function baz (){

bar();

}

abc.js

const bar = require(‘./bar.js’);

module.exports = function baz (){

bar();

}

image-20200627003815071

webpack 的模块化机制与实现


基于以上两项特性,模块的隔离以及模块的依赖聚合。我们现在可以非常清晰的知道了webpack所起的核心作用。

  • 为了尽可能降低编写的难度和理解成本,我没有使用 AST 的解析,(当然 AST 也不是什么很难的东西,以后的文章中我会讲解 AST是什么以及 AST 解析器的实现过程。

  • 仅实现了 CommonJS 的支持

bundle工作原理

为了能够实现 webpack, 我们可以通过反推的方法,先看webpack 打包后 bundle 是如何工作的。

「源文件」

// index.js

const b = require(‘./b’);

b();

// b.js

module.exports = function () {

console.log(11);

}

「build 后」(去除了一些干扰代码)

(function(modules) {

var installedModules = {};

function webpack_require(moduleId) {

if (installedModules[moduleId]) {

return installedModules[moduleId].exports;

}

var module = (installedModules[moduleId] = {

i: moduleId,

l: false,

exports: {},

});

modules[moduleId].call(

module.exports,

module,

module.exports,

webpack_require

);

module.l = true;

return module.exports;

}

return webpack_require((webpack_require.s = 0));

})([

/* 0 */

function(module, exports, webpack_require) {

var b = webpack_require(1);

b();

},

/* 1 */

function(module, exports) {

module.exports = function() {

console.log(11);

};

},

]);

image-20200627135324956

以上就是 bundle 的运作原理。通过上述的流程图我们可以看到,有四个关键点

  • 已注册模块(存放已经注册的模块)

  • 模块列表(用来存放所有的包装模块)

  • 模块查找(从原来的树形的模块依赖,变成了扁平查找)

  • 模块的包装(原有的模块都进行了一次包装)

webpack实现

通过 bundle 的分析,我们只需要做的就是 4 件事

  • 遍历出所有的模块

  • 模块包装

  • 提供注册模块、模块列表变量和导入函数

  • 持久化导出

模块的遍历

首先来介绍一下模块的结构,能使我们快速有所了解, 结构比较简单,由内容和模块id组成。

interface GraphStruct {

context: string;

moduleId: string;

}

{

“context”: `function(module, exports, require) {

const bar = require(‘./bar.js’);

const foo = require(‘./foo.js’);

console.log(bar());

foo();

}`,

“moduleId”: “./example/index.js”

}

接下来我们以拿到一个入口文件来进行讲解,当拿到一个入口文件时,我们需要对其依赖进行分析。说简单点就是拿到 require 中的值,以便我们去寻找下一个模块。由于在这一部分不想引入额外的知识,开头也说了,一般采用的是 AST 解析的方式,来获取 require 的模块,在这里我们使用正则。

用来匹配全局的 require

const REQUIRE_REG_GLOBAL = /require((“|')(.+)(”|'))/g;

用来匹配 require 中的内容

const REQUIRE_REG_SINGLE = /require((“|')(.+)(”|'))/;

const context = `

const bar = require(‘./bar.js’);

const foo = require(‘./foo.js’);

console.log(bar());

foo();

`;

console.log(context.match(REQUIRE_REG_GLOBAL));

// [“require(‘./bar.js’)”, “require(‘./foo.js’)”]

image-20200627202427794

由于模块的遍历并不是只有单纯的一层结构,一般为树形结构,因此在这里我采用了深度遍历。主要通过正则去匹配出require 中的依赖项,然后不断递归去获取模块,最后将通过深度遍历到的模块以数组形式存储。(不理解深度遍历,可以理解为递归获取模块)

image-20200627142130902

以下是代码实现

private entryPath: string

private graph: GraphStruct[]

createGraph(rootPath: string, relativePath: string) {

// 通过获取文件内容

const context = fs.readFileSync(rootPath, ‘utf-8’);

// 匹配出依赖关系

const childrens = context.match(REQUIRE_REG_GLOBAL);

// 将当前的模块存储下来

this.graph.push({

context,

moduleId: relativePath,

})

const dirname = path.dirname(rootPath);

if (childrens) {

// 如有有依赖,就进行递归

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

基础面试题

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

75547)]
[外链图片转存中…(img-yYs9pdwV-1710701575548)]
[外链图片转存中…(img-WamhWAsP-1710701575549)]
[外链图片转存中…(img-bxHrh8kz-1710701575549)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-dgJMiGPV-1710701575550)]

基础面试题

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值