Construction of a Vue UI component library from zero

Foreword

The reason to write this article is to build your own course record a component library, but also to those students who want to write a tutorial component library. Component library also wrote some time, also set up the basic shelf almost the same, but look at your build process is not perfect, so come back again organize their own ideas, so that their technology has outputs.

Look under the effect ninecat-ui.github.io

Component library source code ninecat-ui (If you feel good, you can give a start oh)

Here Insert Picture Description
Here Insert Picture Description

Here is what I write in this UI component library some Todolsit, has completed the function has been ticked, and if you are interested and I can function together to complete unfinished.

  • Custom document directory structure
  • By MD component demo to show
  • Integrated Travis CI
  • Integrated Unit Testing
  • Integrated codecov
  • Automatically build component document
  • According tag automatically publish npm
  • Integrated docsearch
  • Integrated codepen
  • Custom color themes
  • Multi-language internationalization
  • JavaScript and typescript mixed-use development

Well, let's get started!

Find the right component library prototype

Before you start writing component library, you need to have a good prototype drawing. The more popular domestic and Ant Design Element UI has a corresponding component library, if you want to practice hand, it can be directly used to use.

Here are two links to go download the corresponding UI component library resources.

https://element.eleme.cn/2.0/#/zh-CN/resource

https://ant.design/docs/spec/download-cn

I use Rsuite UI component library, I feel pretty good conscience team.

With a prototype you can start work again!

Initialize the project

Since it is starting from scratch to build a library of components that certainly can not be used to build the scaffolding, it is not called from scratch, and we direct all npm initstart the project.

mkdir ninecat-ui
cd ninecat-ui
npm init

Here is initialized to the project a success, and look below to install the necessary dependencies.

Installation depends

Based on my experience installing its dependencies, the dependent is divided into these types: Core dependence, build dependencies, tool-dependent. Of course, this is according to my functionality to distinguish, and classify more professional look https://zhuanlan.zhihu.com/p/29855253

Here we use the yarn to install dependencies. Now install dependencies to not distinguish what type depend directly yarn addon the line, and so build a good rack back again distinction belongs to the kind of dependency, and then reconstruct it package.json files on package.json more detailed documentation may refer to https: // docs.npmjs.com/files/package.json

A basic VUE project needs about these dependencies:
VUE, WebPACK, WebPACK-cli, WebPACK-dev-Server, @ babel / Core, babel-Loader, CSS-Loader, HTML-WebPACK-plugin, VUE-Loader
, VUE-Template -compiler

Write the simplest code

Dependence installed, we have to define what the project html template, import documents and VUE home page document root directory of the new index.html, new src directory, create a index.js the src and index.vue.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ninecat-ui</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

index.vue

<template>
  <div>Hello Ninecat-ui</div>
</template>

<script>
export default {
  name:'App'
}
</script>

index.js

import Vue from 'vue'
import App from './index.vue'

new Vue({
  render: h => h(App)
}).$mount('#app')

Well content, now need to look at webpack simple configuration so that the project up and running.

Add the simplest configuration webpack

Create a build directory with the directory, add a configuration file which webpackwebpack.config.base.js

'use strict'
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader')
const path = require('path')

module.exports = {
  entry: path.resolve(__dirname, '../src/index.js'),
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: "index.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
      filename: 'index.html',
    }),
    new VueLoaderPlugin(),
  ]
}

If some students still do not understand these basic configuration, you should look through what the official documents webpack, oh, given the link: https://www.webpackjs.com/

Be configured as described above, a basic VUE project is built almost, then we need to configure the startup script of the project. Package.json follows in which scripts:

"scripts": {
    "start": "webpack-dev-server --config build/webpack.config.base.js"
 },

Finally, look at our project directory structure:

Then we run the project:yarn start

OK, here's a basic vue build a good project, we can begin to build behind the components.

The preparation of the first component

First at the root of a new packagesfile, and then create a hello in the following folder, open a writing component. Components role is simply that of a simple greeting assembly, passing the name can be displayed Hello, xxx page.

Here we take a look at the directory structure:

Now I need to write about our Hello component.

packages/hello/src/index.vue

<template>
  <div>
    <h2>Hello, {{name}} !</h2>
  </div>
</template>

<script>
export default {
  name:'Hello',
  props:{
    name:{
      type:String,
      default:'Ninecat UI'
    }
  }
}
</script>

packages/hello/index.js

import Hello from './src/index.vue'

