Rollup package

1.1 overview of Rollup

Rollup is an ES Modules packager that can pack scattered small Modules into a whole block of code, so that Modules can be better run in the flowmeter environment or node environment. Rollup is very similar to WebPack. Compared to WebPack -> Rollup is much smaller because WebPack can do most of the front-end engineering in development with plug-ins -> Rollup is just an ESM The packer does not have any additional features -> Ex: Webpack has developer-friendly HMR(module hot replacement) that is not fully supported in Rollup => Rollup was created not to compete fully with tools like Webpack but to provide an efficient ESM packer that takes full advantage of ESM The features of the construction of a relatively flat structure of the performance of the outstanding class library as for its other features and advantages need to get started to understand;

1.2. Rollup

Project directory structure:

//messages.js
export default {
  hi: 'Hey Andy, I am Lcy~'
}
Copy the code
//logger.js
export const log = msg= > {
  console.log('------ INFO ------')
  console.log(msg)
  console.log('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --')}export const error = msg= > {
  console.log('------ ERROR ------')
  console.log(msg)
  console.log('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --')}Copy the code
//index.js
// Import module members
import { log } from './logger'
import message from './message'
// Use module members
const msg = message.hi
log(msg)
Copy the code

Install the Rollup module from the command line

cnpm i rollup -D
Copy the code

After installation, the Rollup module provides a CLI program at node_modules/. Bin that developers can use to package

Run the Rollup package project by command

yarn rollup 
Copy the code

Without passing any arguments, the console will print help information about Rollup -> Help information about the correct Usage of Rollup -> Usage: Rollup [options] -> The package entry file should be specified by parameters

yarn rollup ./src/index.js
Copy the code

Console output error:

Output format: In what format do you want to convert ESM code to output command line arguments? –format specifies the output format — > In this case, the most browser-compatible format: IIFE (self-calling function format)

yarn rollup ./src/index.js --format iife
Copy the code

At this point the package result is output in the console panel -> You can also specify the package output file path with the –file parameter -> so that the package result is output to the file

yarn rollup ./src/index.js --format iife --file dist/bundle.js
Copy the code

Once packaged: the file is exported to dist/bundle.js

=> View the packing result: The packing result is very simple and basically the same as the handwritten code -> in contrast to the large amount of bootstrap code and module functions in the Webpack packing result, there is almost no extra code in the output here, just splicing the various modules in the packing process together in the order of module dependency -> in the packing result -> This is because Rollup automatically turns on Tree shaking to optimize the output. -> Tree shaking was first introduced in the Rollup tool;

1.3 Rollup configuration file

Rollup also supports configuration of various parameters in the packaging process as a configuration file

Create rollup.config.js in the root directory

This file also runs in the Node environment but Rollup itself will process the configuration file extra -> ESM can be used directly here

//rollup.config.js// Export default {input: './ SRC /index.js', // Specify the package entry file output: {// Specify the output configuration: File: './dist/bundle.js', // specify the output file name format: 'iife' // specify the output file format}}
Copy the code

Run the Rollup package project

Note here: the –config parameter is required to indicate that the configuration file used in the project is not read by default. The –config parameter must be used

Ex: yarn rollup –config rollup.production.js -> This allows you to use different configuration files for development and production environments;

yarn rollup --config
Copy the code

The result of the package is output to dist/bundle.js

1.4. Rollup uses plug-ins

Rollup itself is simply a consolidation and packaging of ESM modules if the project has more advanced requirements If you want to load other types of resource files or import CommonJs modules in your code or Rollup helps us compile new ECMAScript features -> these additional requirements Rollup also supports extension implementation using plug-ins and plug-ins are Rollup The only extension method is not like Webpack, which divides the Loader Plugin and Minimizer.

Rollup: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json: rollup-plugin-json

Install a rollup plugin – json

cnpm i rollup-plugin-json -D
Copy the code

Edit the rollup. Config. Js

Since rollup.config.js can use ESM to import plug-in modules directly here using import

import rollupPluginJson from 'rollup-plugon-json'// The plugins module exports a plugins function by default. We can add the result of the plugins call to the plugins array export default {...... , plugins: [ rollupPluginJson() ]}
Copy the code

After the configuration is complete, you can import the JSON file in your code by means of import

Edit index.js to try to import package.json file with import

//index.js// Import the module member...... Import {name, version} from '.. import {name, version} from '.. /package.json'// use the module member...... ,log(name)log(version)
Copy the code

