动手实现webpack

287 阅读1分钟
 const fs = require("fs");
 const babylon = require("babylon");
 const traverse = require("babel-traverse").default;
 const {
   transformFromAst
 } = require('babel-core');

 module.exports = {
   // 通过 babylon 将源码生成AST:可以将 ES6 语法转换成 ES5 的语法·
   getAST: (path) => {
     const source = fs.readFileSync(path, "utf-8");
     return babylon.parse(source, {
       sourceType: "module",
     });
   },
   //获取依赖文件 
   getDependencies: (ast) => {
     const getDependencies = [];
     traverse(ast, {
       ImportDeclaration: ({
         node
       }) => {
         getDependencies.push(node.source.value);
       },
     });
     return getDependencies;
   },
   //将AST重新生成源码
   transform: (ast) => {
     const {
       code
     } = transformFromAst(ast, null, {
       presets: ['env'],
     });
     return code;
   },
 };

webpack内部机制:

截屏2021-08-16上午8.57.24.png

动手实现:

 emitFiles() { 
        const outputPath = path.join(this.output.path, this.output.filename);
        let modules = '';
        this.modules.map((_module) => {
            modules += `'${ _module.filename }': function (require, module, exports) { ${ _module.transformCode } },`
        });
        
        const bundle = `
            (function(modules) {
                function require(fileName) {
                    //获取文件对应的源码
                    const fn = modules[fileName];
        
                    const module = { exports : {} };
 
                    fn(require, module, module.exports);
        
                    return module.exports;
                }

                require('${this.entry}');
            })({${modules}})
        `;
    
        fs.writeFileSync(outputPath, bundle, 'utf-8');
    }

输出: 截屏2021-08-16上午9.05.20.png