Feuilles thermoformées¶
Rouleau - Module ES de nouvelle génération Bundler
Rollup est un groupeur de modules pour JavaScript qui compile de petits morceaux de code en quelque chose de plus grand et plus complexe, comme une bibliothèque ou une application. Il utilise le nouveau format normalisé pour les modules de code inclus dans la révision ES6 de JavaScript.
Sommaire¶
- [Installation] (#installation)
- [Configuration de base] (#basic-configuration)
- [Options d'entrée] (#input-options)
- [Options de sortie] (#output-options)
- [Plugins] (#plugins)
- [dépendances extérieures] (#external-dependencies)
- [Trèvement d'arbre] (#tree-shaking)
- [Doublure du code] (#code-splitting)
- [Mode de surveillance] (#watch-mode)
- [Développement par rapport à la production] (#development-vs-production)
- [Intégration des caractères types] (#typescript-integration)
- [SCS et actifs] (#css-and-assets)
- [Développement de la bibliothèque] (#library-development)
- [Configuration avancée] (#advanced-configuration)
- [Optimisation du rendement] (#performance-optimization)
- [Dépannage] (#troubleshooting)
- [Meilleures pratiques] (#best-practices)
Installation¶
Installation mondiale¶
Installation locale (recommandée)¶
# Initialize npm project
npm init -y
# Install Rollup locally
npm install --save-dev rollup
# Install common plugins
npm install --save-dev @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-babel
```_
### Paquet.json Scripts
```json
{
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"build:prod": "NODE_ENV=production rollup -c"
}
}
```_
## Configuration de base
### Minimal rollup.config.js
```javascript
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'iife'
}
};
Configuration de base complète¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
name: 'MyBundle',
sourcemap: true
},
plugins: [
resolve(),
commonjs(),
terser()
]
};
Configurations multiples¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
const configs = [
// ES module build
{
input: 'src/main.js',
output: {
file: 'dist/bundle.esm.js',
format: 'es'
},
plugins: [resolve(), commonjs()]
},
// UMD build
{
input: 'src/main.js',
output: {
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
},
plugins: [resolve(), commonjs()]
}
];
export default configs;
Configuration environnementale¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: !production
},
plugins: [
resolve(),
commonjs(),
production && terser()
]
};
Options d'entrée¶
Point d'entrée unique¶
Points d'entrée multiples¶
Points d'entrée dynamiques¶
import glob from 'glob';
const entries = glob.sync('src/pages/*.js').reduce((acc, path) => {
const entry = path.replace('src/pages/', '').replace('.js', '');
acc[entry] = path;
return acc;
}, {});
export default {
input: entries
};
Entrée avec dépendances externes¶
Options de sortie¶
Formats de sortie¶
// ES Module
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.esm.js',
format: 'es'
}
};
// CommonJS
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.cjs.js',
format: 'cjs'
}
};
// UMD (Universal Module Definition)
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
}
};
// IIFE (Immediately Invoked Function Expression)
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
name: 'MyApp'
}
};
// AMD (Asynchronous Module Definition)
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.amd.js',
format: 'amd'
}
};
// SystemJS
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.system.js',
format: 'system'
}
};
Formats de sortie multiples¶
export default {
input: 'src/main.js',
output: [
{
file: 'dist/bundle.esm.js',
format: 'es'
},
{
file: 'dist/bundle.cjs.js',
format: 'cjs'
},
{
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
}
]
};
Répertoire des produits¶
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js'
},
output: {
dir: 'dist',
format: 'es',
entryFileNames: '[name].js',
chunkFileNames: '[name]-[hash].js'
}
};
Cartes sources¶
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true, // Generate external source map
// sourcemap: 'inline', // Inline source map
// sourcemap: 'hidden' // Generate but don't reference
}
};
Greffons¶
Greffons essentiels¶
# Install essential plugins
npm install --save-dev @rollup/plugin-node-resolve
npm install --save-dev @rollup/plugin-commonjs
npm install --save-dev @rollup/plugin-babel
npm install --save-dev @rollup/plugin-terser
Plugin de résolution de nœud¶
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
resolve({
browser: true, // Use browser field in package.json
preferBuiltins: false, // Don't prefer Node.js built-ins
extensions: ['.js', '.jsx', '.ts', '.tsx']
})
]
};
Plugin CommonJS¶
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
commonjs({
include: 'node_modules/**', // Convert CommonJS modules
exclude: ['node_modules/foo/**'], // Exclude specific modules
transformMixedEsModules: true // Handle mixed ES/CommonJS modules
})
]
};
Greffon Babel¶
import babel from '@rollup/plugin-babel';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1%', 'last 2 versions']
}
}]
]
})
]
};
Plugin Terser (minification)¶
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
terser({
compress: {
drop_console: true, // Remove console.log
drop_debugger: true // Remove debugger statements
},
format: {
comments: false // Remove comments
}
})
]
};
Remplacer le plugin¶
import replace from '@rollup/plugin-replace';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
'__VERSION__': JSON.stringify(process.env.npm_package_version)
})
]
};
JSON Greffon¶
import json from '@rollup/plugin-json';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
json()
]
};
// Usage in code
import { version } from '../package.json';
console.log(version);
Greffon URL (Assets)¶
import url from '@rollup/plugin-url';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
url({
limit: 10 * 1024, // 10KB limit for inline
include: ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif'],
emitFiles: true
})
]
};
Dépendances extérieures¶
Configuration externe de base¶
export default {
input: 'src/main.js',
external: ['lodash', 'react', 'react-dom'],
output: {
file: 'dist/bundle.js',
format: 'umd',
globals: {
'lodash': '_',
'react': 'React',
'react-dom': 'ReactDOM'
}
}
};
Fonction externe dynamique¶
export default {
input: 'src/main.js',
external: (id) => {
// Mark all node_modules as external
return id.includes('node_modules');
},
output: {
file: 'dist/bundle.js',
format: 'es'
}
};
Dépendances des pairs en tant qu'externes¶
import pkg from './package.json';
export default {
input: 'src/main.js',
external: Object.keys(pkg.peerDependencies || {}),
output: {
file: 'dist/bundle.js',
format: 'es'
}
};
Shaking d'arbre¶
Faire trembler les arbres¶
// Rollup automatically tree-shakes ES modules
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es'
}
};
Shaking d'arbre avec effets secondaires¶
// package.json
{
"sideEffects": false // No side effects, safe to tree-shake
}
// Or specify files with side effects
{
"sideEffects": [
"*.css",
"./src/polyfills.js"
]
}
Préserver les effets secondaires¶
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
treeshake: {
moduleSideEffects: false, // Assume no side effects
// moduleSideEffects: (id) => id.includes('polyfill')
}
};
Exemple de tremblement d'arbre¶
// utils.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export function multiply(a, b) {
console.log('This has a side effect!');
return a * b;
}
// main.js
import { add } from './utils.js'; // Only 'add' will be included
console.log(add(2, 3));
Fractionnement du code¶
Importations dynamiques¶
// main.js
async function loadModule() {
const module = await import('./heavy-module.js');
return module.default();
}
// Rollup config
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'es',
chunkFileNames: '[name]-[hash].js'
}
};
Bouchons manuels¶
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'es',
manualChunks: {
vendor: ['lodash', 'react'],
utils: ['src/utils/helpers.js', 'src/utils/constants.js']
}
}
};
Manuel dynamique Morceaux¶
export default {
input: 'src/main.js',
output: {
dir: 'dist',
format: 'es',
manualChunks: (id) => {
if (id.includes('node_modules')) {
return 'vendor';
}
if (id.includes('src/utils')) {
return 'utils';
}
}
}
};
Découpe des points d'entrée¶
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js',
vendor: 'src/vendor.js'
},
output: {
dir: 'dist',
format: 'es'
}
};
Mode veille¶
Mode de montre de base¶
Configuration de la veille¶
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
watch: {
include: 'src/**',
exclude: 'node_modules/**',
clearScreen: false
}
};
Regarder avec les plugins¶
import livereload from 'rollup-plugin-livereload';
import serve from 'rollup-plugin-serve';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: !production
},
plugins: [
// ... other plugins
!production && serve({
open: true,
contentBase: 'dist',
port: 3000
}),
!production && livereload('dist')
]
};
Développement vs production¶
Configuration environnementale¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
import replace from '@rollup/plugin-replace';
const production = process.env.NODE_ENV === 'production';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: !production
},
plugins: [
resolve(),
commonjs(),
replace({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),
production && terser()
].filter(Boolean)
};
Séparer les fichiers de configuration¶
// rollup.config.dev.js
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true
},
plugins: [
serve({
contentBase: 'dist',
port: 3000
}),
livereload('dist')
]
};
// rollup.config.prod.js
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
terser()
]
};
Paquet.json Scripts¶
{
"scripts": {
"dev": "rollup -c rollup.config.dev.js -w",
"build": "NODE_ENV=production rollup -c rollup.config.prod.js"
}
}
Intégration de typeScript¶
Plugin TypeScript¶
import typescript from '@rollup/plugin-typescript';
export default {
input: 'src/main.ts',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
typescript({
tsconfig: './tsconfig.json'
})
]
};
Configuration du script de type¶
// tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"module": "esnext",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"declaration": true,
"outDir": "dist"
},
"include": [
"src"
]
}
TypeScript avec Babel¶
import typescript from '@rollup/plugin-typescript';
import babel from '@rollup/plugin-babel';
export default {
input: 'src/main.ts',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
typescript(),
babel({
babelHelpers: 'bundled',
extensions: ['.js', '.ts']
})
]
};
CSS et actifs¶
PostCSS Greffon¶
import postcss from 'rollup-plugin-postcss';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
postcss({
extract: true, // Extract to separate CSS file
minimize: true, // Minify CSS
sourceMap: true
})
]
};
SCSS/Sass Support¶
import postcss from 'rollup-plugin-postcss';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
postcss({
extract: 'styles.css',
use: ['sass']
})
]
};
Gestion des actifs¶
import url from '@rollup/plugin-url';
import copy from 'rollup-plugin-copy';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
url({
limit: 10 * 1024, // 10KB
include: ['**/*.svg', '**/*.png', '**/*.jpg'],
emitFiles: true
}),
copy({
targets: [
{ src: 'src/assets/images/*', dest: 'dist/images' },
{ src: 'src/assets/fonts/*', dest: 'dist/fonts' }
]
})
]
};
Développement des bibliothèques¶
Configuration de la bibliothèque¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
import pkg from './package.json';
export default [
// ES module build
{
input: 'src/index.js',
external: Object.keys(pkg.peerDependencies || {}),
output: {
file: pkg.module,
format: 'es'
},
plugins: [
resolve(),
commonjs()
]
},
// CommonJS build
{
input: 'src/index.js',
external: Object.keys(pkg.peerDependencies || {}),
output: {
file: pkg.main,
format: 'cjs'
},
plugins: [
resolve(),
commonjs()
]
},
// UMD build
{
input: 'src/index.js',
output: {
file: pkg.browser,
format: 'umd',
name: 'MyLibrary',
globals: {
'react': 'React',
'react-dom': 'ReactDOM'
}
},
plugins: [
resolve(),
commonjs(),
terser()
]
}
];
Package.json pour Bibliothèque¶
{
"name": "my-library",
"version": "1.0.0",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"browser": "dist/index.umd.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "rollup -c",
"prepublishOnly": "npm run build"
},
"peerDependencies": {
"react": "^17.0.0",
"react-dom": "^17.0.0"
}
}
TypeScript Bibliothèque¶
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.ts',
output: [
{
file: 'dist/index.esm.js',
format: 'es'
},
{
file: 'dist/index.cjs.js',
format: 'cjs'
}
],
plugins: [
typescript({
declaration: true,
declarationDir: 'dist'
}),
resolve(),
commonjs()
]
};
Configuration avancée¶
Plugin personnalisé¶
function myPlugin() {
return {
name: 'my-plugin',
buildStart(opts) {
console.log('Build started');
},
transform(code, id) {
if (id.endsWith('.special')) {
return `export default ${JSON.stringify(code)}`;
}
},
generateBundle(opts, bundle) {
console.log('Bundle generated');
}
};
}
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
myPlugin()
]
};
Constructions conditionnelles¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
const configs = [];
// Development build
if (process.env.NODE_ENV !== 'production') {
configs.push({
input: 'src/main.js',
output: {
file: 'dist/bundle.dev.js',
format: 'iife',
sourcemap: true
},
plugins: [resolve(), commonjs()]
});
}
// Production build
if (process.env.NODE_ENV === 'production') {
configs.push({
input: 'src/main.js',
output: {
file: 'dist/bundle.min.js',
format: 'iife'
},
plugins: [resolve(), commonjs(), terser()]
});
}
export default configs;
Multi-entrée avec dépendances partagées¶
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js'
},
output: {
dir: 'dist',
format: 'es',
manualChunks: {
vendor: ['lodash', 'react'],
shared: ['src/utils/shared.js']
}
}
};
Optimisation des performances¶
Analyse de l'ensemble¶
# Install bundle analyzer
npm install --save-dev rollup-plugin-analyzer
# Use in config
import analyze from 'rollup-plugin-analyzer';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
analyze({
summaryOnly: true,
limit: 10
})
]
};
Optimiser les dépendances¶
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
resolve({
preferBuiltins: false,
browser: true
}),
commonjs({
include: 'node_modules/**'
})
]
};
Minimiser la taille du bloc¶
import { terser } from 'rollup-plugin-terser';
import replace from '@rollup/plugin-replace';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify('production')
}),
terser({
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.info']
}
})
]
};
Dépannage¶
Questions et solutions communes¶
Dépendances circulaires¶
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
onwarn: (warning, warn) => {
if (warning.code === 'CIRCULAR_DEPENDENCY') {
console.warn('Circular dependency:', warning.message);
return;
}
warn(warning);
}
};
Dépendances extérieures Non trouvé¶
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
resolve({
browser: true,
preferBuiltins: false
})
]
};
Questions relatives au module CommonJS¶
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
commonjs({
include: 'node_modules/**',
transformMixedEsModules: true
})
]
};
Problèmes de mémoire¶
Configuration de débogage¶
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
onwarn: (warning, warn) => {
console.log('Warning:', warning);
warn(warning);
}
};
Meilleures pratiques¶
Organisation de configuration¶
// rollup.config.js
import { createConfig } from './config/rollup.common.js';
const configs = [
createConfig('es'),
createConfig('cjs'),
createConfig('umd')
];
export default configs;
// config/rollup.common.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export function createConfig(format) {
return {
input: 'src/index.js',
output: {
file: `dist/bundle.${format}.js`,
format
},
plugins: [
resolve(),
commonjs()
]
};
}
Meilleures pratiques en matière de rendement¶
- Utilisez les modules ES pour mieux secouer les arbres
- ** Marquer les dépendances externes** pour réduire la taille du paquet
- Activer le fractionnement du code pour les grandes applications
- ** Utiliser terser** pour la minification de la production
- Analysez les faisceaux pour identifier les possibilités d'optimisation
Meilleures pratiques de développement¶
- Utilisez le mode veille pour le développement
- Activer les cartes sources pour le débogage
- Set up live reload pour un meilleur DX
- Configurer le lintage avec ESLint
- Utilisez TypeScript pour une meilleure sécurité de type
Développement des bibliothèques Meilleures pratiques¶
- Fournir plusieurs formats (ES, CJS, UMD)
- Générer les déclarations TypeScript pour les utilisateurs de TypeScript
- ** Marquer les dépendances des pairs** comme externes
- Utilisez la version sémantique pour les versions
- Builds de test avant publication
Résumé¶
Rollup est un bundler puissant qui excelle dans la création de bundles optimisés pour les bibliothèques et les applications. Les principales caractéristiques sont les suivantes :
- ES Module First: Support natif pour les modules ES avec un excellent tremblement d'arbre
- ** Formats de sortie multiples**: support pour ES, CJS, UMD, IIFE, AMD et SystemJS
- Écosystà ̈me Plugin: Riche écosystème de plugins pour différentes transformations
- Doublure du code: Capacités avancées de fractionnement du code
- Tree Shaking: élimination automatique du code mort
- TypeScript Support: Intégration de typeScript de première classe
- Bibliothèque conviviale: Excellente pour la construction et la distribution de bibliothèques
En tirant parti des forces de Rollup et en suivant les meilleures pratiques, vous pouvez créer des faisceaux hautement optimisés qui sont parfaits pour le développement de bibliothèques et la construction d'applications.