מפתחים חבילת npm או מערכת עיצוב? תצורת bundler שגויה מובילה לחבילות מנופחות ולבעיות ב-tree-shaking. הצוות שלנו, עם ניסיון של 5 שנים ו-50+ פרויקטי Rollup, מגדיר תצורות אופטימליות. לפי הנתונים שלנו, Rollup מוגדר כראוי מפחית את גודל החבילה ב-30–40% בממוצע. במאמר זה נעבור על מקרים אמיתיים: הכנת ספרייה ל-ESM/CJS/UMD, החרגת תלויות מיותרות, ואוטומציה של בניות CI. כפי שצוין ב-תיעוד Rollup, tree-shaking מסתמך על ניתוח ייבוא סטטי — המאפשר הסרת קוד שאינו בשימוש ברמת דיוק של סמל.
מתי לבחור ב-Rollup על פני Vite או Webpack?
Rollup אינו כלי אוניברסלי. עבור SPA עם טעינה חמה ושרת פיתוח, Vite (המשתמש ב-Rollup פנימית לבניות ייצור) נוח יותר. Rollup נבחר כאשר יש צורך:
- לארוז ספרייה בפורמטים ESM + CJS + UMD בו-זמנית
- לקבל פלט נקי ללא עטיפות מיותרות
- לשלוט אילו תלויות נכללות בחבילה ואילו נשארות חיצוניות
- ליצור הצהרות TypeScript לצד קבצי הבנייה
העברנו פרויקטים שבהם החלפת Webpack ב-Rollup הפחיתה את גודל הקובץ הסופי מ-200 KB ל-120 KB וקיצרה את זמן הבנייה ב-40%.
התקנה ותצורה בסיסית
npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript rollup-plugin-dts rollup-plugin-postcss @rollup/plugin-url rollup-plugin-visualizer glob npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript rollup-plugin-dts rollup-plugin-postcss @rollup/plugin-url rollup-plugin-visualizer glob עבור ספריית TypeScript טיפוסית עם תמיכה ב-ESM/CJS והצהרות:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import dts from 'rollup-plugin-dts';
import { defineConfig } from 'rollup';
import pkg from './package.json' assert { type: 'json' };
export default defineConfig([
{
input: 'src/index.ts',
external: Object.keys(pkg.peerDependencies ?? {}),
plugins: [
resolve({ extensions: ['.ts', '.tsx'] }),
commonjs(),
typescript({ tsconfig: './tsconfig.build.json' }),
],
output: [
{ file: pkg.module, format: 'esm', sourcemap: true },
{ file: pkg.main, format: 'cjs', sourcemap: true, exports: 'named' },
],
},
{
input: 'dist/types/index.d.ts',
output: { file: 'dist/index.d.ts', format: 'esm' },
plugins: [dts()],
},
]);
כיצד להצהיר כראוי על ייצואים ב-package.json?
rollup.config.ts מודרני עבור ספרייה צריך לכלול שדה import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; import dts from 'rollup-plugin-dts'; import { defineConfig } from 'rollup'; import pkg from './package.json' assert { type: 'json' }; export default defineConfig([ { input: 'src/index.ts', external: Object.keys(pkg.peerDependencies ?? {}), plugins: [ resolve({ extensions: ['.ts', '.tsx'] }), commonjs(), typescript({ tsconfig: './tsconfig.build.json' }), ], output: [ { file: pkg.module, format: 'esm', sourcemap: true }, { file: pkg.main, format: 'cjs', sourcemap: true, exports: 'named' }, ], }, { input: 'dist/types/index.d.ts', output: { file: 'dist/index.d.ts', format: 'esm' }, plugins: [dts()], }, ]); לפתרון מודולים ברור. מיפוי נכון לדוגמה:
| שדה | ערך |
|---|---|
| main | dist/index.cjs.js |
| module | dist/index.esm.js |
| types | dist/index.d.ts |
| exports."." | { import: "./dist/index.esm.js", require: "./dist/index.cjs.js", types: "./dist/index.d.ts" } |
| files | ["dist"] |
כיצד להחריג תלויות peer מהחבילה?
טעות נפוצה היא לכלול את React או lodash בחבילת ספרייה. השתמש ב-package.json כדי לרשום את כל תלויות ה-peer והתלויות שלא אמורות להופיע בקובץ הסופי:
const external = [
...Object.keys(pkg.peerDependencies ?? {}),
...Object.keys(pkg.dependencies ?? {}),
];
// Частичная экстернализация — исключить только часть пакета
// external: (id) => id.startsWith('react') || /^lodash/.test(id), כיצד להוסיף CSS ונכסים?
עבור מודולי CSS, השתמש ב-exports. עבור תמונות ו-SVG, השתמש ב-const external = [ ...Object.keys(pkg.peerDependencies ?? {}), ...Object.keys(pkg.dependencies ?? {}), ]; // Частичная экстернализация — исключить только часть пакета // external: (id) => id.startsWith('react') || /^lodash/.test(id), . תצורה:
- postcss עם
rollup-plugin-postcssו-@rollup/plugin-url - url עם
modules: true(הטמעה עד 8KB) ו-extract: 'dist/styles.css'
בנייה עם מספר נקודות כניסה לרכיבים
אם הספרייה שלך מאפשרת ייבוא כל רכיב בנפרד (לדוגמה, limit: 8192), השתמש במספר נקודות כניסה עם destDir: 'dist/assets':
import { glob } from 'glob';
const entries = Object.fromEntries(
(await glob('src/components/**/*.tsx')).map((file) => [
file.replace('src/', '').replace(/\.tsx$/, ''),
file,
])
);
export default defineConfig({
input: entries,
output: {
dir: 'dist',
format: 'esm',
preserveModules: true,
preserveModulesRoot: 'src',
},
});
import Button from 'ui/Button' שומר על מבנה התיקיות, ומאפשר tree-shaking ברמת קובץ.
ניתוח גודל חבילה
import { visualizer } from 'rollup-plugin-visualizer';
plugins: [
visualizer({
filename: 'dist/stats.html',
gzipSize: true,
brotliSize: true,
}),
]לאחר הבנייה, פתח את preserveModules — עץ תלויות אינטראקטיבי עם גדלים אמיתיים. המושג של tree-shaking — הסרת קוד שאינו בשימוש בזמן בנייה — מומחש כאן.
מצב צפייה ופיתוח
לפיתוח ספרייה במקביל לאפליקציה, השתמש ב-import { glob } from 'glob'; const entries = Object.fromEntries( (await glob('src/components/**/*.tsx')).map((file) => [ file.replace('src/', '').replace(/\.tsx$/, ''), file, ]) ); export default defineConfig({ input: entries, output: { dir: 'dist', format: 'esm', preserveModules: true, preserveModulesRoot: 'src', }, }); או הגדר preserveModules. במונוריפו, השתמש בקישורי workspace.
שלבי הגדרה מלאה
- בדיקת בנייה קיימת (אם יש) — הערכת תצורה ותלויות.
- עיצוב מפת ייצוא — קביעת פורמטים ונתיבים.
- הגדרת TypeScript והצהרות — tsconfig, תוספים.
- שילוב CSS ונכסים — postcss, url.
- אופטימיזציה של תלויות חיצוניות — החרגת חבילות מיותרות.
- הוספת visualizer ו-analyzer — יצירת סטטיסטיקות.
- בדיקה ב-CI/CD — הבטחת יציבות.
כל שלב כולל בדיקות איכות: לאחר הבדיקה אנו מספקים דוח עם המלצות; לאחר ההגדרה אנו מריצים בניית בדיקה ומאמתים אותה ב-CI. חודש תמיכה חינם לאחר היישום.
מה כלול בתוצאה?
עם סיום, תקבל:
- תצורת Rollup עובדת עם תוספים מותאמים למחסנית שלך
- מפת ייצוא ב-package.json לכל הפורמטים
- הצהרות TypeScript (d.ts) לצד קבצי הבנייה
- שילוב CSS ונכסים, אם נדרש
- תצורת CI/CD (GitHub Actions או GitLab CI)
- דוח ניתוח גודל חבילה (plato, stats.html)
- ייעוץ לשימוש בבנייה המוגמרת
מדוע תלויות חיצוניות כל כך חשובות?
ללא הגדרת external נכונה, אתה מסתכן באריזת מסגרות שלמות כמו React, מה שמנפח את הספרייה שלך מ-10 KB ל-500+ KB. למשתמשי הספרייה שלך כבר יש תלויות אלה בפרויקט שלהם — כפילות מובילה לשגיאות ולנפיחות בחבילה. הגדרת external עם peerDependencies ו-dependencies היא חובה לכל ספרייה.
לוחות זמנים
| סוג הגדרה | זמן משוער |
|---|---|
| בסיסי (נקודת כניסה אחת, ESM+CJS, הצהרות) | 2–4 שעות |
| מורכב (CSS, נכסים, מספר נקודות כניסה, CI) | 1–2 ימים |
אחריות לתפקוד ב-CI/CD ותמיכה לאחר ההגדרה. הזמן בדיקה של הבנייה הידנית הנוכחית שלך — נזהה צווארי בקבוק ונציע אופטימיזציה. קבל ייעוץ ממהנדס שהגדיר Rollup לעשרות ספריות.