Run Rollup packaging

yarn rollup --config
Copy the code

See the output: Name and version in package.json in bundle.js are packaged while other unreferenced properties are not

This is how plug-ins are used in Rollup

1.5. Rollup Loads the NPM module

By default, Rollup can only load local modules by file path. Third-party modules in node_modules cannot be imported by module name like Webpack Rollup-plugin-node-resolve plugin- > Use this plugin to import the corresponding module directly in your code with the module name

Install rollup-plugin-node-resolve from the command line

cnpm i rollup-plugin-node-resolve -D
Copy the code

Edit the configuration file rollup.config.js

. .import resolve from 'rollup-plugin-node-resolve'export default{... .plugins: [  	......,  	resolve()  ]}
Copy the code

After the configuration is complete in the code can directly use the module name to import the corresponding module

Editing the js

// Import module member...... Import _ form 'lodash-es'// use the module member...... log(_.camelCase('hello world'))
Copy the code

Rollup (yarn Rollup –config) -> Lodash-es can be packaged into bundle.js -> Use the Lodash ESM version instead of Lodash The reason for the normal version is that Rollup can only handle ESM modules by default and requires additional processing to use the normal version

1.6. Rollup loads COmmonJs module

Rollup is designed to deal only with ESM module packaging. Importing CommonJs modules into your code is not supported by default -> But there are still a lot of NPM modules that use CommonJs to export members, so a plugin is provided for compatibility with these modules rollup-plugin-commonjs

Install rollup-plugin-commonjs from the command line

cnpm i rollup-plugin-commonjs -D
Copy the code

Edit the configuration file rollup.config.js

. import commonJsfrom 'rollup-plugin-commonjs'export default{... .plugins: [  	......,  	commonJs()  ]}
Copy the code

Once configured, you can import the commonJs module directly into your code

Add the commonJs sample file: cjS-module.js in the SRC directory

// cjs-module.jsmodule.exports = { foo: 'bar'}
Copy the code

Edit index.js using the cjS-module.js module

// Import module member...... Import cJs from './cjs-module.js'// use the module member...... log(cJs)
Copy the code

Run rollup packaging by command

yarn rollup --config
Copy the code

The commonJs module can then be packaged into bundle.js -> see bundle.js -> cjS-module. js and the default export appears as an object in bundle.js

1.7. Rollup code split

Code splitting is already supported in the latest version of Rollup using the ESM standard dynamic import to load modules on demand and Rollup automatically handles code splitting (subcontract)

Editing the js

// import {log} from './logger'// import message from './messages'// use module member // const MSG = Message.hi // log(MSG) import('./logger'). Then (({log}) => {log('code splitting ~')})
Copy the code

Try running Rollup packaging

Console output error:

=> Error message: Rollup uses split code package and requires output format not IIFE -> Cause: there is no way to split code because there is no bootstrap code –

=> If you want to use code splitting, do not use AMD or other standards such as CommonJs -> only AMD standards can be used in the browser environment -> so you need to use AMD format to output the packaged results here

Rollup packaging is performed by modifying the output format with the –format command line argument

yarn Rollup --config --format amd
Copy the code

Console output error:

=> Error message: Cannot use output.file when using split code packaging -> Because multiple files need to be output. File specifies the output file name of a single file. -> If multiple parameters need to be output, use dir

Modify the rollup.config.js configuration file

/* export default { input: './src/index.js', output: { file: 'dist/bundle.js', format: 'iife' }} */export default {  input: './src/index.js'.output: {    dir: 'dist'.format: 'amd'  }}
Copy the code

Run Rollup packaging again from the command line (yarn Rollup –config)

Once the package is complete -> look in the dist directory -> Generate an incoming bundle and dynamically imported bundle from the dynamic import -> they are all AMD standard output => This is how code splitting is implemented in Rollup -> Implemented using dynamic imports;

1.8 Rollup multi-entry packing

Rollup also supports multi-entry packaging and the common parts of different entries are automatically extracted into a single file as separate bundles

How do we configure it? -> Project Directory:

