Rollup

The next generation of packaging tools, this is how Rollup sees itself. In today’s front-end world, there is no shortage of build tools, and every front-end engineer has used or heard of WebPack. You can see that build tools for frameworks like React and Vue use rollup. So why do these frameworks choose rollup? What are its characteristics? How do we choose build tools for different scenarios? This article will show you one by one.

Tree Shaking

Tree shaking is a very important rollup feature. When building code, in ES6 modularity, your code is analyzed statically and only the code that you use is packaged. This has the advantage of reducing the size of the code.

You can see that its implementation relies on static analysis, so why use ES6 Modules? Let’s review a few features of ES6 Modules:

  • importCan only be string constants
  • Import binding is immutable, similarlyconst
  • Can only appear as a statement at the top level of a module, not infunctionInside orifInside the block-level scope
  • Import hoisted, regardlessimportWhere does the statement appear when the module is initializedimportAll must have been imported.

This makes ES6 Modules less flexible, but allows all dependencies to be fixed and code to be statically analyzed. There is no need to rely on the runtime to determine dependencies. One example: maths.js

// maths.js
export function square ( x ) {
	return x * x;
}
export function cube ( x ) {
	return x * x * x;
}
Copy the code

main.js

import { cube } from './maths.js';
console.log( cube( 5));Copy the code

Run the following command

$ rollup main.js --o bundle.js --f iife
Copy the code

Output bundles. Js

(function () {
'use strict';

// maths.js

function cube(x) {
    return x * x * x;
}

console.log(cube(5)); } ());Copy the code

As you can see, the square method in maths.js is not used and is not packaged into the build result. At build time, a parameter f is added with the value of the iIFE option, and the organization of the post-build code is wrapped in a function that executes immediately.

Output format after code is built

Rollup supports the following output formats: rollup (iIFE) rollup (iIFE) rollup (iIFE) rollup (iIFE)

  • amd – AMD
  • cjs -CommonJS
  • es – ES6 modules
  • umd – UMD
  • system – SystemJS loader

When building code, you can choose different output formats depending on the environment in which your code is running. CJS is fine if your code is running in Node, iIFE is fine if your code is running in a browser, and UMD is fine if both. In webpack compile & Build, there are actually three types of code that refer to webPack build output.

  • Your business logic code
  • Runtime – Bootstrap for code execution
  • Manifest – A record of module dependencies

If we execute the following command on main.js after build

webpack main.js dist.js
Copy the code

Output dist. Js

/ * * * * * * / (function(modules) { // webpackBootstrap
/ * * * * * * / 	// The module cache
/ * * * * * * / 	var installedModules = {};
/ * * * * * * /
/ * * * * * * / 	// The require function
/ * * * * * * / 	function __webpack_require__(moduleId) {
/ * * * * * * /
/ * * * * * * / 		// Check if module is in cache
/ * * * * * * / 		if(installedModules[moduleId]) {
/ * * * * * * / 			return installedModules[moduleId].exports;
/ * * * * * * / 		}
/ * * * * * * / 		// Create a new module (and put it into the cache)
/ * * * * * * / 		var module = installedModules[moduleId] = {
/ * * * * * * / 			i: moduleId,
/ * * * * * * / 			l: false./ * * * * * * / 			exports: {}
/ * * * * * * / 		};
/ * * * * * * /
/ * * * * * * / 		// Execute the module function
/ * * * * * * / 		modules[moduleId].call(module.exports, module.module.exports, __webpack_require__);
/ * * * * * * /
/ * * * * * * / 		// Flag the module as loaded
/ * * * * * * / 		module.l = true;
/ * * * * * * /
/ * * * * * * / 		// Return the exports of the module
/ * * * * * * / 		return module.exports;
/ * * * * * * / 	}
/ * * * * * * /
/ * * * * * * /
/ * * * * * * / 	// expose the modules object (__webpack_modules__)
/ * * * * * * / 	__webpack_require__.m = modules;
/ * * * * * * /
/ * * * * * * / 	// expose the module cache
/ * * * * * * / 	__webpack_require__.c = installedModules;
/ * * * * * * /
/ * * * * * * / 	// define getter function for harmony exports
/ * * * * * * / 	__webpack_require__.d = function(exports, name, getter) {
/ * * * * * * / 		if(! __webpack_require__.o(exports, name)) {/ * * * * * * / 			Object.defineProperty(exports, name, {
/ * * * * * * / 				configurable: false./ * * * * * * / 				enumerable: true./ * * * * * * / 				get: getter
/ * * * * * * / 			});
/ * * * * * * / 		}
/ * * * * * * / 	};
/ * * * * * * /
/ * * * * * * / 	// getDefaultExport function for compatibility with non-harmony modules
/ * * * * * * / 	__webpack_require__.n = function(module) {
/ * * * * * * / 		var getter = module && module.__esModule ?
/ * * * * * * / 			function getDefault() { return module['default']; } :
/ * * * * * * / 			function getModuleExports() { return module; };
/ * * * * * * / 		__webpack_require__.d(getter, 'a', getter);
/ * * * * * * / 		return getter;
/ * * * * * * / 	};
/ * * * * * * /
/ * * * * * * / 	// Object.prototype.hasOwnProperty.call
/ * * * * * * / 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/ * * * * * * /
/ * * * * * * / 	// __webpack_public_path__
/ * * * * * * / 	__webpack_require__.p = "";
/ * * * * * * /
/ * * * * * * / 	// Load entry module and return exports
/ * * * * * * / 	return __webpack_require__(__webpack_require__.s = 0);
/ * * * * * * / })
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * * * * * * / ([
/* 0 */
/ * * * / (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__maths_js__ = __webpack_require__(1);

console.log(Object(__WEBPACK_IMPORTED_MODULE_0__maths_js__["a" /* cube */]) (5));

/ * * * / }),
/ * 1 * /
/ * * * / (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export square */
/* harmony export (immutable) */ __webpack_exports__["a"] = cube;
// maths.js
function square(x) {
    return x * x;
}
function cube(x) {
    return x * x * x;
}

/ * * * / })
/ * * * * * * / ]);
Copy the code
  • You can see the business logic code, Runtime and Manifest in the build result
  • Log dependencies in Manifest, through__webpack_require__loading
  • The build results contain unused onessquare
  • Build volume is significantly greater than in rollupiifeLarge format
  • Rollup when the code executesiifeOutput format, faster code execution, Webpack built out of the dependency search, and each module through a function wrapped form, when executing, it forms a closure, occupying memory, of course, can be used in Webpack 3ConcatenationPluginThe plug-in optimizes this output format and packages it into a dependency

The cost-of-small-modules performance has done a good evaluation, you can understand.

There is no silver bullet

Code-splitting was implemented in order to solve the construction of static files such as CSS and pictures and make codes load on demand. In our daily online business code development, more or less static resources need to be packed, so rollup was not suitable. So we can see that we can choose rollup for building some libs and WebPack for building some applications.


IVWEB Technology Weekly shocked online, pay attention to the public number: IVWEB community, weekly timing push quality articles.

  • Collection of weekly articles: weekly
  • Team open source project: Feflow