【发布时间】:2019-05-14 18:19:33
【问题描述】:
我正在构建一个支持 CommonJS 和 ES 模块的包。对于单个入口点,我可以正常工作。我将我的代码编写为 ESM,并在发布之前使用 Babel 将其编译为 CJS。我的package.json 的相关位看起来像这样:
"main": "cjs/",
"module": "esm/",
"scripts": {
"test": "jest ./test",
"clean": "rm -rf cjs",
"build": "npm run clean && babel esm --out-dir cjs",
"prepare": "npm test && npm run build"
}
所以我的index.js 在esm/index.js 中,而cjs/index.js 在包发布之前不存在。当使用require(例如const myPackage = require('my-package'))包含包时,它将从cjs/拉取。如果是导入的(例如import myPackage from 'my-packge'),它将从esm/ 拉取。
我的问题是我希望能够从包中导入其他文件(例如import adapter from 'my-package/adapters/mysql' 或const adapter = require('my-package/adapters/mysql'))。但是如果我以这种方式包含它,将找不到该文件。
我可以使用完整路径(例如import adapter from 'my-package/esm/adapters/mysql' 或const adapter = require('my-package/cjs/adapters/mysql'))导入它。但我不想在路径中明确指定模块类型。似乎节点已经知道如何区分 CJS 和 ES 模块(它知道从 main 要求并从 module 导入),所以我希望可以对多个文件做同样的事情。
如上所述,有没有什么方法可以包含一个包,而不必明确指定esm/ 或cjs/ 的路径?
【问题讨论】:
-
也许我理解错了,但是您可以从入口点导出多个命名项目:
export adapters from './adapters'等。 -
@rayhatfield 您的意思是将它们导出到
index.js文件中?我想过这样做,但是我必须从索引中导入和解构它们(例如import {adapters: {mysql}} from 'my-package')。 -
如果您希望能够在不解构的情况下导入某些内容,除了命名导出之外,您还可以
export default from ...。你也可以按照以下方式做一些事情:import {Adapters} from 'my-package'; // do something with Adapters.mysql -
@rayhatfield 这就是我要避免的。我可能是错的,但我有一种感觉,如果我将所有未使用的适配器都导入,那么摇树摇晃将无法修剪未使用的适配器。另外,如果我只想使用一个,那么可能需要解析很多额外的代码(一堆数据库适配器)。似乎将每个适配器都放在自己的文件中,自己导入,这将是一个更清洁的解决方案。
-
这些前端模块是为浏览器设计的吗?
标签: javascript node.js npm es6-modules