//index.jsimport fetchApi from './fetch'import { log } from './logger'ferchApi('/posts').then(data => { data.forEach(item => { log(item) })})
Copy the code
// album.jsimport fetchApi from './fetch'import { log } from './logger'fetchApi('/photos? albumId=1').then(data => { data.forEach(item => { log(item) })})
Copy the code
// fetch.jsexport default endpoint => { return fetch(`https://jsonplaceholder.typicode.com${endpoint}`) .then(response => response.json())}
Copy the code
// logger.jsexport const log = msg => { console.log('------ INFO ------') console.log(msg) console.log('------------------')}export const error = msg => { console.error('------ ERROR ------') console.error(msg) console.error('-------------------')}
Copy the code

Configure a rollup. Config. Js

Rollup is very simple -> set the value of the input property to an array or use key-value pairs of objects -> note that multientry packaging will extract common resources, that is, will use code split internally -> output format cannot use IIFE -> Change the output format to AMD

// rollup.config.jsexport default { // input: ['src/index.js', 'src/album.js'] input: { foo: 'src/index.js', bar: 'src/album.js' }, output: { dir: 'dist', format: 'amd' }}
Copy the code

Run Rollup packaging from the command line

yarn rollup --config
Copy the code

Once the package is complete: there will be three more JS files in the dist directory -> two more unimportable package results and the public module JS extracted from the common resources

Note that output files in this format cannot be directly referenced to the page and must be loaded through a library that implements the AMD standard

Manually create an index. HTML file in the dist directory and edit the HTML file

<! DOCTYPEhtml><html lang="zh-CN">  <head>    <meta charset="UTF_8">    <meta name="Viewport" content="Width = device - width, initial - scale = 1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>Document</title>  </head>  <body>    <! -- Try using bundled bundle.js in the file -->    <! -- <script src="foo.js"></script> -->    <! AMD's standard output bundle can specify the entry file path of the module required by the data-main parameter -->    <script src="https://unpkg.com/[email protected]/require.js" data-main="foo.js"></script>  </body></html>
Copy the code

Run the dist directory with serve

Once it’s up and running: Open your browser -> View Developer Tools -> Network and Console and boo.js is loaded and working properly

1.9. Selection principle of Rollup

Rollup does have its advantages through the above exploration and experimentation:

  • The more flat the output -> the more efficient the execution
  • Automatically removes unreferenced code
  • The package results are basically the same as handwritten -> still fully readable

But his certainty was also clear:

  • Loading non-ESM third-party modules is complicated -> requires configuring a bunch of plug-ins
  • Modules end up packaged into a function that does not implement HMR
  • In the browser environment, code splitting is dependent on AMD libraries -> required to use libraries like require -> because its code splitting is required to output AMD formats

To sum up the above characteristics: if we are developing applications, we must face a large number of requirements such as the introduction of third-party modules, and also need functions such as HMR to improve the development efficiency -> And the application volume is large and involves subcontracting -> these requirements are insufficient to meet; These advantages of Rollup are necessary if we are developing a framework or library and the disadvantages can be ignored

So most well-known frameworks/libraries use Rollup as a module packer, not Webpack

But for now most people in the open source community want the two tools to exist and grow together and to support and learn from each other -> the reason is simple: even if you want more specialized tools to do more specialized things;

=> Summary: Webpack large and full Rollup small and beautiful -> In the choice of both: Application development uses Webpack library/framework development uses Rollup -> this is not an absolute standard, just a matter of experience -> because Rollup can also build most applications and Webpack can also build libraries/frameworks, but in a relatively specialized sense -> With the development of Webpack over the years many of the advantages of Rollup have been almost wiped out Ex: flat outputs can be used in Webpack and similar outputs can be achieved;

A parcel has been installed

Parcel is a completely zero-configuration packaging tool that provides an almost dumb-ass packaging experience – you can use it to build front-end applications with just a few simple commands you know it provides

Create a new empty project -> initialize the project’s package.json from the command line

yarn init --yes / cnpm init --yes
Copy the code

Install the module corresponding to the Parcel using the command line

Note here: The NPM module for a parcel is called parcel-bundler

cnpm i parcel-bundler -D
Copy the code

After the installation, the parcel module provides a command-line interface (CLI) program in the node_modules/. Bin directory that you can use to package applications

Create SRC /index.html in the root directory of the project

The index. HTML file that will be used as a parcel package entry -> While Parcel and Webpack can use any file as a parcel entry, Parcel recommends using an HTML file as a parcel entry -> The reasons are as follows: Because the HTML file is the entry point for the application to run in the browser

=> You can write it as usual in the HTML entry file or reference some resource files here -> the reference resources here will eventually be packaged by parcel and eventually exported to the output directory

Editing the HTML

