首页 > 解决方案 > 使用 JavaScript 模块的同构 JavaScript 库 - 在浏览器中省略 Node.js 依赖项?

问题描述

所以我计划编写一个包,希望用户能够在 Node.js 和浏览器中使用它。

在 Node.js 端,它将使用该fs模块。这在浏览器中可能不存在。这可以通过 CommonJS 来完成,它带有一个if检查模块所在环境的子句和一个简单的require.

import当它被吊起时,情况并非如此。

有没有人知道如何构造代码或构建环境以满足同一个包中的两个环境?

标签: javascriptnode.jsbrowserisomorphic-javascript

解决方案


坚持 ES6 导入

似乎import对 Node.js 的支持有所改进。在文档中它说

--experimental-modules标志可用于启用对 ECMAScript 模块(ES 模块)的支持。

一旦启用,Node.js 将在将以下内容作为 ES 模块传递给节点作为初始输入时,或者在 ES 模块代码中的 import 语句引用时:

  • .mjs以.结尾的文件

  • 当最近的父文件包含值为 的顶级字段时,以 结尾的.js文件或无扩展名文件。package.json"type""module"

  • 字符串作为参数传入--evalor --print,或通过管道传送到节点STDIN,带有标志--input-type=module

列出的第二种方法可能适用于 node.js。只需确保您的库package.json包含"type": "module"并且 Node 应该将其视为 ES6 模块而不是 CommonJS。

有条件的导入作为承诺 - 你将不得不等待

条件导入在节点中已经可用,但实际上并不支持。他们似乎在浏览器中工作。还有一个警告:导入的模块是一个承诺。这意味着只要您计划好您的步骤,您就可以拥有部分同构的代码。知道您可以import("test.js")在浏览器中执行并且可以测试window意味着您可以以智能的方式编写条件并拥有跨平台代码。

例如,您可以这样做:

if (typeof window !== 'undefined') const FooPromise = import("foo");

但不是相反。祝你好运。希望对 es6 动态导入的更多支持将来到节点。


推荐阅读