可以转换由express static提供的文件吗?或者流式传输需求?

时间:2016-12-17 03:19:03

标签: javascript express nginx webpack

它让我失望,在我的通用JavaScript应用程序中,我通过webpack DLL plugin提取了DLL库,但我必须在默认导出(供浏览器使用)或commonjs之间进行选择(供我使用)节点)。

在所有数千行供应商代码中,字面上两个出口之间的唯一区别是第一行:

- module.exports =
+ var vendor = 

我的快递应用只允许我require module.exports变种,因为它需要commonjs个模块,而我的浏览器不知道该做什么,除非得到var vendor变种。

我不想99.999999 ...%相同文件的相同副本。

本能地,这感觉很疯狂:我认为两个环境都应该能够使用相同的DLL库,因为它们之间的应用程序代码是相同的。

所以我一直在集思广益,我想出了以下几种可能性:

  • 使用像RequireJS这样的客户端CommonJS加载器(实际上不喜欢这个选项,因为我必须以加载时间为代价强制下载客户端)
  • 当客户端通过Express(或Nginx,如果可能)请求它们时,即时转换DLL以替换第一行;不确定我采用这种方法会产生什么样的惩罚。
  • 需要来自FileStream的DLL,当Express应用程序启动时,它会执行查找/替换(再次,不知道是否可能,但这感觉就像三个选项中的最小侵入一样)。
  • 接受以下事实:无法避免拥有两个DLL副本,并且我添加到我的DLL中的每个新依赖项都需要×2磁盘空间等。

我找不到中间两点或实现替代方法的实现细节是不成功的。我正在寻找超越“只需要两份副本并继续生活”的答案。如果您知道如何处理中间两点,我很乐意向您提供实施细节。如果你有想法或方法我没有在这里列出,我全都听见了!

2 个答案:

答案 0 :(得分:0)

因此,当我发布我的问题时,我发现正确的Google搜索会引导我this solution。我在一小时前从未听说过vm模块,但它似乎提供了我正在寻找的内容。

使用var NAME =为浏览器构建DLL(这是默认行为)。然后,在服务器上,使用vm.runInNewContext评估磁盘中的文件,并返回新的上下文,其中的键将与您的DLL中的var语句匹配。最后,只需将这些键分配给global.NAME和boom:服务器理解文件。

这是我的代码(当前)的样子:

const vm = require('vm');
const fs = require('fs');

// from a custom webpack plugin I wrote, where keys are the name of the chunk
// and the value is a relative filepath to that chunk
const chunks = require('path/to/my/chunks.json');

if (!chunks.js.serverDLL || !chunks.js.appDLL) {
  throw new Error('Chunks could not be loaded!!');
}

const dllContext = ((pathMap, context = {}) => {
  Object.keys(pathMap).forEach((key) => {
    vm.runInNewContext(fs.readFileSync(pathMap[key]), context, pathMap[key]);
  });

  return context;
})({ serverDLL: `.${chunks.js.serverDLL}`, appDLL: `.${chunks.js.appDLL}` });

global.serverDLL = dllContext.serverDLL;
global.appDLL = dllContext.appDLL;

上面还有改进的余地,因为我可能会使用HOC函数迭代我的块输入而不是硬编码键。此外,我的publicPath设置为/,但传递到我的vm.runInNewContext的路径需要是相对文件路径。由于我只在生产中进行此操作(不是开发),因此我的构建目录是扁平的(对于这些文件无论如何),因此我预先添加.,将客户端URL路由转换为适当的相对文件路径。另外,这是我第一次使用vm,所以我相信有人会指出我可以更好地完成上述工作的方法。 :d

答案 1 :(得分:0)

听起来这个文件开头和结尾的变化可能有效:

// start of file
try {
  module.exports;
} catch (err) {
  var module = {};
}
var vendor = // ... the duplicated code

// end of file
module.exports = vendor;

我确信nodejs和浏览器一般都可以通过这种方式获取正确的值,但我自己并没有使用带有webpack的DLL库,所以如果不适合这种情况,我会提前道歉。为了以防万一,我以为我会把它扔出去。