package.json 中的 main 字段的作用是什么?

300 阅读2分钟
{
  "main": "./index.js"
}

main 字段是模块的主要入口点。当进行 require 导入模块时,会查看 main 字段,然后返回模块中导出的对象。

main 应该是一个相对于包文件夹根目录的模块。

对于大多数模块来说,有一个主入口就够了。

如果 package.json 中没有设置 main ,模块的主入口默认指向包根文件夹中的 index.js 文件。

CommonJS 的案例

下面看看 main 字段设置模块主入口的例子,此例子的目录结构如下:

79.png

util/package.json 指定了 util 模块的主入口为 main.jsutil/package.json 代码如下:

{
  "name": "util",
  "main": "./main.js"
}

util/main.js 文件的代码如下,导出了 subtract 函数:

function subtract(a, b) {
  return a - b;
}

module.exports = {
  subtract: subtract,
};

util/index.js 文件的代码如下,导出了 add 函数:

function add(a, b) {
  return a + b;
}

module.exports = {
  add: add,
};

app.js 文件的代码如下:

const util = require("./util");

console.log(util.subtract(2, 1));

然后在命令行终端使用 Node.js 运行 app.js 文件,正常输出 1

80.png

可以发现,当 package.json 的 main 字段设置为 ./main.js 后,require("./util") 会在 util 文件夹下的 main.js 中加载模块。

ESM 的案例

上面的例子是 CommonJS 的,而如果是 ES 模块,则会报 ERR_UNSUPPORTED_DIR_IMPORT 的错误:

81.png

不过 ERR_UNSUPPORTED_DIR_IMPORT 的错误可以通过使用 --experimental-specifier-resolution=node 标志解决:

node --experimental-specifier-resolution=node app.js

ES 模块的例子的目录结构为:

82.png

package.json 文件内容如下,主要告知当前是 ES 模块:

{
  "type": "module"
}

app.js 文件内容如下:

import { subtract } from "./util";

console.log(subtract(2, 1));

util/package.json 文件内容如下,主要指定了当前是 ES 模块,并且模块的主入口为 ./main.js ,这样当 import 这个模块时,则会找到 ./main.js 文件,返回模块导出的内容。

{
  "name": "util",
  "type": "module",
  "main": "./main.js"
}

util/main.js 文件内容如下:

function subtract(a, b) {
  return a - b;
}

export { subtract };

util/index.js 文件内容如下,由于使用 package.json 中的 main 字段设置了新的入口,所以 import util 模块时,不会找到 util/index.js 中来:

function add(a, b) {
  return a + b;
}

export { add };

然后在命令行终端运行 app.js 文件,上文也说过,会报 ERR_UNSUPPORTED_DIR_IMPORT 的错误:

83.png

如果加上 --experimental-specifier-resolution=node 的标识,就可以正常运行了:

84.png

总结

package.json 文件中的 main 字段用于指定模块的入口文件,即当其他模块通过 Node.jsrequire() 函数或现代 JavaScript 的 import 语句来引用这个包时,默认加载的文件。

当使用 import 时,在 Node.js 中要指定 --experimental-specifier-resolution=node 标识,否则运行代码时,会报 ERR_UNSUPPORTED_DIR_IMPORT 的错误。