First we need to know what rollup does

What does rollup do?

Rollup is a JavaScript wrapper modulator that compiles small code into large blocks of complex code, such as libraries or applications. Rollup uses new standardized formats for code modules that are included in the ES6 version of JavaScript, rather than previous ad-hoc solutions such as CommonJS and AMD. ES6 modules allow you to use the most useful stand-alone functions in your favorite library freely and seamlessly, without having to carry around other unused code in your projects. ES6 modules will eventually be implemented natively in the browser, but the current Rollup gives you an early taste.

Rollup plug-in collection rollup plug-in collection

Install a rollup

  1. The preferred installationnode.js
  2. Run the following command to perform the global installation
npm install rollup --global // or npm i rollup -g
Copy the code
  1. To check whether the installation is successful, enter rollup on the terminal

This indicates that the global rollup installation was successful

Implement a simple Hello World

  1. Create a folder and create it under the folderindex.js.hello.js

Hello.js looks like this:

export function hello() {
    return 'hello'
}

export function world() {
    return 'world'
}
Copy the code

The index.js code is as follows:

import {hello, world} from './hello.js'
const result = hello() + world()
Copy the code
  1. To compile, enter the following command at the terminal:
npx rollup index.js --file dist/bundle.js --format iife
Copy the code

We found that a folder dist was packaged as follows:

Let’s take a look at the package:

At this time we will be very confused, said hello, world? This is because tree-shaking is similar to Webpack. So let’s do a transformation:

import {hello, world} from './hello.js'
const result = hello() + world()
document.getElementById('app').innerHTML = result
Copy the code

Then look at the output code in the package

This is where hello World comes in. The rollup package is much cleaner than webPack, so we’ll talk about the difference between WebPack and Rollup.

Webpack and rollup

webpack

The construction of large SPA projects, also known as Web applications.

  • Handle various resource files through various loaders
  • Some processing of the overall file is done through various plug-in Plugins
  • Code spliting Extracts public modules
  • Provide a webpack-dev-server for local development
  • Supports hot replacement of HMR modules

rollup

  • Rollup was designed to build a flat, high-performance library for ES Module
  • The goal is to package ES Modules to produce a specific JS module file and reduce its size
  • The compiled code is more readable, smaller, and more efficient
  • Easier configuration

By the way, the ES Module rule

  • Import statements can only be used as the top layer of a module, not in function if unlike commonJS
  • Module names for ES Modules can only be string constants
  • No matter where the import statement appears, all imports must be imported at module initialization

webpack VS rollup

From the above we can know that webPack is suitable for App construction, and rollup is more suitable for class library construction.

Let’s try to configure Rolluop

Rolluop configuration

  1. Create a new folderrolluplearnDirectory executionnpm init -y
  2. Install a rollup
  3. Create the following directory structure and create a filerollup.config.js

  1. Write the rollup configuration as follows:
// Read the json file
import json from '@rollup/plugin-json';
export default {
    input: 'main.js'.input: 'main.js'.// Import file
    output: {        
        file: 'dist/bundle.js'.// Package file address
        format: 'esm'.// Package in esModule format
    }
    plugins: [json()]
}
Copy the code
  1. inpackage.jsonTo edit the package script:
"scripts": {
    "build": "rollup --config rollup.config.js"
  }
Copy the code
  1. Start writing main.j and SRC /test.js files

src/test.js

const hell = () = > {
    console.log('hell')}const fn = () = > {
    console.log('fn')}export {
    hell,
    fn 
}
Copy the code

main.js

import { fn, hell }from './src/test'
import { version } from './package.json'
console.log(version)
fn()
Copy the code
  1. performnpm run build, the results are as follows:

Rollup is relatively simple and not as complex as weeBPack configuration, so let’s take a look at vuE3 plug-in development.

Vue3 plug-in system development

Add global functionality to vue3 applications. Generally, Object has an install method or function is used directly. There are no strict restrictions on these functions.

  • Add global methods and properties
  • Add global resources and directives
  • Add some component options through global mixin
  • Add instance methods of the app via config.globalProperties

Developing a plug-in

The global method

Create a project using vue-cli and create the test.plugin.ts file under Components as follows:

import {App} from 'vue'
const plugins = {
    install(app: App) {
        app.config.globalProperties.$echo = () = >{
            console.log('echo plugin')}}}export default plugins

Copy the code

Next use it in main.ts for global use

import testPlugin from './components/test.plugin'
createApp(App)
.use(store)
.use(router)
.use(testPlugin)
.mount('#app')
Copy the code

$echo = $echo = $echo = $echo = $echo = $echo = $echo

