为什么使用包名称从链接的本地 ES 模块包导入适用于 "main" 属性 但因 "module" 而失败
Why importing from a linked local ES modules package using the package name works with "main" property but fails with "module"
问题
当 pacakge.json
具有 "main"
属性 时,为什么使用 pacakge 名称从 linked 本地 NPM 包(作为 ES 模块构建)导入有效, 但当它有 "module"
属性?
时失败
设置
更具体地说,如果我们有以下设置:
exporter
:一个 Node.js 包,它是一个 export
的 ES 模块(例如,使用 export default
)。
importer
:一个 Node.js 模块尝试 import
exporter
导出的内容,使用 import something from 'exporter'
.
- 使用
npm link
到本地 link exporter
到 importer
.
然后:
- 如果
exporter
的 package.json
使用 main
属性. ,则设置 运行 成功
- 如果
exporter
的 package.json
使用 module
属性,则设置 运行 失败 。
- 可以使用
import something from 'exporter/dist/bundle.js'
、“修复”此故障,但这是不可接受的。
为什么?我想我做错了什么?
- 有关此设置的更多信息,请参阅我的
代码
exporter
|- webpack.config.js
|- package.json
|- /src
|- index.js
|- /dist
|- bundle.js
webpack.config.js
:
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
mode: "development",
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
library: {
type: "module",
},
},
experiments: {
outputModule: true,
},
};
package.json
:
{
"name": "exporter",
"version": "1.0.0",
"main": "dist/bundle.js", <-- *** NOTE THIS LINE ***
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0"
},
"type": "module"
}
index.js
:
function util() {
return "I'm a util!";
}
export default util;
importer
|- package.json
|- /src
|- index.js
package.json
{
"name": "importer",
"version": "1.0.0",
"type": "module"
}
index.js
import util from 'exporter';
console.log(util());
然后:
- 正在链接:
⚡ cd exporter
⚡ npm link
⚡ cd importer
⚡ npm link exporter
- 正在执行:
⚡ node importer.js
I'm a util!
但是,如果exporter
的package.json
改为:
{
"name": "exporter",
"version": "1.0.0",
"module": "dist/bundle.js", <-- *** NOTE THIS LINE ***
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0"
},
"type": "module"
}
然后:
- 正在执行:
⚡ node importer.js
失败:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'importer\node_modules\exporter\' imported from importer\src\index.js
但是为什么?
解析node_modules包时,Node.js首先检查package.json
中是否有"exports"
字段,如果有none则查找"main"
字段,如果是。也不在那里,它会检查是否有一个名为 index.js
的文件——尽管这种行为已被弃用并且可能会在 Node.js 的更高版本中被删除,但我建议不要依赖它并始终指定 "exports"
and/or "main"
个字段。您可以查看 Node.js 文档的 Package entry points 部分以获取更多信息。
"module"
根本不是 Node.js 使用的字段,它被其他一些工具使用,所以在你的 package.json
中定义它当然没问题,但你也应该 "main"
and/or "exports"
个字段。 Node.js 将使用文件扩展名来确定文件是否为 ES 模块(dist/bundle.js
使用 .js
作为扩展名,而你的 package.json
中有 "type": "module"
,所以你已经准备好了)。
问题
当 pacakge.json
具有 "main"
属性 时,为什么使用 pacakge 名称从 linked 本地 NPM 包(作为 ES 模块构建)导入有效, 但当它有 "module"
属性?
设置
更具体地说,如果我们有以下设置:
exporter
:一个 Node.js 包,它是一个export
的 ES 模块(例如,使用export default
)。importer
:一个 Node.js 模块尝试import
exporter
导出的内容,使用import something from 'exporter'
.- 使用
npm link
到本地 linkexporter
到importer
.
然后:
- 如果
exporter
的package.json
使用main
属性. ,则设置 运行 成功
- 如果
exporter
的package.json
使用module
属性,则设置 运行 失败 。- 可以使用
import something from 'exporter/dist/bundle.js'
、“修复”此故障,但这是不可接受的。
- 可以使用
为什么?我想我做错了什么?
- 有关此设置的更多信息,请参阅我的
代码
exporter
|- webpack.config.js
|- package.json
|- /src
|- index.js
|- /dist
|- bundle.js
webpack.config.js
:
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
mode: "development",
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
library: {
type: "module",
},
},
experiments: {
outputModule: true,
},
};
package.json
:
{
"name": "exporter",
"version": "1.0.0",
"main": "dist/bundle.js", <-- *** NOTE THIS LINE ***
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0"
},
"type": "module"
}
index.js
:
function util() {
return "I'm a util!";
}
export default util;
importer
|- package.json
|- /src
|- index.js
package.json
{
"name": "importer",
"version": "1.0.0",
"type": "module"
}
index.js
import util from 'exporter';
console.log(util());
然后:
- 正在链接:
⚡ cd exporter
⚡ npm link
⚡ cd importer
⚡ npm link exporter
- 正在执行:
⚡ node importer.js
I'm a util!
但是,如果exporter
的package.json
改为:
{
"name": "exporter",
"version": "1.0.0",
"module": "dist/bundle.js", <-- *** NOTE THIS LINE ***
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0"
},
"type": "module"
}
然后:
- 正在执行:
⚡ node importer.js
失败:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'importer\node_modules\exporter\' imported from importer\src\index.js
但是为什么?
解析node_modules包时,Node.js首先检查package.json
中是否有"exports"
字段,如果有none则查找"main"
字段,如果是。也不在那里,它会检查是否有一个名为 index.js
的文件——尽管这种行为已被弃用并且可能会在 Node.js 的更高版本中被删除,但我建议不要依赖它并始终指定 "exports"
and/or "main"
个字段。您可以查看 Node.js 文档的 Package entry points 部分以获取更多信息。
"module"
根本不是 Node.js 使用的字段,它被其他一些工具使用,所以在你的 package.json
中定义它当然没问题,但你也应该 "main"
and/or "exports"
个字段。 Node.js 将使用文件扩展名来确定文件是否为 ES 模块(dist/bundle.js
使用 .js
作为扩展名,而你的 package.json
中有 "type": "module"
,所以你已经准备好了)。