• webpack原理分析之编写一个打包器


    一、引入依赖

    const fs = require('fs')
    const parser = require('@babel/parser')
    const traverse = require('@babel/traverse').default;
    const path = require('path')
    const babel = require('@babel/core')
    

    二、形成AST抽象语法树,分析模块的代码和依赖路径

    function moduleAnalyser(filename) {
        const content = fs.readFileSync(filename, 'utf-8');
        const ast = parser.parse(content, {
            // parse in strict mode and allow module declarations
            sourceType: "module",
        });
        const dependencies = {};
        traverse(ast, {
            ImportDeclaration({ node }) {
                // dependencies.push(node.source.value)
                const dirname = path.dirname(filename)
                const newFile = './' + path.join(dirname, node.source.value)
                dependencies[node.source.value] = newFile
            }
        })
        // console.log(ast.program)
        // console.log(dependencies)
        const { code } = babel.transformFromAst(ast, null, {
            presets: ["@babel/preset-env"]
        });
        return {
            filename,
            dependencies,
            code
        }
    }
    

    三、形成模块间的依赖图谱

    const makeDependenciesGraph = (entry) => {
        const entryModule = moduleAnalyser(entry)
        const graphArry = [entryModule]
        for (let i = 0; i < graphArry.length; i++) {
            const item = graphArry[i];
            // console.log(item,123)
            const { dependencies } = item;
            if (dependencies) {
                for (let j in dependencies) {
                    graphArry.push(
                        moduleAnalyser(dependencies[j])
                    )
                }
            }
        }
        const graph = {}
        graphArry.forEach(item => {
            graph[item.filename] = {
                dependencies: item.dependencies,
                code: item.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('${entry}');
            })(${graph})
        `;
    }
    const code = generateCode('./src/main.js')  //这个就是你项目的入口文件
    console.log(code)
    

    最后生成的code代码就可以在浏览器上执行

  • 相关阅读:
    关于扩展欧几里得算法___基础,基础中的基础
    bzoj 2152聪聪可可
    poj1741 树上的点分治
    POJ1201 区间
    codevs 2756树上的路径
    zoj1260 king
    栈与队列应用:迷宫问题(DFS非最短路径)
    估值为一亿的AI核心代码
    栈与队列应用:计算前缀表达式的值
    栈与队列:循环队列算法+可执行代码
  • 原文地址:https://www.cnblogs.com/uimeigui/p/14133582.html
Copyright © 2020-2023  润新知