zoukankan      html  css  js  c++  java
  • webpack原理-实现webpack打包js

    // 这里导入webpack配置,我用对象的形式表示,当然entry属性上定义的文件要有
    // const config = require("./webpack.config");
    const config = { entry: './src/index.js' };
    
    const { join, dirname } = require("path");
    const { readFileSync, writeFileSync } = require("fs");
    const reg = /(?<=froms+['"])[./w]+(?=['"])/g;
    
    class Complier {
      constructor({ entry }) {
        this.entry = entry;
      }
      run() {
        writeFileSync('generateFile.js', generateCode(this.entry));
      }
    }
    
    const parser = (entry, prePath = '.') => {
        let temp = null;
        const filePath = `./${join(prePath, entry)}`;
        const code = Buffer.from(readFileSync(filePath)).toString();
        const dependencies = {};
        // 通过正则将当前文件es导入的模块识别并存到dependencies里,注释也会存起来,请不要写注释
        while ((temp = reg.exec(code)) !== null) {
          temp.forEach(filePath => {
            dependencies[filePath] = `./${join(prePath, dirname(entry), filePath)}`;
          })
        }
        
        return {
          filePath,
          dependencies,
          code,
        };
      }
    
    const makeDependenciesGraph = (entry) => {
      const entryModule = parser(entry);
      const graphArray = [entryModule];
      // 利用广度遍历的思想遍历一遍
      for (let i = 0; i < graphArray.length; i++) {
        const { dependencies } = graphArray[i];
        if (dependencies) {
          for (let path in dependencies) {
            graphArray.push(parser(path, dirname(entry)));
          }
        }
      }
      const graph = {};
      graphArray.forEach(({ filePath, dependencies, code }) => {
        graph[filePath] = {
          dependencies,
          code
        };
      });
      return graph;
    };
    
    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("${`./${join('.', entry).replace(/\/g, '\\')}`}");
    })(${graph});
     `;
    };
    
    new Complier(config).run();
    
    
  • 相关阅读:
    设计模式-14-桥接模式
    设计模式-13-中介者模式
    设计模式-12-命令模式
    设计模式-11-外观模式
    设计模式-10-装饰器
    设计模式-9-模板
    设计模式-8-适配器模式-组合
    设计模式-8-适配器模式-继承
    设计模式-7-策略模式+工厂模式
    设计模式-7-策略模式
  • 原文地址:https://www.cnblogs.com/smallZoro/p/14015142.html
Copyright © 2011-2022 走看看