Đây là một câu trả lời cực kỳ dài bởi vì câu hỏi này xứng đáng có một câu trả lời cực kỳ dài và chi tiết vì cách "thực hành tốt nhất" phức tạp hơn chỉ là một vài câu trả lời.
Iv'e đã duy trì các thư viện nội bộ của chúng tôi trong hơn 3,5 năm trong thời gian đó. Họ đã giải quyết theo hai cách tôi nghĩ rằng các thư viện nên được kết hợp với sự đánh đổi tùy thuộc vào thư viện của bạn lớn như thế nào và cá nhân chúng tôi biên dịch cả hai cách để làm hài lòng cả hai tập hợp con người tiêu dùng.
Phương pháp 1: Tạo tệp index.ts với mọi thứ bạn muốn được hiển thị và cuộn mục tiêu tại tệp này làm đầu vào. Gói toàn bộ thư viện của bạn vào một tệp index.js và tệp index.css; Với sự phụ thuộc bên ngoài được kế thừa từ dự án tiêu dùng để tránh trùng lặp mã thư viện. (ý chính bao gồm ở dưới cùng của cấu hình ví dụ)
- Ưu điểm: Dễ tiêu thụ vì người tiêu dùng dự án có thể nhập mọi thứ từ đường dẫn thư viện gốc
import { Foo, Bar } from "library"
- Nhược điểm: Điều này sẽ không bao giờ bị rung chuyển cây; và trước khi mọi người nói làm điều này với ESM và nó sẽ được treeshakizable. NextJS không hỗ trợ ESM ở giai đoạn hiện tại và cũng không có nhiều thiết lập dự án, đó là lý do tại sao vẫn nên biên dịch bản dựng này cho chỉ CJS. Nếu ai đó nhập 1 trong các thành phần của bạn, họ sẽ nhận được tất cả css và tất cả javascript cho tất cả các thành phần của bạn.
Phương pháp 2: Cách này dành cho người dùng nâng cao: Tạo một tệp mới cho mỗi lần xuất và sử dụng rollup-plugin-multi-input với tùy chọn "reservedModules: true" tùy thuộc vào cách hệ thống css bạn đang sử dụng cũng cần đảm bảo rằng css của bạn KHÔNG được hợp nhất thành một tệp duy nhất nhưng mỗi tệp css yêu cầu câu lệnh (". css") được để lại bên trong tệp đầu ra sau khi cuộn và tệp css đó tồn tại.
- Ưu điểm: Khi người dùng nhập {Foo} từ "library / dist / foo", họ sẽ chỉ nhận được mã cho Foo và css cho Foo và không có gì nữa.
- Nhược điểm: Thiết lập này liên quan đến việc người tiêu dùng phải xử lý các câu lệnh node_modules yêu cầu (". Css") trong cấu hình xây dựng của họ với NextJS, việc này được thực hiện với
next-transpile-modules
gói npm.
- Hãy cẩn thận: Chúng tôi sử dụng plugin babel của riêng mình mà bạn có thể tìm thấy ở đây: https://www.npmjs.com/package/babel-plugin-qubic để cho phép mọi người
import { Foo,Bar } from "library"
và sau đó với babel chuyển đổi nó thành ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
Chúng tôi có nhiều cấu hình rollup trong đó chúng tôi thực sự sử dụng cả hai phương pháp; vì vậy, đối với những người tiêu dùng thư viện không quan tâm đến việc rung cây, chỉ có thể thực hiện "Foo from "library"
và nhập tệp css duy nhất; và đối với những người tiêu dùng thư viện chăm sóc cây lắc và chỉ sử dụng css quan trọng, họ có thể bật plugin babel của chúng tôi.
Hướng dẫn cuộn cho thực hành tốt nhất:
cho dù bạn đang sử dụng bản in hay không LUÔN LUÔN xây dựng với "rollup-plugin-babel": "5.0.0-alpha.1"
Đảm bảo .babelrc của bạn trông như thế này.
{
"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
}]
]
}
Và với plugin babel trong rollup trông như thế này ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
Và gói.json của bạn trông ATLEAST như thế này:
"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",
}
Và cuối cùng, phần bên ngoài của bạn trong rollup trông ATLEAST như thế này.
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.
Tại sao?
- Điều này sẽ bó shit của bạn để tự động kế thừa Reac / Reac-dom và các phụ thuộc ngang hàng / bên ngoài khác của bạn từ dự án tiêu dùng có nghĩa là chúng sẽ không bị trùng lặp trong gói của bạn.
- Điều này sẽ đi kèm với ES5
- Điều này sẽ tự động yêu cầu ("..") trong tất cả các hàm của trình trợ giúp babel cho objectS rải, các lớp, v.v ... TỪ dự án tiêu dùng sẽ xóa 15-25KB khác từ kích thước gói của bạn và có nghĩa là các hàm trợ giúp cho objectS Lan sẽ không được sao chép trong thư viện của bạn đầu ra + các dự án tiêu thụ đi kèm đầu ra.
- Các chức năng Async vẫn sẽ hoạt động
- bên ngoài sẽ phù hợp với bất cứ điều gì bắt đầu với hậu tố phụ thuộc ngang hàng đó, ví dụ như người trợ giúp babel sẽ phù hợp với bên ngoài cho người trợ giúp / người giúp đỡ / người truyền bá đối tượng
Cuối cùng, đây là một ý chính cho một ví dụ về tệp cấu hình cuộn lên của tệp index.js.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Trường hợp src / export / index.ts mục tiêu trông như thế này ...
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
Hãy cho tôi biết nếu bạn gặp bất kỳ vấn đề nào với babel, rollup hoặc có bất kỳ câu hỏi nào về gói / thư viện.
imported
trong mã do đó làm giảm kích thước gói.