我正在创建一个可共享的React组件库。
库包含许多组件,但最终用户可能只需要使用其中的几个组件。
当您将代码与Webpack (或Parcel或Rollup)捆绑在一起时,它会创建一个包含所有代码的文件。
出于性能原因,除非实际使用,否则我不希望浏览器下载所有的代码。我认为不应该捆绑组件的想法是正确的吗?捆绑应该留给组件的消费者吗?我是否给组件的使用者留下了其他的东西?我是不是只是把它转过来了就这样了?
如果同一个回购包含许多不同的组件,那么main.js中应该包含什么?
发布于 2020-02-01 23:05:47
这是一个非常长的答案,因为这个问题应该得到一个非常长和详细的答案,因为“最佳实践”方法比简单的几行回答要复杂得多。
在这段时间里,我一直在维护我们的内部库,我已经确定了两种方法,我认为图书馆应该捆绑在一起。权衡取决于您的库有多大,就我个人而言,我们编写这两种方法都是为了取悦消费者的两个子集。
方法1:创建一个包含您想要公开的所有内容的index.ts文件,并将该文件的目标汇总作为它的输入。将整个库绑定到单个index.js文件和index.css文件中;使用从使用者项目继承的外部依赖项,以避免库代码的重复。(示例配置底部包含的gist)
import { Foo, Bar } from "library"导入所有内容方法2:这是为高级用户创建的:为每个导出创建一个新文件,并使用rollup plugin-多输入选项"preserveModules: true“,这取决于您使用的CSS系统还需要确保您的CSS不合并到单个文件中,但是每个CSS文件需要(”.css“)语句在汇总后留在输出文件中,并且该CSS文件是存在的。
next-transpile-modules npm包完成的。import { Foo, Bar } from "library",然后使用babel将其转换为.import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"在实际使用这两种方法的情况下,我们有多个汇总配置;因此对于不关心树抖动的库使用者,只需执行"Foo from "library"并导入单个CSS文件,而对于关心树抖动且只使用关键CSS的库使用者,他们只需打开我们的babel插件即可。
汇总最佳实践指南:
无论您是否使用类型记录,都要确保您的"rollup-plugin-babel": "5.0.0-alpha.1"看起来像这样。
{
"presets": [
["@babel/preset-env", {
"targets": {"chrome": "58", "ie": "11"},
"useBuiltIns": false
}],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
["@babel/plugin-transform-runtime", {
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false,
"version": "^7.8.3"
}],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-classes",
["@babel/plugin-proposal-optional-chaining", {
"loose": true
}]
]
}加上babel插件看起来像这样..。
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),你的package.json看起来至少是这样的:
"dependencies": {
"@babel/runtime": "^7.8.3",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"regenerator-runtime": "^0.13.3"
},
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
}最后,你的外挂看起来至少像这样。
const makeExternalPredicate = externalArr => {
if (externalArr.length === 0) return () => false;
return id => new RegExp(`^(${externalArr.join('|')})($|/)`).test(id);
};
//... rest of rollup config above external.
external: makeExternalPredicate(Object.keys(pkg.peerDependencies || {}).concat(Object.keys(pkg.dependencies || {}))),
// rest of rollup config below external.为什么?
最后,这里是一个示例index.js文件输出rollup配置文件的要点。在https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3中,目标src/export/index.ts看起来如下.
export { Button } from "../components/Button/Button";
export * from "../components/Button/Button.styles";
export { Checkbox } from "../components/Checkbox/Checkbox";
export * from "../components/Checkbox/Checkbox.styles";
export { DatePicker } from "../components/DateTimePicker/DatePicker/DatePicker";
export { TimePicker } from "../components/DateTimePicker/TimePicker/TimePicker";
export { DayPicker } from "../components/DayPicker/DayPicker";
// etc etc etc如果您遇到任何关于打包/库的问题,请告诉我。
发布于 2020-01-26 21:47:07
当您将代码与Webpack (或Parcel或Rollup)捆绑在一起时,它会创建一个包含所有代码的文件。 出于性能原因,除非实际使用,否则我不希望浏览器下载所有的代码。
可以为每个组件生成单独的文件。Webpack有这样的能力,通过定义多个条目和输出。假设您有下面的项目结构
- my-cool-react-components
- src // Folder contains all source code
- index.js
- componentA.js
- componentB.js
- ...
- lib // Folder is generated when build
- index.js // Contains components all together
- componentA.js
- componentB.js
- ...Webpack的文件会像这样
const path = require('path');
module.exports = {
entry: {
index: './src/index.js',
componentA: './src/componentA.js',
componentB: './src/componentB.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'lib'),
},
};有关“代码拆分”的更多信息在Webpack博士中
如果同一个回购包含许多不同的组件,那么main.js中应该包含什么?
package.json文件中只有一个名为main的字段,根据上面的项目结构将其值lib/index.js放入其中是很好的。并在index.js文件中导出所有组件。如果使用者想要使用单个组件,只需执行以下操作即可达到
const componentX = require('my-cool-react-components/lib/componentX');我认为不应该捆绑组件的想法是正确的吗?捆绑应该留给组件的消费者吗?我是否给组件的使用者留下了其他的东西?我是不是只是把它转过来了就这样了?
那就看你的了。我发现有些React库是以原始的方式发布的,另一些是以捆绑的方式发布的。如果您需要一些构建过程,那么定义它并导出捆绑版本。
希望,你的所有问题都得到了回答:)
发布于 2020-01-26 21:39:43
您可以像房客为其方法所做的那样拆分您的组件。
您可能拥有的是可以允许单独导入或通过主组件导入的单独组件。
然后消费者就可以导入整个包。
import {MyComponent} from 'my-components';或其个别部分
import MyComponent from 'my-components/my-component';消费者将根据导入的组件创建自己的捆绑包。这应该可以防止下载整个包。
https://stackoverflow.com/questions/59900538
复制相似问题