当前位置: 首页 > news >正文

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')

main 字段通常指定一个不需要 tree-shaking 的 bundle 文件。

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/*"}
}

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

  • 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 具有更高的优先级。一般规则是,条件应按对象顺序从最具体到最不具体。


http://www.mrgr.cn/news/3451.html

相关文章:

  • 企业级WEB应用服务器TOMCAT攻略
  • docker swarm如何让两个副本分别跑在两台不同的主机上
  • Hyper-V 与 VMware 的区别
  • 8月21日CSPJxx模拟题 总结
  • C++设计原则
  • Docker-harbor 私有仓库部署和管理
  • GPS 和arduino 获取经纬度
  • 【Python系列】 并发编程在数据处理中的应用
  • 浮毛怎么去掉比较方便?最最高效解决办法宠物空气净化器分享
  • 为什么不用postman做自动化
  • 微信小程序--28(npm包)
  • PPP简介
  • STM32之点亮LED灯
  • 静态代理和动态代理
  • JAVA_7
  • MySQL读写分离
  • MyBatis源码系列1(使用JDBC查询数据)
  • 代码随想录跟练第六天——LeetCode
  • 网际报文协议ICMP及ICMP重定向实例详解7
  • 利用贝叶斯和决策树 来进行医疗诊断的