Author: Docoder @Edamame front-end

Overview

  • Rollup is a packaging tool for front-end modularity that compiles small pieces of code into large, complex pieces of code, such as libraries or applications.
  • Rollup can use new standardized formats for code modules, such as ES6, rather than previous solutions such as CommonJS and AMD.
  • Rollup is widely used for packaging in Javascript libraries

Quick Start

  • rollup-starter-lib

  • rollup-starter-app

For the browser

# compile to a <script> containing a self-executing function ('iife')
$ rollup main.js --flie bundle.js --format iife
Copy the code

For Node.js

# compile to a CommonJS module ('cjs')
$ rollup main.js --file bundle.js --format cjs
Copy the code

For browsers and Node.js

# UMD format requires a bundle name
$ rollup main.js --file bundle.js --format umd --name "myBundle"
Copy the code

For es module

$ rollup ./src/main.js --file ./dist/bundle.js --format es
Copy the code

Why Rollup

Tree-shaking

  • Also called: Live code inclusion

  • Code modules are processed using Rollup, using the ES6 standard (using import/export), allowing static analysis of module files and exclusion of any code that is not actually used

  • Why is ES Module better than CommonJS

    • ES Module is an official standard with a direct and clear direction
    • CommonJS was just a special, temporary, traditional E standard before ES Module
    • The ES Module can do static analysis of files and tree-shaking optimization
    • ES Module provides more advanced features such as circular references and dynamic binding
    • Rollup ES6 modules Playgroup
// To use CommonJS, you must import the entire library

// Import a full utils object using CommonJS
var utils = require( 'utils' );
var query = 'Rollup';
// Use the ajax method of the utils object
utils.ajax( 'https://api.example.com?search=' + query ).then( handleResponse );

// Use the ES6 module without importing the entire library

// Import ajax function using the ES6 import statement
import { ajax } from 'utils';
var query = 'Rollup';
// Calling ajax function
ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
Copy the code

Use Rollup in a CommonJS module

  • Rollup firmly supports ES Modules, CommonJS is not in the Rollup kernel.
  • Need to use plug-insrollup-plugin-commonjsTo convert it to ES Module, which needs to be installed and importedrollup-plugin-node-resolvePlugin, because Rollup, unlike Webpack and Browserify, doesn’t know how to handle dependencies in modules, sorollup-plugin-node-resolveThe plug-in can tell Rollup how to find external modules.
  • Most NPM packages currently come in the form of CommonJS modules, so you’ll need to install and import plug-ins just in caserollup-plugin-commonjs. Also, to prevent other plugin changes from breaking commonJS detection,rollup-plugin-commonjsShould be used before other plug-in conversion modules.

Use it over Webpack ?

  • A number of open-source projects use it over Webpack

  • Webpack has been a huge success, with millions of downloads per month, enabling thousands of websites and apps, and a huge ecosystem and financial backing, Rollup is tiny by comparison

  • Facebook uses Rollup to implement the React build process, merging a large number of pull requests

  • Vue, Ember, Preact, D3, Three.js, Moment, and dozens of other well-known libraries also use Rollup

  • Rollup was created for a different purpose. The purpose of Rollup is to build flat, allocatable Javascript libraries as efficiently as possible. Taking full advantage of the ES Module, it will put all code in one place for validation and generate lighter code faster. Rollup does not support code-Splitting, HMR, and requires plug-ins to handle CommonJS.

  • Webpack supports code-Splitting, which implements a browser-friendly require that validates and packages each module one by one. On-demand loading is great; Otherwise, performance is wasted, especially if you pack a large number of modules.

Conclusion:

Use webpack for apps, and Rollup for libraries

  • If you need code-splitting, which is a lot of static assets, you need to use a lot of CommonJS dependencies, use Webpack
  • If your codebase is ES Module, write code or libraries for other people to use, use Rollup

pkg.module

  • Future, ES Module (importexport) will unify standards and use of libraries will be seamless. However, many browsers and Node.js do not support itimportexportUMD or CommonJS (Nodejs)
  • inpackage.jsonAdd to file"module": "dist/my-library.es.js", can better support both UMD and ES Module
  • Both Webpack and Rollup take advantage of thispkg.moduleTo generate as much efficient code as possible, tree-shaking in some cases

Example: Create a Typescript and React Module

ALL JS LIBRARIES SHOULD BE AUTHORED IN TYPESCRIPT

Install

$ yarn add typescript rollup rollup-plugin-typescript2 rollup-plugin-commonjs  rollup-plugin-peer-deps-external rollup-plugin-node-resolve --dev

$ yarn add react @types/react --dev
$ yarn add react-dom @types/react-dom --dev
Copy the code

tsconfig.json

{ "compilerOptions": { "outDir": "build", "module": "esnext", "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "sourceMap": true, "allowJs": false, "jsx": "react", "declaration": True, / / automatically generated. Which s "moduleResolution" : "node", "forceConsistentCasingInFileNames" : true, "strict" : true, "resolveJsonModule": true, "downlevelIteration": true, "skipLibCheck": true, "esModuleInterop": True, "allowSyntheticDefaultImports" : true}, "include:" [" SRC "], / / search ts file path "exclude" : ["node_modules", "build"]Copy the code

rollup.config.js

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import external from "rollup-plugin-peer-deps-external";
import resolve from "rollup-plugin-node-resolve";

import pkg from "./package.json";

export default {
  input: "src/index.tsx".output: [{file: pkg.main,
      format: "cjs".// exports: "named",
      sourcemap: true
    },
    {
      file: pkg.module,
      format: "es".// exports: "named",
      sourcemap: true}].external: [
    ...Object.keys(pkg.dependencies || {}),
    ...Object.keys(pkg.peerDependencies || {})
  ],
  plugins: [
    commonjs({  // first (otherwise you may need to configure namedExports to prevent errors)
      include: ["node_modules/**"],
    }),
    external(),
    resolve(),
    typescript({
      rollupCommonJSResolveHack: true.exclude: "**/__tests__/**".clean: true}})];Copy the code

package.json

{ "name": "..." , "version": "..." , "description": "..." , "author": "..." , "main": "build/index.js", "module": "build/index.es.js", // pkg.module "jsnext:main": "build/index.es.js", "types": "build/index.d.ts", "license": "..." , "repository": "..." , "keywords": ['...', '...'], "scripts": { "build": "rollup -c", "start": "rollup -c -w", "prepare": "NPM run build" // NPM publish call" pack ", "files": [// only build folder pack "build"], "peerDependencies": {"react": "> = 16.8.0", "the react - dom" : "> = 16.8.0"}, "dependencies" : {... }, "devDependencies" : {" @ types/react ":" ^ 16.8.23 ", "@ types/react - dom" : "^ 16.8.4", "react" : "^ 16.8.6", "the react - dom" : "^ 16.8.6 rollup", ""," ^ 1.16.6 ", "a rollup - plugin - commonjs" : "^ 10.0.1", "a rollup plugin - node - resolve" : "^ 5.2.0 rollup - plugin -", "peer - deps - external" : "^ 2.2.0", "a rollup - plugin - typescript2" : "^ 0.21.2", "typescript" : "^ 3.5.2}}"Copy the code

Developing locally

# in the development library file directory
$ yarn link # will generate a link in the global files (such as: NVM/versions/node/v10.15.3 / lib/node_modules/your package - name), the link to the library file directory

In the example project directory where you want to use the library
$ yarn link your-package-name Link to the global link file, which in turn links to the developed library file directory

# Fix Duplicate React: https://github.com/facebook/react/issues/15315#issuecomment-479802153$ npm link .. /example/node_modules/reactCopy the code