gpt4 book ai didi

javascript - Webpack 插件静态分析导出函数的使用情况?

转载 作者:行者123 更新时间:2023-12-01 16:16:56 33 4
gpt4 key购买 nike

首先,请注意我是故意设置这个假设的问题,因为这是我面临解决的现实世界问题,甚至不确定它是否可能。
假设我有一个 JavaScript 包,名为 road-fetcher ,带有一个名为 find 的导出函数,我可以将 lat/lng 坐标传入其中,然后返回到该点最近的道路。
所以:

import { find } from 'road-fetcher'

find(36.585940, -95.304241) // output: 'US Route 66'
假设一个用户正在使用我的 road-fetcher应用程序最终使用了这个 find在他们的网络应用程序中运行 200-300 倍(全部以可预测的方式,非 Math.random 方式)。
在内部,我的 road-fetcher包正在向我的外部 API 发出网络请求。这很好,但是如果我们在运行时继续这样做,我们会在每个客户端上产生带宽和延迟成本(无论是在浏览器还是服务器中),我们不一定需要。此外,也许所有 200 个电话都在同一页面上。相反,最好在构建时生成初始值,并可能设置一些较长的 TTL 以便稍后重新验证值。
使用 Webpack 处理 JavaScript 很常见,我想知道是否可以静态分析用户对 find 的使用情况。查找所有排列的函数。
理想情况下,我想用它们的 args 编译函数调用的总列表,然后在构建步骤期间基于此发出网络请求,但甚至能够编译所有函数调用 args 的列表并将其存储在某处文件系统(不确定,在 node_modules 或 cwd 内),以促进单个缓存热步骤也足够了。
初步查看 Webpack 文档,似乎是 evaluateCallExpressionMember 可能是一个起点,但我在这里很不了解。
我很欣赏这是一个人为的例子,但它确实代表了一个非常现实的问题,我在这里试图简化它以清楚地隔离手头的问题。

最佳答案

我设法编写了一个接受函数名称的 webpack 插件,以及一个将使用传递给原始函数的参数调用的回调。

Here is the repo if you just want to jump into the code


它可以工作,但有一些限制:
  • 它仅适用于 ES 模块
  • 如果命名导入被重命名(例如:import { log as logg } from './something'
  • 如果传递给函数的参数是变量
  • 则不起作用

    结果
    这是我的源代码:
    import { log } from './helpers/log';

    // these will be logged
    log(1);
    log(2, 3);
    log(2, "foo");
    log(2, "foo", 4, "bar");
    log(2, "foo", 4, "bar", [1, 2, "asd"]);
    log(2, "foo", 4, "bar", [1, 2, "asd"], { foo: "bar" }, [
    { a: "asd", b: 123, c: [] },
    ]);

    // this one will not be logged because it's using a variable
    const a = [1,2,3];
    log(a);

    // this one will also not be logged because it's not using `log` exactly
    console.log('asd');
    这是 webpack 配置:
    const FunctionCallPlugin = require('./webpack-plugins/FunctionCall');

    module.exports = {
    plugins: [ new FunctionCallPlugin({ functionName: 'log', callback: ({ arguments: args }) => {
    console.log('`log` function was found and called with the arguments:', args);
    // you can do whatever here, make a http request, write to db, etc
    }})],
    }
    这是运行 webpack 时的终端输出:
    ➜  webpack-plugin-function-invoke git:(master) ✗ yarn webpack
    yarn run v1.16.0
    warning ..\package.json: No license field
    $ D:\Projects\webpack-plugin-function-invoke\node_modules\.bin\webpack
    `log` function was found and called with the arguments: [ 1 ]
    `log` function was found and called with the arguments: [ 2, 3 ]
    `log` function was found and called with the arguments: [ 2, 'foo' ]
    `log` function was found and called with the arguments: [ 2, 'foo', 4, 'bar' ]
    `log` function was found and called with the arguments: [ 2, 'foo', 4, 'bar', [ 1, 2, 'asd' ] ]
    `log` function was found and called with the arguments: [
    2,
    'foo',
    4,
    { foo: 'bar' },
    [ { a: 'asd', b: 123, c: [] } ]
    ]
    插件的工作原理
  • 它遍历所有 webpack block ,以及每个 block 内的所有模块,以查看它们是否具有具有指定名称的任何依赖项。例如,如果您正在寻找 log , 它会找到任何模块 import { log } from './somewhere'import log from './somewhere'
  • 对于每个具有指定依赖关系的模块,它通过查看其 fileDependencies 来收集原始源代码的所有文件路径。
  • 使用 fs 将每个文件的源代码读取为字符串模块
  • 使用 babel 解析器
  • 将源代码解析为 AST
  • 遍历 AST,我们查看所有 CallExpression使用相同的指定函数名
  • 我们收集函数调用中使用的所有参数
  • 我们运行指定的回调,同时传递收集到的参数

  • 而已!它可能不是那么高效,但是它可以工作:)
    我已将其放入 GitHub repository如果您对代码感兴趣。我知道这不是您问题的完整答案,但希望对您有所帮助!

    关于javascript - Webpack 插件静态分析导出函数的使用情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63041086/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com