Javascript 是否可以转换express static提供的文件?还是需要一条流?

Javascript 是否可以转换express static提供的文件?还是需要一条流?,javascript,express,nginx,webpack,Javascript,Express,Nginx,Webpack,在我的通用JavaScript应用程序中,我有通过提取的DLL库,但我必须在默认导出(供浏览器使用)或commonjs(供节点使用)之间进行选择,这让我很难受 在所有数千行供应商代码中,两种导出之间的唯一区别是第一行: - module.exports = + var vendor = 我的express应用程序只允许我要求模块。导出变量,因为它需要commonjs模块,我的浏览器不知道该怎么做,除非它得到变量供应商 我不想要99.999999…%相同文件的相同副本。 本能地,这感觉很疯狂:

在我的通用JavaScript应用程序中,我有通过提取的DLL库,但我必须在默认导出(供浏览器使用)或
commonjs
(供节点使用)之间进行选择,这让我很难受

在所有数千行供应商代码中,两种导出之间的唯一区别是第一行:

- module.exports =
+ var vendor = 
我的express应用程序只允许我
要求
模块。导出
变量,因为它需要
commonjs
模块,我的浏览器不知道该怎么做,除非它得到
变量供应商

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

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

因此,我一直在集思广益,并提出以下可能性:

  • 使用客户端CommonJS加载程序,比如RequireJS(我真的不喜欢这个选项,因为我必须以加载时间为代价强制在客户端下载)
  • 通过Express(或Nginx,如果可能的话)动态转换DLL,以在客户端请求时替换第一行;不确定这种方法会导致什么性能损失
  • 需要在Express应用程序启动时执行查找/替换的文件流中的DLL(同样,不知道是否可能,但这是三个选项中侵入性最小的)
  • 接受这样一个事实:没有办法避免拥有两个DLL副本,而且我添加到DLL中的每个新依赖项都需要×2的磁盘空间等

我没有找到中间两点的实现细节,也没有找到替代方法。我正在寻找的答案不仅仅是“只需要两份拷贝,继续你的生活。”如果你知道如何做到中间两点,我很乐意从你那里得到实现细节。如果你有我没有在这里列出的想法或方法,我洗耳恭听

当然,只要我发布我的So问题,我就会找到正确的谷歌搜索结果。一个小时前我从未听说过这个模块,但它似乎提供了我想要的东西

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

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

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函数来迭代我的块输入,而不是硬编码键。此外,my
publicPath
设置为
/
,但传递到my
vm.runInNewContext
的路径需要是相对文件路径。由于我只在生产环境(而不是开发环境)中执行此操作,因此我的构建目录是平面的(无论如何,对于这些文件),因此我预先设置了一个
,它将客户端URL路由转换为相应的相对文件路径。此外,这是我第一次使用
vm
,因此我相信有人会指出我可以更好地完成上述工作的方法:当然,只要我发布了我的So问题,我就会找到正确的谷歌搜索结果。一个小时前我从未听说过这个模块,但它似乎提供了我想要的东西

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

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

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函数来迭代我的块输入,而不是硬编码键。此外,my
publicPath
设置为
/
,但传递到my
vm.runInNewContext
的路径需要是相对文件路径。由于我只在生产环境(而不是开发环境)中执行此操作,因此我的构建目录是平面的(无论如何,对于这些文件),因此我预先设置了一个
,它将客户端URL路由转换为相应的相对文件路径。此外,这是我第一次使用
vm
,因此我相信有人会指出我可以更好地完成上述工作的方法:D

听起来对文件开头和结尾的更改可能有效:

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

// end of file
module.exports = vendor;

我确信nodejs和浏览器通常都可以通过这种方式获得正确的值,但我自己并没有在webpack中使用DLL库,所以如果这不适合这种情况,我提前道歉。我想我会把它扔到那里以防万一。

听起来对文件开头和结尾的更改可能会起作用:

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

// end of file
module.exports = vendor;
我确信nodejs和浏览器通常都可以通过这种方式获得正确的值,但我自己并没有在webpack中使用DLL库,所以如果这不适合这种情况,我提前道歉。我想我会把它扔出去以防万一