Rollup is the next generation ES module bundler

Do not read rollup.js, because it is translated by someone else, not updated in real time, I used to see this installation error

I have searched for relevant rollup usage on the Internet before, and some articles are very difficult to understand, without specific steps; Some articles are not detailed enough, without context. So plan to sort out an article to reduce detours for later comers. I promise this article is really hands-on and down-to-earth, because I’m writing as I’m building a project, not code in a project, so the code is clear and there’s no redundancy.

Why not use Webpack

When it comes to packaging tools, everyone thinks of Webpack, because the vUE and React scaffolding we use are all based on WebPack. It has various loaders to help us solve various problems, which is very effective for development projects. But the generated code has a lot of logic code that is not written by us, such as some of his own module loading functions:

If you are developing JS libraries, the complexity of Webpack and the size of the packed files are not suitable. Where there are requirements, there are tools, so rollup was created to develop JS libraries.

Rollup does nothing but transcode our code to target JS, and if needed it can also generate UMD/CommonJS /es js code. Vue/React/Angular uses it as a package tool. You can see rollup in their official code.

Quick start

1. New construction

Create an empty folder, such as rollupDemo, and perform the project initialization

npm init -y
Copy the code

2. Install the rollup

Open the project with vscode and run the install command

npm install rollup --save-dev
Copy the code

After execution, we see that the project automatically produced some files and saw rollup in the package.

Add gitignore and ignore files that do not need to be uploaded

.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

Copy the code

3. Create a rollup. Config. Js

We could also use the CLI command to package without the configuration file, but if we add more options, this command line approach becomes cumbersome. To do this, we can create a configuration file to include the required options. Configuration files are written in JavaScript, which is more flexible than CLI. (See the cli command package on the official website)

The configuration file is an ES6 module that exposes an object that contains some options for Rollup. Normally, we call this configuration file rollup.config.js and it is usually located in the root directory of the project, with some configuration options below

// rollup.config.js export default {// core options input, // must external, plugins, // additional options onwarn, // Danger zone acorn, context, moduleContext, legacy output: {// must (if you want to output more than one, // Optional paths, banner, Footer, Intro, outro, sourcemap, SourcemapFile, interop, // high risk options exports, AMD, indent strict},};Copy the code

Rollup.config. js current configuration

export default {
  input:'./src/main.js'.// Import file
  output: {file:'./dist/bundle.js'.// Save the file after packing
    format:'cjs'.// Output format AMD ES6 IIFE UMD CJS
    name:'bundleName'If iife, umD needs to specify a global variable}}Copy the code

4. Write files to package

1. Create a SRC folder and create main.js(application entry)

import { name } from './modules/myModole';
console.log('hello' + name);
Copy the code

2. Create a modules folder (representing the module file)

Modules distinguish between modules and the main entry, modules can be based on your own JS library design file directory structure.

Modules /myModole file contents

export const name = 'jiaHang'
export const age = 18

Copy the code

5. Write the packaging command in package.json

Add a script statement to package.json

{
  "name": "rollupDemo"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "build": "rollup --config"
  },
  "keywords": []."author": ""."license": "ISC"."devDependencies": {
    "rollup": "^ 2.45.2",}}Copy the code

6. Run the NPM run build command to view the output

'use strict';

const name = 'jiaHang';

console.log('hello' + name);

Copy the code

We can see that the output is very clean, there is no extra code like WebPack, and the myMoudule is not packed. This is the tree-shaking of rollup, which we will talk about later.

7. Use packaged files

Create a new index.html file under SRC and import the bundled bundle.js to see the log printed in the console

When we open up this page we see a popup saying Hello from Rollup

Commonly used configuration

1.input

Entry file address

2.output

Output :{file:'bundle.js', // output file format: 'CJS, // Five output formats: AMD/ES6 / iife/umD/CJS Name :'A', // Must be provided when format is iife and UMD, will be hung as A global variable in window(browser environment) : window.a =... Sourcemap :true // Generate bundle.map.js for debugging}Copy the code

3.plugins

Configurations used by various plug-ins

4.external

External :['lodash'] // tells rollup not to package this lodash as an external dependencyCopy the code

5.global

Global :{'jquery':'$' // tells rollUp that $is jquery}Copy the code

Further use

1. The use of Babel

To properly parse our module and make it compatible with older browsers, we should include Babel to compile the output. Many developers use Babel in their projects so that they can use features from future versions of JavaScript that are not supported by browsers and Node.js.

1.1 installation rollup – plugin – Babel

npm install rollup-plugin-babel --save-dev
Copy the code

1.2 configuration rollup. Config. Js

import babel from 'rollup-plugin-babel'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'
  },
  plugins: [
    babel({
      exclude: 'node_modules/**'}})]Copy the code

