Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

读 minipack 源码 #7

Open
heycqing opened this issue Jan 8, 2020 · 0 comments
Open

读 minipack 源码 #7

heycqing opened this issue Jan 8, 2020 · 0 comments

Comments

@heycqing
Copy link
Owner

heycqing commented Jan 8, 2020

解读 minipack 源码

整体流程

  1. 同步读取入口文件,然后通过 babylon 解析js文件,再通过 babel-traverse 来操作js的语法树,再交给 babel-core 转码成现在浏览器可以跑起来的代码,

  2. 其中通过一个数组来保存已经构建好父文件和子文件的依赖关系,

      [ './message.js' ]
      [ './name.js' ]
      []
  3. 然后不断去遍历这个存有依赖关系的数组,得出另外一个数组,这个数组包含文件的索引id,文件名,它的依赖文件,还有通过 babel-core 转码出来的代码。

      queue: [ { id: 0,
          filename: './example/entry.js',
          dependencies: [ './message.js' ],
          code:
           '"use strict";\n\nvar _message = require("./message.js");\n\nvar _message2 = _interopRequireDefault(_message);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nconsole.log(_message2.default);',
          mapping: { './message.js': 1 } },
        { id: 1,
          filename: 'example/message.js',
          dependencies: [ './name.js' ],
          code:
           '"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n  value: true\n});\n\nvar _name = require("./name.js");\n\nexports.default = "hello " + _name.name + "!";',
          mapping: { './name.js': 2 } },
        { id: 2,
          filename: 'example/name.js',
          dependencies: [],
          code:
           '"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n  value: true\n});\nvar name = exports.name = \'world\';',
          mapping: {} } ]
  4. 最关键的是,通过遍历生成的 queue 数组 ,把 其中的 code 属性值 放进 CommomJs 模块规范的代码打包函数里。

      function (require, module, exports) {
        // 写的代码,即上面的 queue 数组对象中的不同对象的code属性的值
      })
  5. 最后一步就是,让浏览器读取到第4步打包好的代码,这里没有引入其他插件,是通过内部的代码块实现的。

    例子是下面的:

    (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(){console.log('hhhhh')}]})

    真实的代码如下:

        (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';
          },
          {},
        ],})

总结来说

通过babel解析代码成ES5代码,通过构建文件依赖关系,使用 commomJs 模块化打包文件,使用浏览器能理解的代码实现引入打包文件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant