V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
hanxu317138
V2EX  ›  程序员

webpack 求助如何解析字符串变量

  •  
  •   hanxu317138 · 6 天前 · 1078 次点击

    想通过 webpack 构建时 JavascriptParser Hooks 去解析所有的 "Literal" 节点, 获取["hello-world", "hello]

    console.log("hello-world");
    var name = "hello";
    

    但是实操半天发现没有任何头绪, 各种方法文档哪怕各种 gpt 都用了. 依然没有方案~~

    有哪个大佬做过. 求分享

    第 1 条附言  ·  5 天前
    使用 babel 处理的确容易的多

    ```
    const LiteralPlugin = function (babel) {
    const { types, template } = babel;
    return {
    visitor: {
    Literal(path, state) {
    if (path.node.value === 'KEY_ABC_DEV') {
    console.log('File path>>>', path.hub.file.opts.filename);
    console.log('LiteralDeclaration>>>', path.node.value);
    }
    },
    },
    };
    };
    ```
    第 2 条附言  ·  5 天前

    const LiteralPlugin = function (babel) { const { types, template } = babel; return { visitor: { Literal(path, state) { if (path.node.value === 'KEY_ABC_DEV') { console.log('File path>>>', path.hub.file.opts.filename); console.log('LiteralDeclaration>>>', path.node.value); } }, }, }; };

    第 3 条附言  ·  5 天前

    使用babel处理容易的多

    const LiteralPlugin = function (babel) {
        const { types, template } = babel;
        return {
            visitor: {
                Literal(path, state) {
                    if (path.node.value === 'KEY_ABC_DEV') {
                        console.log('File path>>>', path.hub.file.opts.filename);
                        console.log('LiteralDeclaration>>>', path.node.value);
                    }
                },
            },
        };
    };
    
    第 4 条附言  ·  5 天前

    依然想通过webpack构建去完成功能, 经过尝试

    
    function traverseESTreeAST(node, callback) {
      if (!node || typeof node !== "object") return;
    
      // 处理当前节点
      if (node.type) {
        callback(node); // 对当前节点执行自定义逻辑
      }
    
      // 递归遍历子节点
      for (const key in node) {
        if (key === "parent" || !node.hasOwnProperty(key)) continue; // 忽略 parent 等非子节点属性
        const child = node[key];
        if (Array.isArray(child)) {
          child.forEach((item) => traverseESTreeAST(item, callback));
        } else {
          traverseESTreeAST(child, callback);
        }
      }
    }
    // webpack plugin
     compiler.hooks.normalModuleFactory.tap("MyPlugin", (factory) => {
            factory.hooks.parser
              .for("javascript/auto")
              .tap("MyPlugin", (parser, options) => {
                parser.hooks.program.tap("myPlugin", (program) => {
                  console.log("program", program);
                  fs.writeFileSync("ast.json", JSON.stringify(program, null, 2));
    
                  traverseESTreeAST(program, (node) => {
                    if (node.type === "Literal") {
                      console.log("node  Literal", node);
                    }
                  });
                });
              });
          });
    
    16 条回复    2025-02-08 14:24:43 +08:00
    murmur
        1
    murmur  
       6 天前
    你这个东西应该去看各种代码混淆的插件或者工具,人家可以把字符串量转成\x0000\x1111 这样的东西,肯定能解析字符串
    ltaoo1o
        2
    ltaoo1o  
       6 天前
    https://astexplorer.net/ 先用这个看 AST 结构,然后写一个 babel 插件,能获取到 AST 结构,后面就随便你想怎么做都行
    duowb
        3
    duowb  
       6 天前
    用 ast 来解析吧,列举出所有的"Literal" 节点。
    yishibakaien
        4
    yishibakaien  
       6 天前
    使用 glob 或 fs.readFile 读取文件,去到文件后,使用正则表达式,获取出文件中你需要的字符串
    xuld
        5
    xuld  
       5 天前
    小白:我想学做饭
    大师:用电饭煲啊,先去网上看看电饭煲的广告,给你推荐个下单地址,然后买过来,使用做饭功能,就可以做饭了
    n18255447846
        6
    n18255447846  
       5 天前
    你这不是 webpack 做的事。解析 ast 后再处理,babel 插件和 acorn 都能做到
    leokun
        7
    leokun  
       5 天前
    用 babel-loader 配合一个自定义 babel 插件就可以很轻松完成 (就是附言中那样)
    jchnxu
        8
    jchnxu  
       5 天前
    我一般是找现成的 replace 系插件。print 之后魔改

    这个确实是目前 gpt 搞不定的东西。。
    hanxu317138
        9
    hanxu317138  
    OP
       5 天前
    @jchnxu chatGpt 是工具用于提升生产力的. 太细致的需求, 还得是自己动手.
    hanxu317138
        10
    hanxu317138  
    OP
       5 天前
    @n18255447846 去看了一下 terser 的仓库, 也是看半天也没看懂.

    https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/src/index.js
    n18255447846
        11
    n18255447846  
       5 天前
    @hanxu317138 找 terser 源码,插件只是调用了 terser 库。插件用 worker 执行 minify ,而 minify 调用了 options.minimizer.implementation
    zhwithsweet
        12
    zhwithsweet  
       5 天前
    都是 vite/rspack 了 老哥赶紧迁移吧
    hanxu317138
        13
    hanxu317138  
    OP
       4 天前
    @n18255447846 耐心看了一下午. 看懂了~~感谢指导~
    hanxu317138
        14
    hanxu317138  
    OP
       4 天前
    @zhwithsweet 公司历史债务, 我倒是愿意拥抱新变化~~~
    lisongeee
        15
    lisongeee  
       4 天前   ❤️ 1
    webpack api 不如 rollupjs 现代化,看得脑壳痛

    建议使用 https://github.com/unjs/unplugin ,看你的场景只需要使用 transform hooks 即可

    使用 https://github.com/acornjs/acorn 解析得到 ast 后

    使用 https://github.com/acornjs/acorn/tree/master/acorn-walk/ 快捷方便遍历节点

    替换节点使用 https://github.com/rich-harris/magic-string
    hanxu317138
        16
    hanxu317138  
    OP
       4 天前
    @lisongeee 感觉 webpack 虽然呆. 但是很稳定. 常见问题可以一站式解决~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4161 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:12 · PVG 18:12 · LAX 02:12 · JFK 05:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.