1.3 Adding the Babel configuration file babelrc

Add. Babelrc in the SRC folder

{
  "presets": [["@babel/env",
      {
        "modules": false // Set it to false, otherwise Babel will cause our module to convert to CommonJS before rollup has a chance to perform its operation}}]]Copy the code

There is something unusual about this setup.

First, we set “modules”: false, otherwise Babel will convert our module to CommonJS before Rollup has a chance to do any processing, causing some processing of Rollup to fail.

Second, we place the.babelrc file in SRC instead of the root directory. This allows us to have different.babelrc configurations for different tasks, such as tests, if we need them later – it’s usually better to configure them separately for individual tasks.

1.4 Install @babel/core and @babel/preset-env

@babel/core is the core of Babel, we see that Babelrc is configured with preset Env, so install these two plug-ins

npm install @babel/core @babel/preset-env --save-dev
Copy the code

When we run NPM run build, we see that Babel transforms the contents of the packaged file into ES5 syntax

'use strict';

var name = 'jiaHang';

console.log('hello' + name);
Copy the code

2. Reference to the Node module

At some point, your project may depend on packages installed from NPM into the node_modules folder.

Unlike other bundled software such as Webpack and Browserify, Rollup doesn’t know how to handle these dependencies out of the box – we need to add some plug-in configuration.

By default, only ES6+ import/export is supported for modules in rollup.js compiled source code. However, a large number of NPM modules are based on CommonJS modules, which results in a large number of NPM modules cannot be compiled directly. This is why plug-ins that support NPM and CommonJS modules are compiled to assist rollup.js.

  • The rollup-plugin-node-resolve plug-in allows us to load third-party modules
  • The @rollup/ plugin-Commons plugin converts them to the ES6 version

2.1 Install @rollup/plugin-node-resolve and @rollup/plugin-commonjs

npm install @rollup/plugin-node-resolve @rollup/plugin-commonjs --save-dev
Copy the code

2.2 configuration rollup. Config. Js

2.3 Use a third-party library called LoDash

npm install lodash --save-dev
Copy the code

Open SRC /main.js to use Lodash

import { name } from './modules/myModole';
import _ from 'lodash'
console.log('hello' + name);
const arr = _.concat([1.2].3.4[5]);
console.log(arr);

Copy the code

After executing the NPM run build, we see a lot more content in the packaged file. This code is the loDash code, which we packaged and integrated.

2.4 Additional

External can be configured in rollup.config.js if you don’t want third-party libraries packaged in and can be used outside

import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'
  },
  plugins: [
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'})].external: ['lodash']}Copy the code

Less content is packaged after NPM run build

'use strict';

var _ = require('lodash');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var ___default = /*#__PURE__*/_interopDefaultLegacy(_);

var name = 'jiaHang';

console.log('hello' + name);

var arr = ___default['default'].concat([1.2].3.4[5]);

console.log(arr);

Copy the code

Then the page usage was changed a little bit, script was introduced into LoDash, using iife packaged files (because of the way we use page references here), and viewing the page output was normal.

3. Use the typescript

When developing large projects, we use typescript to make our code more maintainable. So using typescript in rollup is essential.

3.1 installation @ rollup/plugin – typescript

I used rollup-plugin-typescript, but as I write this article today, the plugin is no longer maintained and the module is ported to @rollup/plugin-typescript

npm install @rollup/plugin-typescript --save-dev
Copy the code

After installation, we get an error telling us to install tslib and typescript

3.2 Installing Tslib and typescript

npm install tslib typescript --save-dev
Copy the code

3.3 configuration rollup. Config. Js

Introducing plug-ins

import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'
import typescript from '@rollup/plugin-commonjs'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'
  },
  plugins: [
    typescript(),
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'})].external: ['lodash']}Copy the code

3.4 configuration tsconfig. Json

If you run NPM run build without the configuration, you will be prompted to create a new tsConfig configuration

{
  "compilerOptions": {
    "lib": [
      "es6"]."module": "ESNext"."allowJs": true
  },
  "exclude": [
    "node_modules"]."include": [
    "src/**/*"]}Copy the code

3.5 Writing TS Files

Greeter.ts

class Greeter {
  greeter: string;

  constructor(message: string) {
    this.greeter = message
  }

  greet() {
    console.log('hello ts'); }}export default Greeter
Copy the code

main.js

import { name } from './modules/myModole';
import Greeter from './modules/Greeter';
import _ from 'lodash';

const a = new Greeter('ss');
a.greet()
console.log('hello' + name);
const arr = _.concat([1, 2], 3, 4, [5]);
console.log(arr);

Copy the code

4. Compress code

To make the code smaller, we use code compression plug-ins

4.1 installation rollup – plugin – terser

What is Terser, which is a JavaScript parser, Mangler, and compressor toolkit for ES6 +

We are familiar with uglify because we used it in webpack and rollup also has rollup-plugin-uglify

Note that uglip-js can only translate ES5 syntax. To translate es6+ syntax, use Terser instead

So we use rollup-plugin-terser

npm install rollup-plugin-terser --save-dev
Copy the code

4.2 configuration rollup. Config. Js

import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'
import typescript from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'
  },
  plugins: [
    typescript(),
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'
    })
    terser()
  ],
  external: ['lodash']}Copy the code

