您好,欢迎来到年旅网。
搜索
您的当前位置:首页package 文件中的 main、module、exports 字段

package 文件中的 main、module、exports 字段

来源:年旅网

package 文件中的 main、module、exports 字段

main

main 字段的值是一个模块 id(默认是 index.js),是程序的主要入口点。也就是说,如果我们的包名为 foo,当其他开发者安装 foo 这个包,然后通过 require(‘foo’) 、import ‘foo’ 方式导入,那么 foo 包中 package.json 中的 main 的导出对象将被返回。这应该是相对于包文件夹根的模块 id。require(‘foo’) 相当于 require(‘./node_modules/foo/index.js’)。

{
  "main": "index.js",
}
require('foo');
// 相当于
// require('./node_modules/foo/index.js')

module

module 字段是为了解决 ES 模块(ES6 import)的需要而引入的。它通常指向一个经过编译,适合在浏览器或支持动态导入的环境使用的ES模块版本。在这些环境中,如使用 import 导入模块时,系统会优先查找 module 字段指定的文件。例如,如果我们 foo 包 module 字段设置为 “index.esm.js”,而 main 字段设置为 ‘index.js’,那么通过 import ‘foo’ 和 require(‘foo’) 导入的文件是不同的。

{
  "main": "index.js",
  "module": "index.esm.js"
}
import 'foo';
// 相当于
// import './node_modules/foo/index.esm.js'

require('foo');
// 相当于
// require('./node_modules/foo/index.js')

虽然表明上只是用于区别 import 和 require 的写法,但是 module 还有一个非常重要的指示作用,就是告诉其他开发者 module 指定的文件是可以进行 Tree Shaking,比如我们只需要包中的某个方法,通过 import 导入 module 后,在打包的时候会去除掉其他未使用的代码,而 main 指定的文件通常包含了整个 bundle 文件,不好进行 tree shaking,如果我们导入的是 main 文件,那么在打包的时候就会将全部内容都打包进去。

exports

exports 字段是 Node 13.2 版本引入的新特性,用于提供更灵活的导出控制。它允许你指定多个导出路径,甚至可以对不同导入方式进行差异化处理。并且当它存在时,它的优先级最高。

在前面介绍 main、module 两个字段,只向外部暴露了一个文件,也就是我们通过 require、import 只能导入一个文件。通过配置 exports,我们可以导出更多文件。

{
  "main": "index.js",
  "module": "index.esm.js",
}

// 上面的写法相当于
{
"exports": {
  ".": {
    "require": "./index.js",
    "import": "./index.esm.js"
  }
 }
}

为什么要加一个层级,把 require 和 import 放在 “.” 下面呢?

因为 exports 除了支持配置包的默认导出,还支持配置包的子路径。

比如我们想导入 foo 包下的某个文件:

require('foo/dist/index.css')

会报错:

Package subpath './dist/index.css' is not defined by "exports" in xxxxx

我们可以在 exports 中设置:

{
"exports": {
  ".": {
    "require": "./index.js",
    "import": "./index.esm.js"
  },
  "./dist/*": "./dist/*"
 }
}

在 中,可以定义如下几个字段:

  • node-addons:类似 node,适用于任何 node.js 环境。此条件可用于提供一个使用本机 C++ 插件的入口点,而不是一个更通用、不依赖本机插件的入口。可以通过 --no addons标志禁用此条件。
  • node:匹配任何 node.js 环境。可以是 CommonJS 或 ES 模块文件。
    • 可以配置 production、development、default
      {
        "exports": {
          ".": {
            "require": {
              "node": {
                "production": "./index.prod.js",
                "development": "./index.dev.js",
                "default": "./index.js"
              }
            }
          }
        }
      }
      
  • import: 通过 import 或 import() 或 ECMAScript 模块加载器的任何顶级导入或解析操作加载包时匹配。无论目标文件的模块格式如何,都适用。总是与 require 相互排斥。
  • require:通过 require() 加载包时匹配。引用的文件应该可以使用 require() 加载,尽管无论目标文件的模块格式如何,条件都匹配。如果启用了 --experimental-require-module,则预期的格式包括 CommonJS、JSON、本机插件和 ES 模块。始终与 import 相互排斥。
  • default:始终匹配的通用回退。可以是 CommonJS 或 ES 模块文件。这种情况应该总是最后出现。

这几个字段的顺序是非常重要的,在条件匹配过程中,前面的 key 具有更高的优先级。一般规则是,条件应按对象顺序从最具体到最不具体。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务