Make writing a habit together! This is the fourth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

This article describes the process of packaging a component library with Webpack from scratch.

1. Initialize the project

vue init webpack-simple tip-components
Copy the code

Optimizing directory structure

Modify the project structure, the following directory structure is clearer and more reasonable.

We created build to package the configuration, doc to store the documentation, and lib to store the packaged output file.

2. Pack the configuration

It is good practice to package configurations for different requirements in separate files.

Our packaging configuration has a base class file and different subclasses depending on the packaging requirements — complete component library packaging, individual component packaging, and sample project packaging.

Simplify packaging commands by configuring scripts in NPM’s script.

Packaging orders

(See package.json for details of what the command does and which configuration file to select.)

Run the sample project NPM run test

Package the complete component library NPM Run build

Package a single component NPM Run Build: Components

Generate the component document NPM Run build:doc

* Any package command plus :analyze, enable the webpack-bundle-Analyzer plugin, after the package is complete will open the bundle analysis page.

Let’s focus on the next three packaging profiles.

webpack.base.js

Common Webpack configuration, including the Rules configuration module for reading and parsing rules, and the Webpack-bundle-Analyzer plug-in.

//webpack.base.js
var path = require('path')
var webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
  module: {
    rules: [
    / /...]}}if (process.env.npm_config_report) {
  module.exports.plugins = (module.exports.plugins || []).concat([new BundleAnalyzerPlugin()])
}

Copy the code

webpack.prod.js

Inherit from webpack.base.js, complete component library packaging configuration, output file as tip-components.min.js, containing all components. The modular format is UMD, suitable for various introduction methods.

//webpack.prod.js
var path = require('path')
var webpack = require('webpack')
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.js');

const basePath = path.resolve(__dirname, '.. / ')

module.exports = merge(webpackBaseConfig, {
  entry: path.join(basePath, 'src'.'enter.js'),
  output: {
    path: path.resolve(__dirname, '.. /lib'),
    publicPath: '/lib/'.filename: 'tip-components.min.js'.// Output the file name
    library: 'tip-components'.// Component library name
    libraryTarget: 'umd'.// Modular format
    umdNamedDefine: true
  },
  externals: {
    vue: {  // Externalize vUE dependencies without packaging them into component libraries
      root: 'Vue'.commonjs: 'vue'.commonjs2: 'vue'.amd: 'vue'}}});Copy the code

The entry file packaged here is SRC /enter.js. Let’s see what this entry file does.

enter.js
import dialog from './component/dialog/dialog.js'
import marquee from './component/marquee/main.js'
import toast from './component/toast/toast.js'
/ /...

const components = {
    dialog,
    marquee,
    toast,
    / /...
}

export default components
Copy the code

Here we simply import all the components, put them in components, and export them out.

We add a package command to the package.json file.

"build": "webpack --config build/webpack.prod.js --progress --hide-modules".Copy the code

Run NPM run build, package the entire component library, and you’re done!

The last configuration file to mention is webpack.component.js, which is used to package individual components, which we’ll cover in the next section.

3. Package the configuration in chunks

Normally, we only need one or two components from the component library, and it is obviously unreasonable to introduce the whole library. We implement load on demand, and the premise of load on demand is that our components can be packaged individually.

Let’s start by creating a components.json file that configudes which components need to be packaged separately and where to locate them.

//components.json
{
    "marquee": "component/marquee/main.js"."toast": "component/toast/toast.js"."dialog": "component/dialog/dialog.js"./ /...
}
Copy the code

webpack.component.js

Inheriting from webpack.base.js, packaging a single component.

Instead of webpack.prod.js, we configure entry as multiple entries, traversing components. Json to fill in the name and path information of the component. Output only needs to be specified, using placeholders to ensure the name of the output file bit component.

var path = require('path')
var webpack = require('webpack')
const merge = require('webpack-merge');
const components = require('./components.json')
const webpackBaseConfig = require('./webpack.base.js');

const basePath = path.resolve(__dirname, '.. / ')
let entries = {}
Object.keys(components).forEach(key= > {
  entries[key] = path.join(basePath, 'src', components[key])
})

module.exports = merge(webpackBaseConfig, {
  entry: entries,
  output: {
    path: path.resolve(__dirname, '.. /lib'),
    publicPath: '/lib/'.filename: '[name].js'.chunkFilename: '[id].js'.library: '[name]'.// Specify the module name when you use require
    libraryTarget: 'umd'.umdNamedDefine: true // AMD modules in the UMD build process are named. Otherwise use anonymous define
  },
  externals: {
    vue: {
      root: 'Vue'.commonjs: 'vue'.commonjs2: 'vue'.amd: 'vue'}}});Copy the code

We add a package command to the package.json file.

"build:components": "webpack --config build/webpack.component.js --progress --hide-modules".Copy the code

Run NPM run build: Components, pack the components separately, and you’re done!

4. Import components as required

Since individual component packaging is implemented, we certainly do not import the entire component library each time, after we publish the component library to TNPM, in order to import individual components, we can.

import dom2image from "@tencent/tip-components/lib/dom2image";
Copy the code

But the path is too long and cumbersome.

babel-plugin-import

We can use the babel-plugin-import plug-in to convert the path.

Installing a plug-in

npm install babel-plugin-import --save-dev
Copy the code

Add configuration in babel.config.js

//babel.config.js
plugins: [["import", {
	"libraryName": "@tencent/tip-components"."libraryDirectory": "lib".// default: lib
}]]
Copy the code

So, we can use this directly, by default, to find the individual components in the lib file, happily.

import { dom2image } from "@tencent/tip-components";
Copy the code

5. Sample project

To make it easier to debug components during development, you can add a portal that pulls up an HTML page for debugging. This is the same as creating a normal Vue page. See webpack.demo.js for the configuration.

Let’s add a package command to run a sample page service with webpack-dev-server.

"test": "webpack-dev-server --config build/webpack.demo.js --open --hot".Copy the code

Note that since we initially created Webpack-Simple, not the full webpack template, we need to take the initiative to include the js file dist/main.js that is packaged as output in the HTML file. If your sample page is blank, please check that the output file is correctly imported.

6. Document generation

jsdoc

Jsdoc is chosen here to automatically generate the document (later found that the document directly generated by JSdoc is not pretty, the example can not clearly explain the usage, lack of pictures and GIF demonstration, JSdoc as a timely update of the API document is sufficient, but in order to make the library users more convenient to start with, it is suggested to organize the document of the component).

To better document vUE components from annotations, we also used the jsdoc-vuejs plug-in.

For the configuration file, see doc.conf.json.

Add a document generation command to package.json:

"build:doc": "jsdoc -c ./build/doc.conf.json ./src/*"
Copy the code

NPM run build:doc generates documentation.

The detailed process of document generation can be seen in another article, VueJS document generation

0. Refer to the article

How to build a VUE component library

VueJS document generation

Past oliver

Say goodbye to Bad Code

2022 Code Specification Best Practices (with Web and applets Best configuration examples)

【 Front-end Exploration 】 Say goodbye to bad code! Encapsulate network requests in the chain of responsibility pattern

【 Front-end Exploration 】 Say goodbye to bad code # 2! Encapsulate sharing components with policy patterns

The code of life

[Thinking on three years of front-end development] How to read requirements effectively?

Front end step pit must see guide

[Front-end exploration] Best practices for image loading optimization

[Front-end exploration] Exploration of mobile terminal H5 to generate screenshot posters

[Front-end Exploration] H5 to obtain user positioning? This one is enough

【 Front-end exploration 】 The exploration of wechat small program jump — Why does open label exist?

VConsole fancy usage