<! DOCTYPEhtml><html lang="zh-CN">  <head>    <meta charset="UTF_8">    <meta name="Viewport" content="Width = device - width, initial - scale = 1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>Parcel Tutorials</title>  </head>  <body>    <script src="main.js"></script>  </body></html>
Copy the code

Create main.js and foo.js in the SRC directory

// foo.jsexport default { bar: () => { console.log('hello parcel~') }}
Copy the code
//mian.jsimport foo from './foo'foo.bar()
Copy the code

Parcel also supports packaging of ESM modules

Execute parcel packaging using the command line

Parcel packaging requires passing in the path to the package entry file

yarn parcel src/index.html
Copy the code

Execute the command -> Parcel to find the index. HTML file based on the parameters passed in -> find main.js based on the imported main.js file -> and follow the import statement to find the foo module to complete the package

After executing the command: Parcel not only packages the application but also starts the development server -> this development server is the same as devServer in Webpack -> open the developer tool in the browser according to the address provided in the terminal -> Open the developer tool to use the automatic refresh function

-> Modify the source code -> Parcel repackage and refresh the browser -> Experience Parcel if you need module hot replacement as well

Edit main.js to implement HMR

. if (module.hot) {  // There is a module.hot object -> Parcel that supports the HMR API: HMR logic module.hot.accept(() => {// Accept is not the same as Webpack API: The API provided by Webpack supports accepting two arguments to handle logical processing after a given module is updated -> Accept of a Parcel only accepts one argument (the callback function): Log ('HMR')})} Console. log('HMR')}
Copy the code

At this point, modifying foo.js -> code is automatically hot-replaced and executed

The hot replacement Parcel also supports a very friendly feature: automatically installing dependencies

Edit the main js

. import $from 'jquery'.Copy the code

Due to auto-install dependencies that allow you to import some modules directly at development time -> Once you save the file, Parcel automatically installs the new module you just imported -> manual operations are largely avoided

In addition, Parcel also supports loading other types of resource modules -> And loading any module in a Parcel is also zero-configuration compared to other module packaging tools

Add the style. CSS file in the SRC directory and edit it

body{  background-color: #2F4056; }Copy the code

Go back to main.js and import style.css

. import'./style.css'.Copy the code

The style takes effect automatically after you save the file

You can also add images to the project

PNG -> edit main.js in the SRC directory

. imprt bodybgfrom './bodybg.png'. $(document.body).append(`<img src="${bodybg}"/ > `)...Copy the code

The image is automatically displayed in the browser -> the whole process does not stop to do other things

In short: Does Parcel want to give developers the experience of just doing what you want and letting the tool take care of the extra stuff

If a Parcel package uses dynamic import, the code will be split automatically

Edit main.js to implement dynamic import

// import $ form 'jquery'...... / / using dynamic import import jqueryimport (' jquery). Then ($= > {$(document. The body). Append (` < img SRC = "${bodybg}" / > `)}) / / $(document.body).append(``)......
Copy the code

Save and go back to the browser -> Network in developer tools to find the bundle.js request for the newly split JQury

These are some of the most commonly used features of a Parcel. There is little difficulty in using a Parcel except that the Parcel package command is executed all the way through and everything else is done automatically within the Parcel

End the Parcel command -> See how Parcel is packaged in production mode again

Parcel in production mode: You need to run the build command provided by the Parcel CLI command and the package entry path

yarn parcel build src/index.html
Copy the code

A packaged Parcel can be built much faster than Webpack for projects of the same size -> because multiple processes work simultaneously inside a Parcel to maximize the performance of a multi-core CPU -> Webpack can also use Happypack A plugin to implement multithreaded packaging

=> Look at the packaged code: all output files are compressed and the style code is extracted separately into a single file

=> Overall feel Parcel is very simple and comfortable to use

=> The first version of Parcel was released in 2017 because: But Webpack was too cumbersome to use and the official documentation wasn’t very clear -> So Parcel got a lot of buzz when it launched. Its core features are: Literally zero configuration is no intrusion into the project -> and the whole process has an auto-install dependency experience that allows our development process to focus more on coding -> One more thing: Parcels build faster

The advantages of Parcel are obvious, but in practice most projects still use Webpack -> reasons:

  • Webpack has a better ecology -> extensions are richer -> problems are easy to solve
  • Over the past two years Webpack has become more and more user-friendly -> developers have become more and more familiar with using it