// install 是默认的方法,供按需引入。
// 当外界在 use 这个组件的时候,就会调用本身的 install 方法,同时传一个 Vue 这个类的参数。

Hello.install = function(Vue){
  Vue.component(Hello.name, Hello)
}

export default Hello

Components folder reason for such a write is to allow the components to have a unified export, src directory folder under each component can be extended to other functional components.

src/index.vue

<template>
  <div>
    <Hello 
      :name="name"
    />
  </div>
</template>

<script>
import Hello from '../packages/hello'
export default {
  name:'App',
  components:{
    Hello
  },
  data:function(){
    return {
      name:'Terence'
    }
  }
}
</script>

OK, here we count encapsulates a simple Hello components, but now we have not achieved after the components packaged with npm install this component library, and then reference inside Hello components, so the following is required to export the configuration and package configuration.

Configuration export and packaging

Well written component requires a unified export, is now a component, will be behind many components, so we need to harmonize the export component.

packages/index.js

import Hello from './hello'

const components = {
  Hello
}

const install = function (Vue) {
  Object.values(components).forEach(component => {
    Vue.component(component.name, component);
  })
}

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}

export default {
  install,
  Hello
}

Configuration package
build / webpack.config.build.js

'use strict'
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')


module.exports = {
  mode: 'production',
  entry: {
    'ninecatui': './packages/index.js' // 入口文件
  },
  output: {
    path: path.resolve(__dirname, '../package'), // 出口目录
    publicPath: '/package/',
    library: 'ninecatui', // 包名
    libraryTarget: 'umd',
    umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
  },
  externals: {
    vue: {
      root: 'Vue',
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue'
    }
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all'
        }
      }
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
  ]
}

Here's the basic package it, test it locally.

In package.jsonadding a packaging script,

"build": "webpack --config build/webpack.config.build.js"

We look to build the project:npm run build

Will play a package folder, we cite the component library.

Modify src / index.js

import Vue from 'vue'
import App from './index.vue'
import Ninecatui from '../package/ninecatui'

Vue.use(Ninecatui)

new Vue({
  render: h => h(App)
}).$mount('#app')

Modify src / index.vue

<template>
  <div>
    <Hello 
      :name="name"
    />
  </div>
</template>

<script>
export default {
  name:'App',
  data:function(){
    return {
      name:'Ninecat UI'
    }
  }
}
</script>

Like accessible.

Next we will try to package npm, and then installed locally to refer to the component library.

NPM release

Local packaged test

Modify an entry file package.json file

"main": "package/ninecatui.js",

Then npm packyou can play a ninecatui-1.0.0.tgzfile.

This file can be installed via npm, in order to test, we can test it directly on the current project.

Before mounting npm need to change the look package.jsonof the name, or will conflict at the time of installation, we will

"name": "ninecatui"

Change

"name":"ninecatui-test"

Direct yarn add ./ninecatui-1.0.0.tgzornpm install ./ninecatui-1.0.0.tgz

The reason for the increase ./is because the local path for the installation is a parameter.

If the above effect, congrats on your local installation was successful, let's change it references, to see whether the application can be used normally.

modifysrc/index.js

import Vue from 'vue'
import App from './index.vue'
// 修改引用
import Ninecatui from 'ninecatui'

Vue.use(Ninecatui)

new Vue({
  render: h => h(App)
}).$mount('#app')

Nice, normal use, instructions are packaged locally normal use. Let's publish it to npm.

Publish to npm

In the first npm register an account on the official website.

Under the project root directory, login npm account, enter your user name, password, email.

npm login

As information appears to show that you log on success.

Then execute npm publishto

The figure, ninecatui-testis our package.

Verification Test npm package

We vue-cli create a vue project, and then install introduced by npm.

direct

vue create hello-world

then

yarn add ninecatui-test

Direct tinkering src/main.jsandsrc/App.vue

src/main.js

import Vue from 'vue'
import App from './App.vue'
import Ninecatui from 'ninecatui-test'

Vue.use(Ninecatui)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

src/App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <Hello 
      :name="name"
    />
  </div>
</template>

<script>

export default {
  name: 'App',
  data:function(){
    return {
      name:'Ninecat UI'
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Congratulations, first npm package successfully published. npm publish successfully taken the least a small step back but also continue to optimize the project engineering.

Published an original article · won praise 0 · Views 7

Guess you like

Origin blog.csdn.net/github_39132491/article/details/105177858