j_d*_*j_d 4 javascript optimization static-analysis node.js webpack
首先,请注意,我是故意设置这个假设问题的,因为这是我面临解决的现实世界问题,并且不确定它是否可能。
假设我有一个名为 的 JavaScript 包,road-fetcher带有一个名为 的导出函数find,我可以将纬度/经度坐标传递到其中,并返回到该点的最近的道路。
所以:
import { find } from 'road-fetcher'
find(36.585940, -95.304241) // output: 'US Route 66'
Run Code Online (Sandbox Code Playgroud)
假设使用我的road-fetcher应用程序的用户最终find在其 Web 应用程序中使用此函数 200-300 倍(所有这些都是以可预测的、不可预测的Math.random方式)。
在内部,我的road-fetcher包正在向我的外部 API 发出网络请求。这工作得很好,但如果我们在运行时继续这样做,我们会在每个客户端上产生带宽和延迟成本(无论是在浏览器还是服务器中),但我们不一定需要。而且,也许所有 200 个调用都在同一页面上。相反,理想的做法是在构建时生成初始值,并可能设置一些长 TTL 以便稍后重新验证值。
使用 Webpack 处理 JavaScript 是很常见的,我想知道是否可以静态分析用户对该find函数的使用情况以找到所有排列。
理想情况下,我希望编译带有参数的函数调用的总列表,然后在构建步骤中基于此发出网络请求,但甚至能够编译所有函数调用参数的列表并将其存储在文件系统(不确定是在node_modules或 cwd 内),以促进单个缓存热步骤也足够了。
初步查看 Webpack 文档,这似乎可能是一个起点,但我对此的了解还不够深入。evaluateCallExpressionMember
我很欣赏这是一个人为的例子,但它确实代表了一个非常现实的问题,我试图在这里简化以清楚地隔离手头的问题。
我设法编写了一个 webpack 插件,它接受函数名称和将使用传递给原始函数的参数调用的回调。
\n\n\n这是回购协议如果您只想跳入代码,
\n
它有效,但有一些限制:
\nimport { log as logg } from \'./something\'这是我的源代码:
\nimport { log } from \'./helpers/log\';\n\n// these will be logged\nlog(1);\nlog(2, 3);\nlog(2, "foo");\nlog(2, "foo", 4, "bar");\nlog(2, "foo", 4, "bar", [1, 2, "asd"]);\nlog(2, "foo", 4, "bar", [1, 2, "asd"], { foo: "bar" }, [\n { a: "asd", b: 123, c: [] },\n]);\n\n// this one will not be logged because it\'s using a variable\nconst a = [1,2,3];\nlog(a);\n\n// this one will also not be logged because it\'s not using `log` exactly\nconsole.log(\'asd\');\nRun Code Online (Sandbox Code Playgroud)\n这是 webpack 配置:
\nconst FunctionCallPlugin = require(\'./webpack-plugins/FunctionCall\');\n\nmodule.exports = {\n plugins: [ new FunctionCallPlugin({ functionName: \'log\', callback: ({ arguments: args }) => {\n console.log(\'`log` function was found and called with the arguments:\', args);\n // you can do whatever here, make a http request, write to db, etc\n }})],\n}\nRun Code Online (Sandbox Code Playgroud)\n这是运行 webpack 时的终端输出:
\n\xe2\x9e\x9c webpack-plugin-function-invoke git:(master) \xe2\x9c\x97 yarn webpack\nyarn run v1.16.0\nwarning ..\\package.json: No license field\n$ D:\\Projects\\webpack-plugin-function-invoke\\node_modules\\.bin\\webpack\n`log` function was found and called with the arguments: [ 1 ]\n`log` function was found and called with the arguments: [ 2, 3 ]\n`log` function was found and called with the arguments: [ 2, \'foo\' ]\n`log` function was found and called with the arguments: [ 2, \'foo\', 4, \'bar\' ]\n`log` function was found and called with the arguments: [ 2, \'foo\', 4, \'bar\', [ 1, 2, \'asd\' ] ]\n`log` function was found and called with the arguments: [\n 2,\n \'foo\',\n 4,\n { foo: \'bar\' },\n [ { a: \'asd\', b: 123, c: [] } ]\n]\nRun Code Online (Sandbox Code Playgroud)\nlog,它将找到任何执行以下操作的模块import { log } from \'./somewhere\':import log from \'./somewhere\'fileDependenciesfs模块读取为字符串CallExpression使用相同指定函数名称的内容就是这样!它可能不是那么高效,但是嘿它有效:)
\n我已将其放入GitHub 存储库中如果您对代码感兴趣,我知道这不是您问题的完整答案,但希望对您有所帮助!
\n