1. An overview of the
Rollup is an ES Module-based packager, similar to WebPack, which can pack small modules scattered in a project into whole pieces of code. Rollup modules can run better in a browser or nodeJs environment without having to click on Rollup.
Rollup is very similar to WebPack in effect, and much smaller than WebPack. Webpack with plug-ins can do almost the vast majority of front-end engineering. Rollup is just a wrapper for the ES Module and has no additional functionality.
Webpack has developer-friendly HMR functionality that Rollup does not support. Rollup’s goal is not to compete with WebPack, but to provide an efficient ES Module wrapper that takes full advantage of the features of ES Module to build a relatively flat, high-performance library.
2. Use
Here is a simple example that uses ES Module to organize code modularization. The source code for the example consists of three files. Message.js exports an object as the default export.
export default {
hi: 'Hey Guys, I am yd~'
}
Copy the code
Two functions are exported from logger.js.
export const log = msg= > {
console.log(msg);
}
export const error = msg= > {
conole.log('------ ERROR ------')
console.log(msg);
}
Copy the code
Index.js imports these two modules and uses them.
import { log } from './logger';
import message from './message';
const msg = message.hi;
log(msg);
Copy the code
Install rollup to package the sample application.
yarn add rollup --dev
Copy the code
Rollup Provides the CLI program to run through YARN rollup. You can see that rollup automatically prints the help message without passing any arguments. The start of the help message indicates that a package entry file should be specified by the argument. The package entry is the index.js file under SRC.
yarn rollup ./src/index.js
Copy the code
You should also specify an output format for the code, using the –format argument, such as the format of iIFE self-executing functions.
yarn rollup ./src/index.js --format iife
Copy the code
You can also specify the output path of the file by using –file, such as bundle.js in the dist folder, so that the package results are exported to the dist file.
yarn rollup ./src/index.js --format iife --file dist/bundle.js
Copy the code
The rollup package results are astonishingly simple, basically the same as the handwritten code, and the output is almost free of any extra code compared to the massive bootstrap code in WebPack.
Rollup only concatenates the modules in the packaging process according to the dependency order of the modules. After careful inspection of the packaging result, it will be found that only the used parts are retained in the output result, and the unreferenced parts are not output. Rollup automatically turns on tree-shaking optimized output by default. The tree-shaking concept was first introduced in the rollup tool.
(function () {
'use strict';
const log = msg= > {
console.log(msg);
};
var message = {
hi: 'Hey Guys, I am yd~'
};
constmsg = message.hi; log(msg); } ());Copy the code
3. Configuration file
Rollup supports configuration files to configure parameters during the packaging process. You can create a rollup.config.js configuration file in the same directory of the project. This file runs in the Node environment, but rollup itself handles this configuration file in addition, so you can use ES Modules directly.
In this file you need to export a configuration object that specifies the path to the packaged entry file through the input property. Output specifies the configuration of the output. The output property requires an object in which you can use the file property to specify the file name of the output. The format attribute can be used to specify the output format.
export default {
input: 'src/index.js'.output: {
file: 'dist/bundle.js'.format: 'iife'}}Copy the code
The –config argument is required to indicate that the configuration file in the project is used. By default, the configuration file is not read.
yarn rollup --config rollup.config.js
Copy the code
4. Use plug-ins
Rollup itself is designed to merge ES modules if the project has higher-level requirements such as loading other types of resource files, importing CommonJS modules in code, or compiling new ECMAScript features. For these additional requirements, Rollup can also be extended using plug-ins, and plug-ins are the only extension method for Rollup, unlike WebPack, which divides the loader, plugin, and minimize extensions.
Try using a plugin that can import JSON files into your code. The plugin used here is called rollup-plugin-json, which you need to install first.
yarn add rollup-plugin-json --dev
Copy the code
After the installation is complete, open the rollup configuration file. Since the rollup configuration file can use ES Modules directly, import the plug-in with import mode. An export is a function that adds the result of the call to the plugins array of the configuration object.
import json from 'rollup-plugin-json';
export default {
input: 'src/index.js'.output: {
file: 'dist/bundle.js'.format: 'iife'
},
plugins: [
json()
]
}
Copy the code
Once the plug-in is configured, you can import the JSON file in your code via import.
import { log } from './logger';
import message from './message';
import { name, version } from '.. /package.json';
const msg = message.hi;
log(msg);
log(name);
log(version);
Copy the code
yarn rollup --config rollup.config.js
Copy the code
The bundle.js output will see that the name and version in json are packed normally, and the unused properties in JSON are tree-shaking removed.
(function () {
'use strict';
const log = msg= > {
console.log(msg);
};
var message = {
hi: 'Hey Guys, I am yd~'
};
var name = "rollup_p";
var version = "1.0.0";
constmsg = message.hi; log(msg); log(name); log(version); } ());Copy the code
5. Load the NPM module
By default, rollup can only load local file modules according to the file path. Third-party modules in node_modules cannot be directly imported by the module name like webpack. Rollup provides a rollup-plugin-node-resolve plugin to resolve this discrepancy. Use this plugin to import the corresponding module directly in code when using the module name.
yarn add rollup-plugin-node-resolve --dev
Copy the code
You need to import this module in the configuration file and then configure the plugins into the plugins array.
import json from 'rollup-plugin-json';
import resolve from 'rollup-plugin-node-resolve'
export default {
input: 'src/index.js'.output: {
file: 'dist/bundle.js'.format: 'iife'
},
plugins: [
json(),
resolve()
]
}
Copy the code
When this is done, you can import the third-party NPM module in node_modules directly. Import the loadash-es module, which is the ES Modules version of loadAsh.
import _ from 'loadash-es';
import { log } from './logger';
import message from './message';
import { name, version } from '.. /package.json';
const msg = message.hi;
log(msg);
log(name);
log(version);
log(_.camelCase('hello world'))
Copy the code
Here we use the loadsh ES Module version instead of the normal version because rollup can only handle the ES Module by default, and additional processing is required to use the normal version.
6. Load CommonJS module
Rollup-plugin-commonjs plug-in is provided on the official website for compatibility with CommonJS mode modules.
yarn add rollup-plugin-commonjs --dev
Copy the code
import json from 'rollup-plugin-json';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
export default {
input: 'src/index.js'.output: {
file: 'dist/bundle.js'.format: 'iife'
},
plugins: [
json(),
resolve()
]
}
Copy the code
To use the CommonJS module, add the commonJS module.module.js file under SRC.
module.exports = {
foo: 'bar'
}
Copy the code
The CommonJS export as a whole will be the default export.
import _ from 'loadash-es';
import { log } from './logger';
import message from './message';
import { name, version } from '.. /package.json';
import cjs from './cjs.module';
const msg = message.hi;
log(msg);
log(name);
log(version);
log(_.camelCase('hello world'));
log(cjs);
Copy the code
Commonjs is packaged into bundle.js.
7. Code splitting
Rollup’s latest release now supports code splitting. Modules can be loaded on demand using Dynamic Imports that conform to the ES Module standard. Rollup automatically handles code splitting, also known as subcontracting.
Use the dynamic import method to import the corresponding module of logger. The import method returns a Promise object. In the promise then method, you can retrieve the object after the module is imported.
// import { log } from './logger';
// import message from './message';
// const msg = message.hi;
// log(msg);
import('./logger').then(({ log }) = > {
log('code splitting');
});
Copy the code
yarn rollup --config
Copy the code
Using code split packaging requires format not to be iIFE. Since self-executing functions put all modules into the same function, there is no bootstrap code like WebPack, so there is no way to split the code.
To use code splitting you must use another standard such as AMD or CommonJS. Browser environments can only use AMD standards. Also because of the output of multiple files, the configuration of file cannot be used here, because file is the name of the file to perform a single file output.
If you need to output multiple files, you can use the dir parameter to set the output directory to dist.
export default {
input: 'src/index.js'.output: {
// file: 'dist/bundle.js',
// format: 'iife'
dir: 'dist'.format: 'amd'}},Copy the code
yarn rollup --config
Copy the code
Once the package is complete, you can see that the dist directory generates the bundle.js entry and dynamically imported bundles based on the dynamic import. All are using AMD standard output.
8. Multi-entry packing
Rollup supports multi-entry packaging, and parts common to different entries are automatically extracted into a single file as separate bundles. The instance has two entries, index and album, which share the fetch. Js and logger.js modules.
index.js
import fetchApi from './fetch';
import { log } from './logger';
fetchApi('/posts').then(data= > {
data.forEach(item= >{ log(item); })})Copy the code
album.js
import fetchApi from './fetch';
import { log } from './logger';
fetchApi('/photos? albumId=1').then(data= > {
data.forEach(item= >{ log(item); })})Copy the code
fetch.js
export default endpoint => {
return fetch('xxxxx').then(response= > response.json())
}
Copy the code
logger.js
export const log = msg= > {
console.log(msg);
}
export const error = msg= > {
conole.log('------ ERROR ------')
console.log(msg);
}
Copy the code
Configuring multi-entry packaging is very simple. You just change the input property to an array. You can also use the same object configuration as WebPack, but be aware that because of multi-entry packaging, the public modules are automatically extracted internally, which means code splitting is used internally. The iIFE output format cannot be used here, and you need to change the output format to AMD.
export default {
// input: ['src/index.js', 'src/album.js'],
input: {
foo: 'src/index.js'.bar: 'src/album.js'
},
output: {
dir: 'dist'.// format: 'iife',
format: 'amd'}},Copy the code
After packaging, there will be three js files in dist directory, which are the packaging results of two different packaging entrances and the public module extracted from the common.
In addition, it should be noted that for AMD this output format js files, can not be directly referenced to the page, must be implemented through the AMD standard library to load.
Manually create an HTML file in the dist directory. The bundled bundle.js is then used in HTML, and the requirejs library is used to load the AMD standard output bundle.
Require can specify the entry module path of modules loaded by require with the data-main argument.
<body>
<script src="... require.js" data-main="foo.js"></script>
</body>
Copy the code
9. Selection principle
Rollup does have its advantages. First of all, its output is flatter, which naturally results in higher execution efficiency. The second is that it automatically removes unreferenced code, that is, tree-shaking. Another is that his package results are basically the same as the hand-written code, which means that the package results are normally readable by developers.
However, its disadvantages are also obvious. First of all, loading some third-party modules that are not ES Modules will be complicated and require a lot of plug-in configuration. Because these modules are eventually packaged into a function, there is no way to achieve the development experience of module hot replacement like HMR as webPack does. Another is that in the browser environment, code splitting must use an AMD library like requireJS because it must use an OUTPUT format like AMD for code splitting.
Combined with these characteristics, if you are developing an application, you will be faced with the need to introduce a large number of third-party modules. At the same time, features like HMR are needed to enhance the development experience. And once the application gets big, it has to be subcontracted. Each of these requirements rollups is somewhat lacking in fulfillment.
If you are developing a JS framework or class library, the advantages are particularly necessary and the disadvantages are largely negligible. Taking loading third-party modules as an example, it is rare to rely on third-party modules in your code when developing a class library. So frameworks like React or Vue use rollup as a module packer rather than Webpack.
So far, most people in the open source community expect the two tools to exist and evolve together, and to support and learn from each other. The reason is simply that you want more specialized tools to do more specialized things.
To summarize, Webpack is big and Rollup is small and beautiful.
In choosing between the two, the basic rule is to use Webpack if you are opening applications and Rollup if you are developing libraries or frameworks.
Of course, Rollup can also build most applications, and Webpack can also build libraries or frameworks. It’s just that relatively speaking, it’s specialized.
Another point is that with the development of Webpack in recent years, many of the advantages of Rollup have been almost wiped out. For example, the flattened output of Rollup can be done in Webpack using the concatenateModules plugin. Similar output can be achieved.