code:https://github.com/ronami/minipack

看了https://www.youtube.com/watch?v=Gc9-7PBqOC8总结一下

工具和环境:

node环境;

依赖模块:

  fs:文件读取

  path:文件路径处理

  babylon:ast树的转换(https://astexplorer.net/

  babel-traverse:遍历ast数,查找所有依赖关系

  babel-core:用transformFromAst方法把ast数转换为js代码(此处的代码为babel解析过后的代码:https://babeljs.io/repl/,commonJs标准)

总体流程是为:根据entry路口文件,用babylon转换为ast树,从中查找所有的依赖管理,然后遍历依赖关系图,再把所有依赖的代码整合输出。

最后整合输出的代码如下:

(function(modules) {
function require(id) {
const [fn, mapping] = modules[id]; function localRequire(name) {
return require(mapping[name]);
} const module = { exports : {} }; fn(localRequire, module, module.exports); return module.exports;
} require(0);
})({0: [
function (require, module, exports) {
"use strict"; var _message = require("./message.js"); var _message2 = _interopRequireDefault(_message); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } console.log(_message2.default);
},
{"./message.js":1},
],1: [
function (require, module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
}); var _name = require("./name.js"); exports.default = "hello " + _name.name + "!";
},
{"./name.js":2},
],2: [
function (require, module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
});
var name = exports.name = 'world';
},
{},
],})

解析后大概流程如下:

1、自执行函数(fun(...){})(params)

2、fun代码

function fun1(modules) {// 接收modules对象
function require(id) {
const [fn, mapping] = modules[id];// 获取对应模块的 fn和依赖mapping function localRequire(name) { // 递归,请求所有依赖
return require(mapping[name]);
} const module = { exports : {} }; fn(localRequire, module, module.exports);//执行函数,因为require传入后,在fun方法体中会执行require方法请求依赖,故会先执行最底层的依赖。 return module.exports;
} require(0);
}

3、params

{0: [
function (require, module, exports) {
"use strict"; var _message = require("./message.js"); var _message2 = _interopRequireDefault(_message); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } console.log(_message2.default);
},
{"./message.js":1},
],1: [
function (require, module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
}); var _name = require("./name.js"); exports.default = "hello " + _name.name + "!";
},
{"./name.js":2},
],2: [
function (require, module, exports) {
"use strict"; Object.defineProperty(exports, "__esModule", {
value: true
});
var name = exports.name = 'world';
},
{},
],}
// key为模块的id,对应的value = [fun,mapping];
// fun为一个函数,接收require,modle,exports,fun里的内容是经过babel-core转换过的js代码
// mapping为依赖模块的id

  

当然,真正的打包还需要很多工作,如循环依赖、异常捕获及提示等等。此为冰山一角

webpack - minipack 打包原理的更多相关文章

  1. webpack打包原理

    什么是 webpack ? 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依 ...

  2. 0基础手把手教你搭建webpack运行打包项目(未完待续)

    这些天在项目之余的时间学习了webpack打包项目的东西,非常荣幸的找到一些大神的文章来学习,死劲嚼了几天,终于略知一二.在以后的工作上还需继续学习,下面我将分享我这几天学到的一点东西,希望能让我一个 ...

  3. WEBPACK & BABEL 打包项目

    本文首发于 BriFuture's Blog. 最近在用 Vue 重写之前的一个项目 Compass,这个项目以前是用 QML + JavaScript 在 Qt 平台上搭建的.这是我本科毕设时做的一 ...

  4. webpack 的编译原理

    自从接触了react,vue 这两个框架,都会用到webpack这个打包工具.面试的时候,经常被问到知道webpack的编译原理吗? 可以简单的介绍一下.每每这个时候都被问的哑口无言,平时用的时候挺顺 ...

  5. 如何编写一个WebPack的插件原理及实践

    _ 阅读目录 一:webpack插件的基本原理 二:理解 Compiler对象 和 Compilation 对象 三:插件中常用的API 四:编写插件实战 回到顶部 一:webpack插件的基本原理 ...

  6. 浅谈Webpack模块打包工具一

    为什么要使用模块打包工具 1.模块化开发ES Modules存在兼容性问题 打包之后成产阶段编译为ES5 解决兼容性问题 2.模块文件过多 网络请求频繁  开发阶段把散的模块打包成一个模块 解决网络请 ...

  7. Android 多渠道打包原理和使用

    每次中午吃饭总会和技术同学聊天.当做 iOS 开发的做安卓开发的人员在一起的时候,他们中间又多了一个话题:iOS 开发难还是安卓开发难. 这个时候做安卓开发的同学最激动说安卓开发要自己画界面.机型复杂 ...

  8. webpack独立打包与缓存处理

    关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 先前写了一篇webpack入门的文章<webpack入门必知必会>,简单介绍了webpa ...

  9. express整合webpack的打包文件dist

    对于我来说,第一次接触前后端整合问题的小白,刚开始是一脸懵逼,这个问题整整坑了我一个晚上加一个早上,现在写出来总结: 前端开发:vue-cli+webpack: 后台开发:nodejs框架expres ...

随机推荐

  1. 【转载】系统吞吐量(TPS)、用户并发量、性能测试概念和公式

    系统吞度量要素 一个系统的吞度量(承压能力)与request对CPU的消耗.外部接口.IO等等紧密关联.单个reqeust 对CPU消耗越高,外部系统接口.IO影响速度越慢,系统吞吐能力越低,反之越高 ...

  2. python数据库多字段插入

    # -*- co;ding: utf-8 -*-#企业详细信息写入数据库+征信得分import pymysqlfrom impala.dbapi import connect conn = pymys ...

  3. loadrunner转码两种方式

    1.//使用转换函数将resp值做编码转换并存入msg lr_convert_string_encoding(“佛挡杀佛”),"utf-8",NULL,"msg" ...

  4. 在多机器上远程执行JMeter

    安装完jmeter之后直接执行%InstallDir%\apache-jmeter-3.2\bin\JMeter.bat可以启动UI界面,可以编辑或者执行TestPlan等,默认情况下,用例是在本机执 ...

  5. Vue-admin工作整理(六):路由元信息

    路由源信息:每一个路由对象,可以配置一个meta字段,它里面可以存放一些我们定义的信息,比如说页面是否需要一个权限 to.meta && setTitle(to.meta.title) ...

  6. hbase调优配置项笔记

    gc配置 hbase-env.sh export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC" export HBASE_OPT ...

  7. jquery清除某一结点下的子节点

    jquery清除某一结点下的子节点:这个情况多用于数据的加载中,如果当执行某一操作之后,想重新加载页面,但是又不想整个页面都重新加载,这个时候就可以使用该方法, case:   $("#ta ...

  8. linux下初始化mysql时报错

    执行mysqld --initialize后报错 报错内容: 019-04-24 18:07:59 0 [Warning] TIMESTAMP with implicit DEFAULT value ...

  9. 第二章 Java 基本语法1

    2.1关键字 1.定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词). 2.特点:关键字中所有字母都是小写字母. 3.分类: 用于定义数据类型的关键字:byte.short.int.lo ...

  10. TreeMap/LinkedHashMap/HashMap按键排序和按值排序

    今天做统计时需要对X轴的地区按照地区代码(areaCode)进行排序,由于在构建XMLData使用的map来进行数据统计的,所以在统计过程中就需要对map进行排序. 一.简单介绍Map 在讲解Map排 ...