【问题标题】:How to combine node.js modules/source into one .js file, to execute inside node如何将 node.js 模块/源合并到一个 .js 文件中,以在节点内部执行
【发布时间】:2012-03-21 06:30:00
【问题描述】:

我需要使用 vm.createScript / script.runInNewContext 在节点应用程序(沙箱中)中执行节点代码/模块。主机节点应用程序在 heroku 上运行,因此没有本地文件系统可言。我能够下载和运行没有外部依赖的代码就好了,但是要求也能够包含其他节点模块。 (作为构建/打包步骤将是理想的)

有许多现有的解决方案(browserify 是我花费最多时间的一个),但它们不可避免地会生成一个代码块(是的!),旨在在浏览器中执行(嘘! )。例如,Browserify 生成对 window. 等的依赖项。

有谁知道一种工具可以读取 package.json 依赖项{}(或查看源代码中的所有 require())并生成适合节点 runInNewContext 的单个整体 blob?

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    我不认为您正在寻找的解决方案是正确的解决方案。基本上你想获取一堆require('lib')'s,将它们混合到一个单一的Javascript上下文中,将该上下文序列化为源代码,然后将该序列化形式传递给runInNewContext函数以反序列化并重建为一个Javascript上下文,然后反序列化您的自定义沙盒代码,最后运行整个代码。

    创建一个包含所需require('lib') 的上下文对象并将该对象直接传递到您的VM 不是更有意义吗?基于来自documentation的代码:

    var vm = require('vm'), 
    initSandbox = {
        async: require('async'),
        http: require('http')
    },
    context = vm.createContext(initSandbox);
    vm.runInContext("async.forEach([0, 1, 2], function(element) { console.log(element); });", context);
    

    现在您可以通过上下文访问所需的库,而无需经过昂贵的序列化/反序列化过程。

    【讨论】:

    • 这就是我遇到 Heroku 不可写文件系统问题的地方。这个包通过 S3 进入应用程序,我正在遍历 .zip,将主文件提取到内存中,然后将其喷射到上下文中。我可以将包含的模块(比如它不是核心模块)提取到 ./tmp(暂时可写)中,并让 NODE_PATH 变量在那里查找 require(),但这似乎容易出错。此外,如果直到稍后的代码路径才遇到 require(),.zip 中的模块将早已不复存在。这就是为什么编译成单个文件似乎是理想的。
    • 您为什么要尝试动态安装软件包?如果您的 VM 脚本之一需要它,它应该是您的应用程序的依赖项,Heroku 应该为您安装它。如果您有 10 个不同的用户都需要重叠的包集,会发生什么?您会将其中一些加载到内存中 10 次吗?这种方法似乎非常脆弱且不可扩展。
    • 这是一个非常独特的node应用。 (也许正确的答案是 !heroku)(或 !node.. 但它是一个非常理想的平台)它需要处理一组受控的开发人员模块,这在部署应用程序时是没有预料到的。他们需要能够从管理界面随意进出 - 你是对的,内存中肯定存在重复包的开销。至少在打包工具更新并且更新后的模块列表包含在基本 slug 中之前。
    • 我会说我会为此使用 Amazon EC2 实例,因此您至少有一个准持久存储可以使用,然后read up on using npm programmatically 可以动态安装/卸载包根据需要(例如,您可以在上次请求使用它时设置超时)。
    猜你喜欢
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多