Rollup is a JavaScript module packer. Its function is the same as that of webpack, which is to compile small pieces of code into large pieces of complex code, such as library or application. When developing applications at ordinary times, we basically choose to use webpack. In contrast, rollup JS is more used for library packaging. We are familiar with vue, react, vuex, vue router, etc. are packaged with rollup.
Installation and use of rollup
First, install:
npm i rollup -g # Global installation npm i rollup -D # Project local installation Copy code
Package a js file
Create a new project as follows, install rollup, and create two files: Hello JS and index js
If it is a global installation, execute it directly under the project root directory:
rollup -i src/index.js -o dist/bundle.js -f es**
If the project is installed locally, in package Add to the script field of JSON:
"dev": "rollup -i src/index.js -o dist/bundle.js -f es", and then execute npm run dev
Here, we take the local installation as an example. As follows, rollup outputs the packaging results on the command line.
In this instruction:
- -i specifies the file to package, - i is the abbreviation of -- input.
- src/index.js is the parameter of - i, that is, the package entry file.
- -o specifies the output file, which is -- output Abbreviation for file or -- file. (if there is no such parameter, it will be output directly to the console)
- dist/bundle.js is the parameter of - o, that is, the output file.
- -f specifies the format of the package file, - f is the abbreviation of -- format.
- es is the parameter of - f, indicating that the packaged file uses the ES6 module specification.
The formats of package files supported by rollup include AMD, cjs, ES \ ESM, iife and umd. Among them, AMD is amd standard, cjs is CommonJS standard, esm\es is es module standard, iife is immediate call function, and umd supports AMD, cjs and iife at the same time.
rollup profile
In project development, we usually use configuration files, which can not only simplify command-line operation, but also enable the advanced features of rollup.
Create rollup.com under the project root directory config. js.
export default { input: "./src/index.js", output: [ { file: './dist/my-lib-umd.js', format: 'umd', name: 'myLib' //When the entry file has export, the 'umd' format must specify name //In this way, when importing through the < script > tag, you can access the contents of export through name. }, { file: './dist/my-lib-es.js', format: 'es' }, { file: './dist/my-lib-cjs.js', format: 'cjs' } ] } Copy code
Using the Rollup configuration file, you can use the rollup --config or rollup -c directive.
//Modify package script field of JSON "dev": "rollup -c" // Rollup is used by default config. js "dev": "rollup -c my.config.js" //Use a custom configuration file, my config. js Copy code
src/index.js content:
import { hello } from './hello' hello() export const world = 'world' Copy code
Packaged files:
It can be seen that for the same entry file, the file volume in es format is the smallest.
rollup plugin
Above, we know the basic usage of rollup. In practical application, there will be many more complex requirements, such as how to support es6 syntax and how to package vue file, how to compress our js code, etc. In rollup, we use plug-ins to do this.
In the webpack, the loader is used to preprocess the source files, and the plugin completes the specific functional requirements of the build package. The plugin of rollup has the functions of both loader and plugin in webpack.
Some commonly used plug-ins.
rollup-plugin-babel
Rollup plugin Babel is used to convert es6 syntax.
Set Src / Hello JS is rewritten as:
export const hello = () => { console.log('hello world') } Copy code
Packaging results without babel plug-in:
Using the babel plug-in:
npm i rollup-plugin-babel @babel/core @babel/preset-env --D
//rollup.dev.js import babel from 'rollup-plugin-babel' export default { input: ..., output: ..., plugins:[ babel({ exclude: 'node_modules/**' }) ] } Copy code
Create in the project root directory babelrc file.
{ "presets": [ [ "@babel/preset-env" ] ] } Copy code
Repackage:
rollup-plugin-commonjs
rollup does not support the CommonJS module by default. You can avoid using the syntax of the CommonJS module when writing by yourself. However, some external libraries are cjs or umd (packaged by webpack), so using these external libraries needs to support the CommonJS module.
Create a new Src / util JS file, as follows:
module.exports = { a: 1 } Copy code
In Src / index JS js
import util from './util' console.log(util.a) Copy code
An error will be reported when npm run dev is packaged:
This requires the use of rollup plugin commonjs. First, NPM I rollup plugin commonjs -- D
In rollup Config, JS:
import commonjs from 'rollup-plugin-commonjs' export default { input: ..., output: ..., plugins:[ commonjs() ] } Copy code
When npm run dev is packaged, no error is reported.
We can also use require to introduce modules in the code:
// src/index.js const util = require('./util') console.log(util.a) Copy code
Rollup plugin commonjs can recognize the require syntax and package it into es module syntax. The packaged my lib es JS is as follows:
var util = { a: 1 }; console.log(util.a); var src = { }; export default src; Copy code
rollup-plugin-postcss
The plug-in needed to handle css is rollup plugin postcss. It supports css file loading, css prefixing, css compression, support for scss/less, and so on.
First, install NPM I rollup plugin postcss postcss -- D, and then in rollup config. JS configuration:
import postcss from 'rollup-plugin-postcss' export default { input: ..., output: ..., plugins:[ postcss() ] } Copy code
Then, create a new test CSS, in index JS. umd file obtained after packaging:
(function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); }((function () { 'use strict'; function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = "body{\r\n color: green;\r\n}"; styleInject(css_248z); }))); Copy code
The imported css file will be used to generate style tags and insert them into the head.
We create a new test file and import the umd file. You can see in the head that we are testing Content written by CSS.
<body> test css </body> <script src="../dist/my-lib-umd.js"></script> Copy code
css prefix
Use the autoprefixer plug-in to prefix some properties of css3. Install npm i autoprefixer@8.0.0 --D. Configuration:
import postcss from 'rollup-plugin-postcss' import autoprefixer from 'autoprefixer' export default { input: ..., output: ..., plugins:[ postcss({ plugins: [ autoprefixer() ] }) ] } Copy code
In addition to the above configuration, you also need to configure browserslist to use autoprefixer. There are two ways: one is to create a browser list Browserlistrc file, the other is directly in package JSON. We configure it in package JSON, add the "browserslist" field.
"browserslist": [ "defaults", "not ie < 8", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions" ] Copy code
Modify test CSS content:
body{ color: green; display: flex; } Copy code
Package and refresh the test page just now.
css compression
Cssnano compresses the packaged css. It is also easy to use. Like autoprefixer, install cssnano and configure it.
plugins:[ postcss({ plugins: [ autoprefixer(), cssnano() ] }) ] Copy code
Extract a separate css file
Rollup plugin postcss can configure whether to separate css. By default, there is no extract. css style generates style tags, which are inline into the head. If extract is configured, css will be separated into separate files.
postcss({ plugins: [ autoprefixer(), cssnano() ], extract: 'css/index.css' }) Copy code
Of course, the packaged css files need to be introduced separately in the page.
Support scss/less
In actual projects, we are unlikely to write css directly, but use pre compilers such as scss or less. Rollup plugin postcss integrates support for scss, less and stylus by default. In our project, as long as rollup plugin postcss is configured, you can directly use these css precompilers, which is very convenient.
rollup-plugin-vue
Rollup plugin Vue is used for processing Vue file. The version of rollup plugin Vue used in vue2 and vue3 projects is different, and the compiler of Vue is also different.
- vue2: rollup-plugin-vue^5.1.9 + vue-template-compiler
- vue3: rollup-plugin-vue^6.0.0 + @vue/compiler-sfc
Take vue2 as an example:
npm i rollup-plugin-vue@5.1.9 vue-template-compiler --D
In rollup Add rollup plugin Vue to dev.js
import vue from 'rollup-plugin-vue' export default { ... plugins:[ vue() ] } Copy code
Create a new vue file and modify Src / index js
npm run dev package, let's take a look at the generated umd file.
Test umd file:
<body> <div id="app"> <hello></hello> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../dist/my-lib-umd.js"></script> <script> Vue.use(myLib) new Vue({ el: '#app' }) </script> Copy code
The successful use of the component indicates that our configuration can be compiled and packaged vue file.
Rollup plugin vue also supports scss, less and stylus by default, and can be used directly in the project. Here you are css in vue files is automatically prefixed and needs to be configured in rollup plugin vue. More configuration references rollup-plugin-vue
import vue from 'rollup-plugin-vue' import autoprefixer from 'autoprefixer' //Also configure the browserlist import cssnano from 'cssnano' export default { ... plugins:[ vue({ style: { postcssPlugins: [ autoprefixer(), cssnano() ] } }) ] } Copy code
rollup-plugin-terser
In the production environment, code compression is essential. We use rollup plugin terser for code compression.
import { terser } from 'rollup-plugin-terser' export default { ... plugins:[ terser() ] } Copy code
In the above process, we all pack the files, and then introduce them through script, or npm link, and then debug in other projects. This is more like a debugging method for the component library. If we package an application with rollup, can it be hot updated like webpack? The answer is yes. We need to use rollup plugin serve and rollup plugin livereload.
rollup-plugin-serve,rollup-plugin-livereload
The two plug-ins are often used together. Rollup plugin serve is used to start a server, and rollup plugin liveload is used to refresh the page in real time when the file changes.
import serve from 'rollup-plugin-serve' import livereload from 'rollup-plugin-livereload' export default { ... plugins:[ serve({ contentBase: '', //The folder started by the server is the root directory of the project by default. You need to create index html port: 8020 //Port number, 10001 by default }), livereload('dist') //watch dist directory, which refreshes the page when the files in the directory change ] } Copy code
We need to be in the index Html is manually added to the packaged file, js or css, because it is not automatically injected at this time. Then visit http://localhost:8020 You can see the index HTML.
However, if the file in src is modified at this time, the page will not be refreshed in real time, because the file in dist directory is not updated. rollup listens for changes to the source file simply by adding - w or -- watch when executing the package command
//package.json "scripts": { "dev": "rollup -wc" }, Copy code
When you're done, modify the code of the source file, and you'll find that the browser is updated in real time.
Package on-demand component libraries
That's all. It's too easy to package and load components on demand.
For component library projects, on-demand loading is supported. The requirements are met: the component library is exported in ES modular mode. rollup supports the export of ES modules.
Create two vue components, hello and test:
Modify Src / index js:
import Hello from "./components/Hello" import Test from "./components/Test" function install(Vue){ Vue.use(Hello) Vue.use(Test) } /*** In the es module, variables that can be introduced on demand need to be exported in these ways: export const a = 1 export function a(){} export { a, b } You cannot use export default ***/ export { Hello, Test } export default install //umd Copy code
Modify rollup config. JS is as follows:
import babel from 'rollup-plugin-babel' import commonjs from 'rollup-plugin-commonjs' import vue from 'rollup-plugin-vue' import autoprefixer from 'autoprefixer' export default { input: "./src/index.js", output: [ { file: './dist/my-lib-umd.js', format: 'umd', name: 'myLib' }, { file: './dist/my-lib-es.js', format: 'es' }, { file: './dist/my-lib-cjs.js', format: 'cjs' } ], plugins:[ babel({ exclude: 'node_modules/**' }), vue({ style: { postcssPlugins: [ autoprefixer() ] } }), commonjs() ], external:[ //External library. When using the 'umd' file, you need to import this external library first 'vue' ] } Copy code
After packaging, modify the package json:
"main": "dist/my-lib-cjs.js", "module": "dist/my-lib-es.js", Copy code
Then you can test in the test project. For details, please refer to How to debug component libraries locally
import { Hello } from "my-lib-new" Vue.use(Hello) Copy code
So far, we have completed packaging the on-demand component library with rollup. The overall feeling is that it is much more convenient than webpack. There is no need to use plug-ins when loading components on demand. It is very excellent in class library packaging.
Author: Alaso
Link: https://juejin.cn/post/6934698510436859912
Source: rare earth Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.