NodeJS 从客户端应用程序的webpack编译中排除仅服务器端模块

332nm8kg  于 11个月前  发布在  Node.js
关注(0)|答案(1)|浏览(118)

我开发基于NodeJS和React的Web应用程序。我一直在尝试不同的架构风格,最近痴迷于跨服务器端和客户端共享代码的想法。我认为这种风格很强大,因为它可以降低维护API连续性的难度。
下面是一个简单的例子,说明客户端如何从服务器端导入类型:

我想进一步开发这种风格,这样我就可以在一个地方编写API的请求和响应部分,并且服务器端和客户端都可以从同一个源代码导入它。Webpack将分别编译和tree-shake它们,这样我就不必担心bundle大小变得太大。
问题是,当服务器端模块依赖于浏览器不支持的模块,但不直接用于客户端时,如“bcrypt”,webpack将在编译React应用程序时抛出错误。我尝试在webpack配置中使用“externals”选项。

{
  ...
  externals: ["bcrypt", ...]
  ...
}

字符串
但是我在运行时得到错误,因为webpack添加了这样的行,而没有定义变量“bcrypt”

modules.exports = bcrypt


请注意,使用支持bcrypt版本的浏览器并不能解决问题,因为我的痛点并不特定于bcrypt。我想要一个适用于NPM中任何类型模块的解决方案。
我知道这不是一个推荐的工程方式,因为没有太多的资源开发的方式支持这个想法,但我认为这将完全为我的个人项目工作,谁知道它会成为一件事有一天?提前感谢。

ozxc1zmp

ozxc1zmp1#

我自己终于找到了解决办法
Webpack使用package.json中的browser属性来确定包的入口点,这样我们就可以创建一个很小的子包,为服务器和客户端导入不同的所需模块。
这里有一个例子,我实际上评论了一个类似的问题,目前是开放的反作用应用程序。
例如,对于crypto
1.创建名为crypto的文件夹
1.在crypto文件夹下创建package.json,并像这样配置:

{
  "browser": "client.js",
  "main": "server.js",
  "types": "index.d.ts" // optional
}

1.创建文件crypto/client.js

// crypto/client.js
module.exports = window.crypto

1.创建文件crypto/server.js

// crypto/server.js
module.exports = require("crypto").webcrypto

现在导入你刚刚创建的crypto文件夹。希望它有意义。
如果你认为安全的话,你甚至可以做一些虚拟的导出,这样几乎任何模块都可以为浏览器编译。

相关问题