接下来我们要生成真正可以在浏览器中运行的代码:
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打包代码。