默认导出
对于开发一个 JavaScript 三方库供外部使用而言,package.json
是其中不可缺少的一部分
一般而言,对于库开发者来说,我们会在package.json
中指定我们的导出入口。一般而言会涉及两个字段main
和export
,它们会涉及到当前模块在被导入的行为。通常我们会将main
字段指向 cjs 产物,module
字段指向 ES 产物
main
main
字段指定了该模块的主入口文件,即 require 该模块时加载的文件。该字段的值应为相对于模块根目录的路径或者是一个模块名(如index.js
或lib/mymodule.js
,如果是模块名,则需要保证在该模块根目录下存在该模块)。主入口文件可以是 JavaScript 代码、JSON 数据或者是 Node.js C++扩展
module
module
字段是 ES 模块规范下的入口文件,它被用于支持 import 语法。当使用 esm 或 webpack 等工具打包时,会优先采用 module 字段指定的入口文件。如果没有指定 module 字段,则会使用 main 字段指定的入口文件作为默认的 ES 模块入口文件
指定导出
一般情况下,我们使用main
和module
在大部分场景下对于开发一个库来说已经足够。但是如果想实现更精细化的导出控制就无法满足
当我们一个库本身同时包含运行时和编译时的导出时,如果我们导出的模块在编译时(node 环境)包含副作用,如果运行时模块也从同一入口导出就会出现问题
// 例如编译时入口存在以下编译时副作用
// buildtime.ts
console.log(process.env.xxx)
export const buildLog = () => console.log("build time")
// runtime.ts
export const runLog = () => console.log("run time")
// index.ts
export * from "./buildtime.ts"
export * from "./runtime.ts"
当前,可以通过解决掉副作用规避这个问题,但是很可能我们依赖的第三方模块也是有复作用的这个时候就无解了。此时最好的办法是将这个库的运行时和编译时从两个入口进行导出,这样子就不存在某一方影响到另一方。库使用者也不需关心从统一入口导入的方法到底是编译时方法还是运行时方法
这个时候就可以利用package.json
的exports
字段进行导出,当存在该字段时会忽略main
和module
字段。该字段在 Node.js 12 版本中引入,可用来大幅简化模块的导出方式,支持同时支持多个环境下的导出方式,提供了更好的可读性和可维护性
支持以下用法
- 多文件导出
"name":