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 字段是为了解决 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 字段是 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": {
".": {
"require": {
"node": {
"production": "./index.prod.js",
"development": "./index.dev.js",
"default": "./index.js"
}
}
}
}
}
这几个字段的顺序是非常重要的,在条件匹配过程中,前面的 key 具有更高的优先级。一般规则是,条件应按对象顺序从最具体到最不具体。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务