webpack-Bundler源码编写(生成代码)

接下来我们要生成真正可以在浏览器中运行的代码:

const makeDependenciesGraph=entry=>{
    ...
}
const generateCode=entry=>{
    const graph=JSON.stringify(makeDependenciesGraph(entry));
    return `
        (function(graph)){}(${graph});
    `;
}

const code=generateCode('./src/index.js');
console.log(code);

输出:

(function(graph)){}({"./src/index.js":{"dependencies":{"./message.js":"src/message.js"},"code":""use strict";

var _message = _interopRequireDefault(require("./message.js"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

console.log(_message["default"]);"},"src/message.js":{"dependencies":{"./word.js":"src/word.js"},"code":""use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _word = require("./word.js");

var message = "say ".concat(_word.word);
var _default = message;
exports["default"] = _default;"},"src/word.js":{"dependencies":{},"code":""use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.word = void 0;
var word = 'hello';
exports.word = word;"}});

以上代码中含有require、exports等浏览器不支持的语法,还不能正确执行,所以我们还需要构造require函数和exports对象:

const generateCode=entry=>{
    const graph=JSON.stringify(makeDependenciesGraph(entry));
    return `
        (function(graph){
            function require(module){
                function localRequire(relativePath){
                    return require(graph[module].dependencies[relativePath])
                }
                var exports={};
                (function(require,exports,code){
                    eval(code);
                })(localRequire,exports,graph[module].code);
                return exports
            };
            require('${entry}');
        })(${graph});
    `;
}

const code=generateCode('./src/index.js');
console.log(code);

输出:

(function(graph){
    function require(module){
        function localRequire(relativePath){
            return require(graph[module].dependencies[relativePath])
        }
        var exports={};
        (function(require,exports,code){
            eval(code);
        })(localRequire,exports,graph[module].code);
        return exports
    };
    require('./src/index.js');
})({"./src/index.js":{"dependencies":{"./message.js":"src/message.js"},"code":""use strict";

var _message = _interopRequireDefault(require("./message.js"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

console.log(_message["default"]);"},"src/message.js":{"dependencies":{"./word.js":"src/word.js"},"code":""use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _word = require("./word.js");

var message = "say ".concat(_word.word);
var _default = message;
exports["default"] = _default;"},"src/word.js":{"dependencies":{},"code":""use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.word = void 0;
var word = 'hello';
exports.word = word;"}});

将以上代码复制到控制台,能正确打印出'say hello',至此,我们已经完成bundler打包代码。

原文地址:https://www.cnblogs.com/jingouli/p/12336384.html