最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack进阶(代码转换/依赖分析)

    正文概述 掘金(courage酱)   2021-03-07   779

    JavaScript 是一门编译型语言。

    AST/Babel/依赖

    bable的原理

    1. parse 把代码code变成AST(Abstract Syntax Tree:什么是抽象语法树)
    2. traverser遍历AST进行修改
    3. generate:把AST变成代码code2

    即 原代码 --(1)-> ast ---(2)->ast--(3)->code(2)

    示例(将let 变成var)

    import { parse } from '@babel/parser'
    import traverse from '@babel/traverse'
    import generate from '@babel/generator'
    
    const code = `let a = 'let';let b = 2`
    const ast = parse(code, { sourceType: 'module' })
    traverse(ast, {
        enter: (item) => {
            if (item.node.type === 'VariableDeclaration') {
                if (item.node.kind === 'let') {
                    item.node.kind = 'var'
                }
            }
        }
    })
    const result = generate(ast, {}, code)
    console.log(result.code)
    //输出
    //var a = 'let';
    //var b = 2;
    

    将ES6转换成ES5

    import { parse } from '@babel/parser'
    import * as babel from '@babel/core'
    import * as fs from 'fs'
    
    const code = `let a = 'let'; let b = 2; const c = 3`
    const ast = parse(code, { sourceType: 'module' })
    const result = babel.transformFromAstAsync(ast, code, {
        presets: ['@babel/preset-env']
    })
    result.then(res => {
        fs.writeFileSync('./test.es5.js', res.code)
    })
    

    依赖分析

    // 请确保你的 Node 版本大于等于 14
    // 请先运行 yarn 或 npm i 来安装依赖
    // 然后使用 node -r ts-node/register 文件路径 来运行,
    // 如果需要调试,可以加一个选项 --inspect-brk,再打开 Chrome 开发者工具,点击 Node 图标即可调试
    import { parse } from "@babel/parser"
    import traverse from "@babel/traverse"
    import { readFileSync } from 'fs'
    import { resolve, relative, dirname } from 'path';
    
    // 设置根目录
    const projectRoot = resolve(__dirname, 'project_1')
    
    // 类型声明
    type DepRelation = { [key: string]: { deps: string[], code: string } }
    // 初始化一个空的 depRelation,用于收集依赖
    const depRelation: DepRelation = {}
    
    function getProjectPath(path: string) {
        return relative(projectRoot, path).replace(/\\/g, '/')
    }
    function collectCodeAndDeps(filepath: string) {
        const key = getProjectPath(filepath) // 文件的项目路径,如 index.js
        // 获取文件内容,将内容放至 depRelation
        const code = readFileSync(filepath).toString()
        // 初始化 depRelation[key]
        depRelation[key] = { deps: [], code: code }
        // 将代码转为 AST
        const ast = parse(code, { sourceType: 'module' })
        // 分析文件依赖,将内容放至 depRelation
        traverse(ast, {
            enter: path => {
                if (path.node.type === 'ImportDeclaration') {
                    // path.node.source.value 往往是一个相对路径,如 ./a.js,需要先把它转为一个绝对路径
                    const depAbsolutePath = resolve(dirname(filepath), path.node.source.value)
                    // 然后转为项目路径
                    const depProjectPath = getProjectPath(depAbsolutePath)
                    // 把依赖写进 depRelation
                    depRelation[key].deps.push(depProjectPath)
                }
            }
        })
    }
    
    
    // 将入口文件的绝对路径传入函数,如 D:\demo\fixture_1\index.js
    collectCodeAndDeps(resolve(projectRoot, 'index.js'))
    console.log('depRelation')
    console.log(depRelation)
    

    用递归进行嵌套依赖分析

    //其他代码同上,在collectCodeAndDeps中调用自己即可!缺点:如果太深会导致
    function collectCodeAndDeps(filepath: string) {
        traverse(ast, {
            enter: path => {
                if (path.node.type === 'ImportDeclaration') {
                    ...
                    depRelation[key].deps.push(depProjectPath)
                    collectCodeAndDeps(depAbsolutePath)
                }
            }
        })
    }
    

    避免循环依赖

    if (Object.keys(depRelation).includes(key)) {
    	console.warn(`duplicated dependency:${key}`)
        return
    }
    

    起源地下载网 » webpack进阶(代码转换/依赖分析)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元