如何输出具有允许选择性导入的对等依赖项的 NPM 包?
How to output NPM packages with peer dependencies that allow for selective imports?
我正在发布一个使用一些对等依赖项的模块:
在我的 package.json 文件中,我声明了 peerDependencies:
...
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16",
"@material-ui/core": ">=4",
"@material-ui/icons": ">=4"
},
...
在我的 webpack 配置中,我声明了外部变量以及 commonjs2
的输出格式(我完全不确定为什么我会使用 commonjs2
而不是 commonjs
):
...
output: {
filename: 'index.js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, output),
},
externals: {
react: 'react',
'react-dom': 'react-dom',
'@material-ui/core': '@material-ui/core',
'@material-ui/icons': '@material-ui/icons',
},
...
这似乎有效,因为我可以看到输出文件中不包含外部组件。但是,在我的项目中包含此包的输出会导致包大小大得多。
我认为这是因为包的输出将我的 import
语句转换为 require
语句,所以在我使用这个包的项目中,对等依赖项定义为 require
语句无法优化。
换句话说,包的输出不是将 @material-ui/core
库作为构建的一部分,而是将其引用为 require('@material-ui/core')
对吗?
打包对等依赖项的正确方法是什么:
- 他们遵守 commonjs 模块格式(这是必要的)吗?
- 对等依赖的间接导入仍然可以是选择性的?
我认为(但可能是错误的)目前正在发生的事情是:
// In my project where I consume the package
import { Thing } from '@org/package-name'
// And in @org/package-name` source code, I have
import { Card } from '@material-ui/core'
// Which gets transpiled to (more or less)
require('@material-ui/core').Card
// Which means that when I use "Thing", that I'm loading the whole of @material-ui/core
我也试过用 babel-plugin-transform-imports
配置 babel。但我发现我必须为每次导入配置对等依赖项/外部项(@material-ui/core/Card
、@material-ui/core/List
等)
我发现可行的解决方案是在 preset-env 的 babel 配置中将 targets.esmodules 设置为 true。
我认为这对我有用的原因是我在单个条目中重新导出模块。 commonjs 格式的命名导出在导入时不容易隔离?
但这只是一个猜测。
我正在发布一个使用一些对等依赖项的模块:
在我的 package.json 文件中,我声明了 peerDependencies:
...
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16",
"@material-ui/core": ">=4",
"@material-ui/icons": ">=4"
},
...
在我的 webpack 配置中,我声明了外部变量以及 commonjs2
的输出格式(我完全不确定为什么我会使用 commonjs2
而不是 commonjs
):
...
output: {
filename: 'index.js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, output),
},
externals: {
react: 'react',
'react-dom': 'react-dom',
'@material-ui/core': '@material-ui/core',
'@material-ui/icons': '@material-ui/icons',
},
...
这似乎有效,因为我可以看到输出文件中不包含外部组件。但是,在我的项目中包含此包的输出会导致包大小大得多。
我认为这是因为包的输出将我的 import
语句转换为 require
语句,所以在我使用这个包的项目中,对等依赖项定义为 require
语句无法优化。
换句话说,包的输出不是将 @material-ui/core
库作为构建的一部分,而是将其引用为 require('@material-ui/core')
对吗?
打包对等依赖项的正确方法是什么:
- 他们遵守 commonjs 模块格式(这是必要的)吗?
- 对等依赖的间接导入仍然可以是选择性的?
我认为(但可能是错误的)目前正在发生的事情是:
// In my project where I consume the package
import { Thing } from '@org/package-name'
// And in @org/package-name` source code, I have
import { Card } from '@material-ui/core'
// Which gets transpiled to (more or less)
require('@material-ui/core').Card
// Which means that when I use "Thing", that I'm loading the whole of @material-ui/core
我也试过用 babel-plugin-transform-imports
配置 babel。但我发现我必须为每次导入配置对等依赖项/外部项(@material-ui/core/Card
、@material-ui/core/List
等)
我发现可行的解决方案是在 preset-env 的 babel 配置中将 targets.esmodules 设置为 true。
我认为这对我有用的原因是我在单个条目中重新导出模块。 commonjs 格式的命名导出在导入时不容易隔离?
但这只是一个猜测。