Skip to main content

package.json

{
// 主要包入口定义
"main": "lib/cjs/index.js",
"unpkg": "dist/pkg.development.js",
"types": "lib/types/index.d.ts",
"esnext": "lib/esnext/index.d.ts",
// 由 bundler 使用的 esm 入口
"module": "lib/esm/index.js",
// 导入单入口
// "exports": "./index.js"
// 导出多个入口
// 未 export 的为私有
// https://nodejs.org/api/esm.html#resolver-algorithm
"exports": {
// 定义后可自引用
".": "./main.mjs",
// import {} from 'pkg/foo'
"./foo": "./foo.js",

// 同时支持 cjs 和 esm
"import": "./index.mjs",
"require": "./index.cjs",
// typescript 4.7+
// https://github.com/microsoft/TypeScript/issues/33079
"types": "./index.ts",

// 指定路径
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
},
// 替代
"./*": {
"types": "./lib/*/index.d.ts",
"default": "./lib/*/index.js"
},
// 允许访问
"./package.json": "./package.json"
},
// Node 条件 resolve
"node": "",
"node-addons": "",
"default": "",
"import": "",
"require": "",
// 社区定义的条件
"browser": "", // build for browser
"deno": "", // build for deno

"development": "", // dev build entrypoint - node --conditions=development main.js
"production": "", // prod build entrypoint

// 针对包的 import map
"imports": {
"#dep": {
"node": "dep-node-native",
"default": "./dep-polyfill.js"
}
},
// 可以 tree shaking
// /*#__PURE__*/
"sideEffects": true,
// 部分文件有 side effetcs
"sideEffects": ["./src/register.js", "*.css", "!(dist/(components|utils)/**)"]
}
{
"bundlewatch": {
"files": [
{
"path": "dist/*.production.min.js"
}
]
}
}

exports

  • TypeScript 4.7 支持 exports
  • TypeScript 5.0 支持 bundler moduleResolution
  • --conditions,-C
    • node --conditions=development index.js
    • 运行 node 指定 condition 会根据 condition resolve
  • 常见类型
    • types - d.ts - 一般放在最前面
    • import - esm - import,import() 使用 ECMAScript module loader
      • 可能 mjs 结尾
    • module
      • 可能 js 结尾
    • require - cjs
    • node - cjs/esm
    • node-addons - native C++ addons
    • default - cjs/esm - 优先级低
      • 注意
        • 一般为 esm
        • 一定要放在最后
        • 不建议,因为不用环境处理逻辑不同
  • 扩展
    • types - 优先级高
    • demo
    • browser - 例如 iife 格式
    • development
      • 有些为源码 - ts
      • 但是有些环境不支持 ts - 例如 nextjs
    • production
  • https://nodejs.org/api/packages.html#conditional-exports
package.json
{
"sideEffects": "false",
"types": "src/.ts",
"main": "dist/cjs/index.js",
"module": "lib/esm/index.mjs",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./lib/esm/index.mjs",
"default": "./lib/cjs/index.js"
},
"./src/": "./src/",
"./icons/*": "./lib/icons/*.json",
"./package.json": "./package.json"
}
}

exports types

  • ts 4.7+
  • package.json - type module
  • tsconfig.json 的 module 设置为 Node12 或 NodeNext

替代方案

package.json
{
"typesVersions": {
"*": {
"index": ["lib/components/index.d.ts"],
"tokens": ["lib/tokens/index.d.ts"]
}
}
}

imports

  • 包内映射 import
{
"imports": {
"#dep": {
"node": "dep-node-native",
"default": "./dep-polyfill.js"
},
"#internal/*.js": "./src/internal/*.js"
},
"dependencies": {
"dep-node-native": "^1.0.0"
}
}
// 根据环境 import dep-node-native 或 polyfill
import '#dep';

self-referencing

Protocol

  • link:
  • workspace:
    • 从 workspace 里选择
    • pnpm
  • pnp:
    • yarn plug & play
  • alias - <alias>@npm:<name>
  • lodash1@npm:lodash@1
  • git+{url}.git
  • <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
    • GIT_ASKPASS
    • GIT_EXEC_PATH
    • GIT_PROXY_COMMAND
    • GIT_SSH
    • GIT_SSH_COMMAND
      • 例如修改 key GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident'
    • GIT_SSL_CAINFO
    • GIT_SSL_NO_VERIFY
  • Github
    • <githubname>/<githubrepo>[#<commit-ish>]
    • github:<githubname>/<githubrepo>[#<commit-ish>]
  • Gist
    • gist:[<githubname>/]<gistID>[#<commit-ish>|#semver:<semver>]
  • bitbucket:<bitbucketname>/<bitbucketrepo>[#<commit-ish>]
  • gitlab:<gitlabname>/<gitlabrepo>[#<commit-ish>]
  • [<@scope>/]<name>@<tag>
  • 也可以 https://github.com/{USER}/{REPO}/tarball/{BRANCH}
caution
# support private
npm install git+ssh://[email protected]:user_name/node_project.git
npm install use_name/node_project#branch_name
npm install use_name/node_project#commit
npm i https://github.com/user_name/node_project_name
npm install gist/gist_id

resolve

  • esm 要求有后缀
  • node 不要求
    • --experimental-specifier-resolution=node

engines

{
"engines": {
"node": "^16 || ^18"
}
}
npx -y check-engine