【发布时间】:2020-10-08 21:25:08
【问题描述】:
我编写了一个 JavaScript 库作为 ES6 模块,主要用于浏览器。现在我想为节点打包它。我可以限制到节点 v 14+。我不想转译。
我不确定如何处理依赖项。特别是moment-js,给我带来了麻烦。
在浏览器中(尝试了最新的 FF + Chrome),我在 <script> 标记中引用了矩库,然后在我的代码中,我可以只使用变量 moment,而不必先导入它。
my-module.js:
function testFn() {
return moment.duration(300).asSeconds();
}
export { testFn }
browser code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<script type="module" src="my-module.js"></script>
<script>
import { testFn } from 'my-module.js';
let val = testFn();
console.log(val);
</script>
但是,在节点中,我需要模块包含 import 才能使其工作:
my-module.js:
import moment from 'moment';
function testFn() {
return moment.duration(300).asSeconds();
}
export { testFn }
然后我可以在节点中使用my-module:
import { testFn } from 'my-module.js';
let val = testFn();
console.log(val);
但是,现在浏览器代码坏了:
TypeError: Error resolving module specifier: moment
我尝试了不同的 imports (import * as ..., import { moment } from ...) 但没有运气 - 浏览器仍然在抱怨。
Moment-js 只是一个例子——我想要一个通用的解决方案,因为我也有其他依赖项。
这一定是其他人已经遇到并解决的问题,而无需求助于检测环境和有条件导入等糟糕的解决方法。有没有人有好的解决方案或参考?谢谢!!
【问题讨论】:
-
你把npm安装到目录了吗?看起来您以前使用过 cdn,只是想覆盖基础
-
是的,模块文件夹通过 npm 安装了依赖项(moment-js)。否则导入语句根本不起作用。问题是,当在浏览器中运行的脚本中使用模块时,在模块源中包含该语句会引发错误,而在节点环境中,如果没有它,它将无法工作。
-
我觉得这可能是那些很简单但仍然需要几个小时才能弄清楚的愚蠢事情之一,哈哈。比如需要某些模块的顺序
-
有很好的理由,人们使用转译器。像这个。有一个动态 import() 可能对您的情况有所帮助:v8.dev/features/dynamic-import 或者,您可以在全局范围内注册您的第三方库(工作人员的自我,浏览器的窗口和节点中的全局。或者只是在较新的环境中使用 globalThis )
-
您需要提供包的相对路径,因为浏览器无法像 nodejs 那样解析 node_modules 路径。在这里,检查这个答案:stackoverflow.com/a/52558858/6080889
标签: javascript node.js ecmascript-6 browser node-modules