5. Compile the CSS

Development projects we use Webpack, develop JS class library, rollup is better than Webpack. If you want to write a lot of CSS, then you may be working on a project. Choose WebPack first. Webpack also has the configuration to develop library.

Rollup also has plug-ins to compile CSS if you still need to write CSS in your js library

5.1 installation rollup – plugin – postcss

npm install rollup-plugin-postcss --save-dev
Copy the code

5.2 configuration rollup. Config. Js

Introduce the PostCSS plugin and use it, first commenting out the zip plugin so we can see what the packaged CSS looks like.


import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'
import typescript from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import postcss from 'rollup-plugin-postcss'

export default {
  input: './src/main',
  output: {
    file: './dist/bundle.js',
    format: 'cjs',
    name: 'bundleName'
  },
  plugins: [
    typescript(),
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'
    }),
    // terser(),
    postcss()
  ],
  external: ['lodash']
}

Copy the code

5.3 Writing using the CSS

1. Write the style. CSS file in the SRC directory

2. Write the relevant CSS usage code in main.js

3. Run the NPM run build command to view the content of the packed file. We see CSS introduced dynamically through this code

4. Open the page to view the HTML code

It is also possible to precompile using less, if necessary, ask me questions and I will update.

6. Start the local server

During actual development, when you’re definitely running code and looking at pages, it’s important to have a local server so you can debug the code.

6.1 installation rollup – plugin – serve

npm install rollup-plugin-serve --save-dev
Copy the code

6.2 configuration rollup. Config. Js

Remember to configure sourcemap: true for easy debugging.

import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'
import typescript from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import postcss from 'rollup-plugin-postcss'
import serve from 'rollup-plugin-serve'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'.sourcemap: true
  },
  plugins: [
    typescript(),
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'
    }),
    terser(),
    postcss(),
    serve({
      open: true.contentBase: 'dist'})].external: ['lodash']}Copy the code

7. Enable hot update

Now the local server has it, but every time you change the code, you have to reboot to take effect, which is inconvenient, so you need a hot update.

7.1 installation rollup – plugin – livereload

npm install rollup-plugin-livereload --save-dev
Copy the code

7.2 configuration rollup. Config. Js

import babel from 'rollup-plugin-babel'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-typescript'
import typescript from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import postcss from 'rollup-plugin-postcss'
import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload'

export default {
  input: './src/main'.output: {
    file: './dist/bundle.js'.format: 'cjs'.name: 'bundleName'.sourcemap: true
  },
  plugins: [
    typescript(),
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'
    }),
    terser(),
    postcss(),
    livereload(),
    serve({
      open: true.contentBase: 'dist'})].external: ['lodash']}Copy the code

7.3 Adding Script Statements

{
  "name": "rollupDemo"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "build": "rollup --config"."dev": "rollup --config -w"
  },
  "keywords": []."author": ""."license": "ISC"."devDependencies": {
    "@babel/core": "^ 7.13.16"."@babel/preset-env": "^ 7.13.15"."@rollup/plugin-commonjs": "^ 18.0.0"."@rollup/plugin-node-resolve": "^ 11.2.1." "."@rollup/plugin-typescript": "^ 8.2.1." "."lodash": "^ 4.17.21"."postcss": "^ 8.2.13"."rollup": "^ 2.45.2"."rollup-plugin-babel": "^ 4.4.0"."rollup-plugin-livereload": "^ 2.0.0." "."rollup-plugin-postcss": "^ 4.0.0"."rollup-plugin-serve": "^ 1.1.0." "."rollup-plugin-terser": "^ 7.0.2"."tslib": "^ 2.2.0." "."typescript": "^ 4.2.4"}}Copy the code

8. Distinguish between development and production environments

In the development environment we need sourcemap on, configure hot update and local service, in the production environment we need Sourcemap off, do not need hot update and local service, need code compression, etc., so we need to distinguish.

Rollup.config. js is divided into two rollup.config.dev.js and rollup.config.build.js, and then we write the configuration file according to the actual situation of our project.

9. Address of the related rollup plug-in

  • awesome
  • Github.com/rollup/plug…

conclusion

Rollup is a rollup plugin that can be used to configure rollup. There are many plug-ins that can be used to configure rollup. Please refer to the documentation for details.