code:https://github.com/ronami/minipackjavascript
看了https://www.youtube.com/watch?v=Gc9-7PBqOC8总结一下java
工具和环境:node
node环境;git
依赖模块:github
fs:文件读取babel
path:文件路径处理app
babylon:ast树的转换(https://astexplorer.net/)函数
babel-traverse:遍历ast数,查找全部依赖关系工具
babel-core:用transformFromAst方法把ast数转换为js代码(此处的代码为babel解析事后的代码:https://babeljs.io/repl/,commonJs标准)ui
整体流程是为:根据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'; }, {}, ],})
解析后大概流程以下:
一、自执行函数(fun(...){})(params)
二、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); }
三、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
固然,真正的打包还须要不少工做,如循环依赖、异常捕获及提示等等。此为冰山一角