Answers:
这是一个非常漫长的答案,因为该问题值得一个非常漫长而详尽的答案,因为“最佳实践”的方式要比仅几行回答更为复杂。
在那段时间里,我将我们的内部图书馆维持了3.5年以上,我以两种方式解决我认为图书馆应该捆绑在一起的问题,取舍取决于您的图书馆的规模,而我们个人汇编两种方式来取悦两个子集消费者。
方法1:创建一个index.ts文件,将要公开的所有内容导出并以该文件的目标汇总作为输入。将整个库捆绑到单个index.js文件和index.css文件中;用外部依赖项从使用者项目继承来避免重复的库代码。(要点包含在示例配置的底部)
import { Foo, Bar } from "library"
方法2:适用于高级用户:为每个导出创建一个新文件,并使用rollup-plugin-multi-input和“ preserveModules:true”选项,具体取决于您所使用的CSS系统,还需要确保您的css不会合并到单个文件中,而是在汇总后每个css文件require(“。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"
请确保您的.babelrc如下所示。
{
"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看起来像ATLEAST:
"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",
}
最后,您的外部汇总看起来像这样的ATLEAST。
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文件输出汇总配置文件的要点。 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
如果您在使用babel,汇总时遇到任何问题,或者对捆绑/库有任何疑问,请告诉我。
当您将代码与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');
我是否认为我不应该捆绑组件是正确的吗?捆绑产品应该留给组件的使用者使用吗?我是否还要将其他东西留给组件的使用者?我只是编译JSX就是这样吗?
好吧,这取决于您。我发现有些React库是以原始方式发布的,其他的则是以捆绑方式发布的。如果您需要一些构建过程,请对其进行定义并导出捆绑的版本。
希望您的所有问题都能得到回答:)
您可以像lodash一样拆分组件为它们的方法。
您可能拥有的是单独的组件,您可以允许它们分别导入或通过主组件导入。
然后,消费者可以导入整个包装
import {MyComponent} from 'my-components';
或其各个部分
import MyComponent from 'my-components/my-component';
消费者将根据他们导入的组件创建自己的捆绑包。那应该防止您的整个捆绑包被下载。
imported
代码中的那些文件,从而减小捆绑包的大小。