Why learn rollup.js
Rollup. js is the ES module wrapper for Javascript, and many well-known frameworks or libraries such as Vue and React are packaged with rollup.js. Unlike Webpack’s orientation towards application packaging, rollup.js is more focused on Javascript library packaging (although rollup.js can also provide resource packaging, which is clearly not its strong suit). Rollup.js is a must for learning the source code of frameworks like Vue and React or writing our own Javascript libraries.
How rollup.js works
Rollup.js can package our own Javascript code (with plugins that support more languages like Tyepscript) with third-party modules into a file, which can be a Library or an App. Various plug-ins can be applied during the packaging process to achieve specific functionality. The following diagram illustrates how rollup.js works:
Install a rollup. Js
Rollup. js installation depends on nodejs. In the previous notes, I detailed how to manage nodeJS versions with NVM
Rollup.js is installed globally
First install rollup globally:
npm i rollup -g
Copy the code
Rollup.js packages the instance
After the installation is successful, we try a simple example using rollup to create a SRC directory:
mkdir src
Copy the code
Create a.js under SRC directory:
vim src/a.js
Copy the code
This module is very simple and exposes only one variable, a:
const a = 1
export default a
Copy the code
Create main.js from SRC:
vim src/main.js
Copy the code
This module will introduce module A and expose a function:
import a from './a.js'
export default function() {
console.log(a)
}
Copy the code
With the rollup directive, we can quickly preview the packaged source code, much like Babel:
$ rollup src/main.js -f es
src/main.js stdout...
const a = 1;
function main() {
console.log(a);
}
export default main;
created stdout in 26ms
Copy the code
Note that rollup must have a -f parameter, otherwise an error will be reported:
$ rollup src/main.js src/main.js stdout... [!] Error: You must specify output.format,which can be one of 'amd'.'cjs'.'system'.'esm'.'iife' or 'umd'
https://rollupjs.org/guide/en#output-format-f-format
Copy the code
The rollup error notification is great for locating errors and fixing problems. From the error above, we know that the value of -f can be any of ‘AMD’, ‘CJS’, ‘system’, ‘ESM’ (‘es’ also works), ‘iife’, or ‘umD’. The -f argument is short for –format, which indicates the format of the generated code, AMD indicates the AMD standard, CJS is the CommonJS standard, and ESM (or ES) is the ES module standard. We then output this code to a file:
$ rollup src/main.js -f es -o dist/bundle.js
src/main.js dist/bundle.js...
created dist/bundle.js in 29ms
Copy the code
The -o parameter specifies the output path. Here we output the packaged file to bundle.js in the dist directory. The contents of the file are exactly the same as what we previewed earlier. Let’s print CommonJS code again:
$ rollup src/main.js --format cjs --output.file dist/bundle-cjs.js
src/main.js dist/bundle-cjs.js...
created dist/bundle-cjs.js in 27ms
Copy the code
–output.file is the full name of -o. They are equivalent. After output, we have a bundle-cjs.js file in the dist directory.
'use strict';
const a = 1;
function main() {
console.log(a);
}
module.exports = main;
Copy the code
As you can see, the code is written in CommonJS standard and fuses a.js and main.js files.
Verify the rollup.js package results
After successful packaging, we try to run the dist/bundle-cjs.js code:
$ node
> const m = require('./dist/bundle-cjs.js')
> m()
1
Copy the code
Dist /bundle.js is not supported by the ES standard.
$ node
> require('./dist/bundle.js')()
/Users/sam/Desktop/rollup-test/dist/bundle.js:7
export default main;
^^^^^^
SyntaxError: Unexpected token export
Copy the code
Babel provides us with a tool: Babel-node, which converts ES code to CommonJS format at runtime, makes it possible to run ES code. @babel/cli contains Babel, and both tools rely on @babel/core, so it is recommended to install both:
npm i @babel/core @babel/node @babel/cli -g
Copy the code
Note that Babel 7 has changed the name of the NPM package. The previous versions of babel-core and babel-cli have been deprecated.
npm uninstall babel-cli babel-core -g
Copy the code
Then go to the root directory of the code and initialize the project:
npm init
Copy the code
After press Enter, create a configuration file for Babel in the code root directory. Babelrc and write the following configuration
{
"presets": ["@babel/preset-env"]}Copy the code
Install Babel dependencies after configuring Babel:
npm i -D @babel/core @babel/preset-env
Copy the code
Try compiling code with Babel:
$ babel dist/bundle.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var a = 1;
function main() {
console.log(a);
}
var _default = main;
exports.default = _default;
Copy the code
You can see the ES module code compiled into CommonJS format and run the code through babel-Node:
$ babel-node
> require('./dist/bundle.js')
{ default: [Function: main] }
> require('./dist/bundle.js').default()
1
Copy the code
Note that Babel considers export default function() to be a function named default. If you want to change the function name, you can modify main.js:
import a from './a.js'
export function test() {
console.log(a)
}
Copy the code
Rewrite packaged and run via babel-node:
$ rollup -f es --file dist/bundle.js src/main.js
src/main.js dist/bundle.js...
created dist/bundle.js in 26ms
$ babel-node
> require('./dist/bundle.js').test()
1
Copy the code
Note that –file is priced at -o and –output.file. With the above example, we completed the rollup package and verified the package result. Most of the time we don’t do this because using the command line directly is one-dimensional and plug-ins are not available, so we need to use configuration files to do this.
Rollup.js configuration file
First create the rollup.config.js file in the code root:
touch rollup.config.js
Copy the code
Write the following configuration:
export default {
input: './src/main.js'.output: [{
file: './dist/index-cjs.js'.format: 'cjs'.banner: '// welcome to imooc.com'.footer: '// powered by sam'
}, {
file: './dist/index-es.js'.format: 'es'.banner: '// welcome to imooc.com'.footer: '// powered by sam'}}]Copy the code
The rollup configuration file is very easy to understand, and there are a few things to note:
- Rollup configuration files need to be written in ES module standard
- Input indicates the path of the entry file (the old version is Entry, which has been abandoned)
- Output represents the contents of an output file. It allows an object or an array to be passed in. When an array is passed in, multiple files in turn are output, which contains the following contents:
- Output. file: path to the output file (dest in the older version is deprecated)
- Format: indicates the format of the output file
- Output. banner: the content added to the file header
- Output. footer: The content added to the end of the file
Rollup.js automatically looks for a configuration file named rollup.config.js, which is packaged with the rollup -c directive:
$ rollup -c
./src/main.js ./dist/index-cjs.js, ./dist/index-es.js...
created ./dist/index-cjs.js, ./dist/index-es.js in 13ms
Copy the code
Dist /index-es.js
// welcome to imooc.com
const a = 1;
function test() {
console.log(a);
}
export { test };
// powered by sam
Copy the code
The content of the code is identical to that generated on the command line, but custom comment information is added to the header and end. Next we change the name of the configuration file and package it by specifying the configuration file with the -c argument:
$ mv rollup.config.js rollup.config.dev.js
$ rollup -c rollup.config.dev.js
./src/main.js ./dist/index-cjs.js, ./dist/index-es.js...
created ./dist/index-cjs.js, ./dist/index-es.js in 13ms
Copy the code
A rollup. Js API package
Write the rollup.js configuration
In many cases, the packaging method of command line and configuration file cannot meet the requirements, and we need more personalized packaging method. In this case, we can consider packaging through the API of rollup.js, create rollup-input-options.js, which is the input configuration, and package a module separately. Improved reusability and scalability:
touch rollup-input-options.js
Copy the code
Add the following to the input configuration file. Note that the file must be in CommonJS format because nodeJS is used for execution:
module.exports = {
input: './src/main.js'
}
Copy the code
Add another output configuration file:
touch rollup-output-options.js
Copy the code
In the output configuration file, we still use an array to implement the output of multiple file formats. Note that the UMD format must specify the name of the module, which is implemented through the name attribute:
module.exports = [{
file: './dist/index-cjs.js'.format: 'cjs'.banner: '// welcome to imooc.com'.footer: '// powered by sam'
}, {
file: './dist/index-es.js'.format: 'es'.banner: '// welcome to imooc.com'.footer: '// powered by sam'}, {file: './dist/index-amd.js'.format: 'amd'.banner: '// welcome to imooc.com'.footer: '// powered by sam'}, {file: './dist/index-umd.js'.format: 'umd'.name: 'sam-umd'.// Specify the file name
banner: '// welcome to imooc.com'.footer: '// powered by sam',}]Copy the code
Write the rollup.js build code
Next we will install the rollup library in the current project:
npm i -D rollup
Copy the code
Create a rollup-build file that calls the ROLLup API:
touch rollup-build.js
Copy the code
Rollup-build: rollup-build:
const rollup = require('rollup')
const inputOptions = require('./rollup-input-options')
const outputOptions = require('./rollup-output-options')
async function rollupBuild(input, output) {
const bundle = await rollup.rollup(input) // Package according to the input configuration
console.log('generating:${output.file}`)
await bundle.write(output) // Configure the output file according to output
console.log(`${output.file}Build successful! `)} (async function () {
for (let i = 0; i < outputOptions.length; i++) {
await rollupBuild(inputOptions, outputOptions[i])
}
})()
Copy the code
At the heart of the code are two things:
- through
rollup.rollup(input)
Get the package object - through
bundle.write(output)
Output package file
Here we can also synchronize operations with async and await, because bundle.write(output) is asynchronous and will return a Promise object, we can use async mechanism to implement packaging in configuration order. Execute rollup-build file:
$node rollup-build.js:./dist/index-cjs.js./dist/index-cjs.js. Dist /index-es. Js./dist/index-es. Js. /dist/index-amd.js /dist/index-amd.js generated successfully! /dist/index-umd.js:./dist/index-umd.jsCopy the code
Dist /index-umd.js
(function (global, factory) {
typeof exports === 'object' && typeof module! = ='undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global['sam-umd'] = {}))); } (this, (function (exports) {
// ...
}
Copy the code
You can see in the index-umd.js file that the sam-umd attribute was added to the global variable, which is why we needed to add the name attribute to the UMD configuration earlier.
conclusion
This article introduced you to three ways to package Rollup.js: command line, configuration file, and API. In the next tutorial, I will continue to introduce you to more features of Rollup.js, such as tree-shaking, watch, and more.