<script lang="ts">
import { defineComponent, getCurrentInstance } from 'vue'
export default defineComponent({
  setup() {
      // getCurrentInstance returns the instance object of the current componentgetCurrentInstance()? .appContext.config.globalProperties.$echo() } }) </script>Copy the code

View the Browser console

Now that our global methods have been added, let’s look at how to add global components.

Global components

Some changes are made in mian. Ts

import {App} from 'vue'
const plugins = {
    install(app: App) {
        app.config.globalProperties.$echo = () = >{
            console.log('echo plugin')
        }
        app.component(HelloWord.name, HelloWord)
    }
}
export default plugins
Copy the code

We have already registered the global method in main.ts using the use method. Now we only need to use the global method in app. vue as follows:

<template>
  <div id="nav">
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <router-view/>
</template>
Copy the code

The global component has been registered in the browser

In general, it is almost the same as VUE2. The main differences are:

  • The vue2 global method is mounted on the prototype object of Vue, and vue3 is mounted onapp.config.globalPropertiesOn the way
  • Vue2 can be called directly using this. XXX, as vue3 doesgetCurrentInstance()? .appContext.config.globalPropertiesThe calling

Now that we’re almost done developing a plug-in using VUe3, we need to understand how a component library entry should be developed.

Component library entry file design

When we use a component library, there are two ways to import, one is global import, the other is load on demand. So you should have an index.ts file when exporting:

import componentA from './a'
const componentList = [
    componentA
]
const install = (app: App) {
      ...
}
// Export a single
expoert {
...
}
// Export all
export default {
    install
}
Copy the code

There should also be an install method at componentA, so how do you implement that? 🤔️ Modify the project downloaded from the original VUe-CLI directory as follows:

Now main implementation components/TText/index. The ts and index. The ts components/TText/index. The ts

import { App } from 'vue'
// Just write a component
import TText from './TText.vue'

// Add the install method to the component to make it easier to use a single component directly
TText.install = (app: App) = > {
    app.component(TText.name, TText)
}

export default TText
Copy the code

index.ts

import { App } from 'vue'
import TText from './components/TText'
// List of components
const components = [
  TText
] 
// Use all components
const install = (app: App) = > {
    components.forEach(component= > {
      app.component(component.name, component)
    })
  }
export {
  TText,
  install
}
export default { install }
Copy the code

At this point we will complete the development of the component entry file. The rest will basically follow this pattern and build the wheel directly. Next we will use rollup to package the umD and ESModule files.

Add rollup configuration and package

The root directory creates the Build folder and creates from there

  1. rollup.config.js: Common basic configuration
  2. rollup.esm.config.js: Package the esModule file configuration
  3. rollup.umd.config.jsPackage the UMD file configuration

Rollup.config.js rollup.config.js rollup.config.js rollup.config.js

// Process vue file plug-ins
import vue from 'rollup-plugin-vue'
// Handle CSS file plug-ins
import css from 'rollup-plugin-css-only'
// Process the TS plugin
import typescript from 'rollup-plugin-typescript2'
// Used to use third-party modules in node cell modules
import { nodeResolve } from '@rollup/plugin-node-resolve'
import { name } from '.. /package.json'
// Output the packaged file name type 1.esm 2.umd
const file = type= > `dist/${name}.${type}.js`
const overrides = {
  compilerOptions: { declaration: true }, // Generate.d.ts files
  exclude: ["tests/**/*.ts"."tests/**/*.tsx"]}export { name, file }
export default {
  input: 'src/index.ts'.output: {
    name,
    file: file('esm'),
    format: 'es'
  },
  plugins: [
    nodeResolve(),
    typescript({ tsconfigOverride: overrides }),
    vue(),
    css({ output: 'bundle.css' }) // You can modify the output file name].external: ['vue'.'lodash-es'] // Specify which modules are externally referenced
}
Copy the code

rollup.esm.config.js

import basicConfig, {file, name} from './rollup.config'
export default {
    ...basicConfig,
  output: {
    name,
    file: file('esm'),
    format: 'es'}}Copy the code

rollup.umd.config.js

import basicConfig, { name, file } from './rollup.config'
export default {
  ...basicConfig,
  output: {
    name: 'thComponents'.file: file('umd'),
    format: 'umd'.globals: { // Set the name of the global variable
      'vue': 'Vue'.'lodash-es': '_'
    },
    exports: 'named'}}Copy the code

Writing packaging scripts

"scripts": {
    "build": "npm run clean && npm run build:esm && npm run build:umd".// Whole package instruction
    "build:esm": "rollup --config ./build/rollup.esm.config.js"./ / packaging esmodule
    "build:umd": "rollup --config ./build/rollup.umd.config.js".// Package in UMD format
    "clean": "rimraf ./dist" / / remove dist
  },
Copy the code

Run NPM run build

View the results

With the components packaged, let’s test them locally using NPM Link

Release the component

Component library testing using NPM Link

  1. Configuration package. Json
{
    "name": "th-bricks"."version": "0.1.0 from"."private": false."author": "linlei"."main": "dist/th-bricks.umd.js"."module": "dist/th-bricks.esm.js"."types": "dist/index.d.ts". }Copy the code
  1. Run in the root directory:npm link

  1. For use in projects
  • configuration
"dependencies": {..."th-bricks": "0.1.0 from"
  }
Copy the code
  1. performnpm link th-bricks

  1. Introduced in the project main.ts and used in app.vue

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import thBricks from 'th-bricks'
import 'th-bricks/dist/bundle.css'
import router from './router'
import store from './store'
createApp(App)
.use(store)
.use(router)
.use(thBricks)
.mount('#app')
Copy the code

App.vue

<template>
  <div id="nav">
    <! - use - >
    <t-text text="hello" tag="h2" />
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <router-view/>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({

  setup() {
    return{}}})</script>
Copy the code
  1. View the results

You can see that component pits have been rendered: if you can print thBricks and it doesn’t work, restart your computer and try.

Release NPM

  1. First check whether you are logged innpm whami
  2. Skip if already logged in, otherwise usenpm loginFor login, if you do not have an NPM account, you need to register one
  3. releasenpm publish

You can see that the release has been successful.

🤔 There is no guarantee that NPM run build is executed every time we publish, so what can we do about it? After looking at a variety of information found that can be handled as follows:

"scripts": {
    "build": "npm run clean && npm run build:esm && npm run build:umd"."build:esm": "rollup --config ./build/rollup.esm.config.js"."build:umd": "rollup --config ./build/rollup.umd.config.js"."clean": "rimraf ./dist"."prepublishOnly": "npm run build" // NPM publish executes NPM run build first
  }
Copy the code

Write in the last

  • The basic component library process is almost complete, but there is still a long way to go to a complete component library, which needs to be continuously enriched, such as tree, table, message, various project-specific components, etc
  • Component library code