为什么使用包名称从链接的本地 ES 模块包导入可以使用“main”属性,但使用“module”会失败

2023-12-11

Question

为什么使用 pacakge 名称从链接的本地 NPM pacakage(作为 ES 模块构建)导入可以工作?pacakge.json"main"属性,但当它具有"module"财产?

Setup

更具体地说,如果我们有以下设置:

  1. exporter:一个 Node.js 包,它是一个 ES 模块export是某事(例如,使用export default).
  2. importer:一个 Node.js 模块,试图import what exporter出口,使用import something from 'exporter'.
  3. Using npm link本地链接exporter to importer.

Then:

  • 如果出现以下情况,则安装程序成功运行exporter's package.json使用main财产。
  • The setup run fails if exporter's package.json uses the module property.
    • 此故障可以通过使用“修复”import something from 'exporter/dist/bundle.js', 但这是不可接受的.

这是为什么?我想我做错了什么?

  • 有关此设置的更多信息,请参阅我的其他问题

Code

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());

Then:

  1. Linking:
⚡  cd exporter
⚡  npm link
⚡  cd importer
⚡  npm link exporter
  1. 执行:
⚡  node importer.js 
I'm a util!

However, if exporter's 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"
}

Then:

  1. 执行:
⚡  node importer.js 

Fails:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'importer\node_modules\exporter\' imported from importer\src\index.js

But Why?


当解析一个node_modules包时,Node.js首先检查是否有"exports"领域中的package.json,如果没有,它会寻找"main"字段,如果是的话。也不在那里,它检查是否有一个名为index.js– 尽管此行为已被弃用,并且可能会在 Node.js 的更高版本中删除,但我建议不要依赖它并始终指定"exports" and/or "main"字段。您可以查看包入口点Node.js 文档的部分以获取更多信息。

"module"根本不是 Node.js 使用的字段,它被其他一些工具使用,所以在你的代码中定义它当然没问题package.json,但你还应该有"main" and/or "exports"字段。 Node.js 将使用文件扩展名来判断该文件是否是 ES 模块(dist/bundle.js正在使用.js作为扩展,你有"type": "module"在你的package.json,所以一切都准备好了)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么使用包名称从链接的本地 ES 模块包导入可以使用“main”属性,但使用“module”会失败 的相关文章

随机推荐