First time in nuggets article, a bit verbose, everyone forgive me.

Most current UI frameworks are designed with relatively complex Webpack configurations, such as Element, Ant Design Vue, and Muse-UI Vue component libraries. For Element, for example, the Webpack configuration becomes very complex in order to implement two forms of introduction at the business level (full introduction and on-demand introduction) and throw out some utils, i18n, and so on that are common to the business level. In order to simplify the UI framework design, here is a simple UI framework design, and before that, let’s take a quick look at the Element build process to compare the new UI framework design.

Designers of general component libraries design the introduction form into two forms: complete introduction and on-demand introduction: the development of the complete introduction is relatively convenient, for some large businesses or for the packaging volume is not particularly focused on the business, the development of on-demand introduction is relatively fine granularity, can reduce the packaging volume of the business.

The github address of the designed UI framework practice project is Ziyi2 / Vue-cli3-Lerna-UI, including PRESET. Json, my designed Vue CLI plug-in and my designed series of UI components (slightly different from the generated UI framework example), If you think the overall structure is unreasonable or the consideration is not comprehensive enough, you are welcome to raise an issue, so that I can improve it. If you are interested, I hope you can Star, thank you here!

Element

To get an idea of the Element build process, check out the NPM script for Element2.7.0 version package.json:

// Where 'node build/bin/build-entry.js' generates the Webpack build entry
"build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js".// Build the CSS style
"build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib  lib/theme-chalk".// Build the commonJS specification 'utils'
"build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js".// Build the language pack for the UMD module
"build:umd": "node build/bin/build-locale.js".// Clear build folder 'lib'
"clean": "rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage".// Overall build
"dist": "npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme".// Perform esLint validation
"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet"
Copy the code

The focus here is on the Element’s build script, ignoring the scripts for testing, releasing, launching the development-mode debug page, building the demo page, and so on.

npm run dist

There are many NPM scripts associated with Element builds, but the overall build script is dist:

"dist": "npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme"
Copy the code

&& is the secondary execution. The next task can be executed only if the current task succeeds.

The overall build script contains the following script commands that are executed in sequence

  • npm run clean– Clear the build folderlib
  • npm run build:file– one of thenode build/bin/build-entry.jsGenerate the Webpack build entry
  • npm run lint– Perform ESLint verification
  • webpack --config build/webpack.conf.js– Build the UMD total file
  • webpack --config build/webpack.common.js– Build the commonJs2 total file
  • webpack --config build/webpack.component.js– Build CommonJS2 components (provide on-demand import)
  • npm run build:utils– Build commonJSutils(for total CommonJS2 files, CommonJS2 components, and services)
  • npm run build:umd– Build the UMD language pack
  • npm run build:theme– Build CSS styles

If the definitions for umD, CommonJS2, AMD and other modules are not clear, refer to the Webpack documentation for the module definition system.

NPM run dist will generate a new lib folder in the current root directory containing the following build:

Lib ├── Directives # Commonjs ├─ Mixins # commonjs Mixins - - Theme - Chalk # CSS Style document.exe - - Transitions # CommonJS Transitions - - UmD # UMD Language pack - - └ ── alert.js # Html.js # Html.js # html.js # html.js # html.js ├── Element-ui.com/mon.js # CommonJs2 General File ├──... ├── index.js # Umd - -...Copy the code

As you can see from the official Element documentation’s user guide in conjunction with Lib, Element provides the following capabilities:

  • 1, CDN import (UMD total file)
  • 2, NPM package full import (throw commonjs2 total file)
  • 3. Import on demand (throw all COMMONJs2 UI components)
  • 4. Support internationalization
  • 5, provideutilsMethod (not stated in the official documentation, but in fact the business can use it)

The total UMD file introduced by the CDN is generally built in full without dependency issues, but the commonJs2 module file needs to be built again at the business level using Webpack. For example, the need to support internationalization at the business level and provide functionality for Utils, You can’t internationalize and bundle the code that provides Utils into the total commonJs2 file or into all of the COMMONJS2 UI components (it’s obviously not reasonable for each component to bundleUtils methods or internationalization apis), and if you need to support the functionality introduced on demand at the business level, Therefore, it is not recommended to put the source bundle of all UI components into the total file of CommonJs2, so that multi-level reference can be realized, throwing functions externally while preventing Webpack secondary packaging at the business level, which leads to the problem of introducing the same code twice or more times.

When developing in a component library, to build the CommonJs2 module files, you need to make strong conventions for the paths that each utils, component, and so on are introduced, which not only makes the resulting Webpack configuration difficult to maintain, but also imposes some specification restrictions on the developer’s development.

Next, look at the build capabilities of each script.

npm run build:file

The build:file script is a script that automatically generates some source files:

"build:file": "node build/bin/iconInit.js & node build/bin/build-entry.js & node build/bin/i18n.js & node build/bin/version.js".Copy the code

The node build/bin/build-entry.js script is used to generate the Webpack build entry source file SRC /index.js:

// Note that the file is automatically generated by the build-entry.js script
/* Automatically generated by './build/bin/build-entry.js' */

import Pagination from '.. /packages/pagination/index.js';
/ /... Most component introductions are omitted here
import TimelineItem from '.. /packages/timeline-item/index.js';
import locale from 'element-ui/src/locale';
import CollapseTransition from 'element-ui/src/transitions/collapse-transition';

const components = [
  Pagination,
  / /... Most components are omitted here
  TimelineItem,
  CollapseTransition
];

const install = function(Vue, opts = {}) {
  locale.use(opts.locale);
  locale.i18n(opts.i18n);

  components.forEach(component= > {
    Vue.component(component.name, component);
  });

  Vue.use(Loading.directive);

  Vue.prototype.$ELEMENT = {
    size: opts.size || ' '.zIndex: opts.zIndex || 2000
  };

  Vue.prototype.$loading = Loading.service;
  // ...
};

/* istanbul ignore if */
if (typeof window! = ='undefined' && window.Vue) {
  install(window.Vue);
}

export default {
  version: '2.7.0'.locale: locale.use,
  i18n: locale.i18n,
  install,
  CollapseTransition,
  Loading,
  Pagination,
  / /... Most components are omitted here
  TimelineItem
};
Copy the code

If there are many components in the development process, you are advised to use scripts to automatically generate build entry files.

npm run lint

Use the Lint script to esLint the build source files before the build:

"lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet".Copy the code

Element has strict control over ESLint. If ESLint reports an error, the execution of the dist overall build script stops and the overall build fails. Eslint validation can be handled using the ESlint-Loader (you can also build if you want esLint validation to fail). See Errors and Warning.

webpack --config build/webpack.conf.js

The webpack –config build/webpack.conf.js script is used to build the umd total file. The execution of this script will eventually generate the index.js file under lib:

Lib ├── index.js # UmdCopy the code

The webpack.conf.js configuration is as follows:

// build/webpack.conf.js

/ /... ignore

module.exports = {
  mode: 'production'.// Specify the entry file SRC /index.js, which is automatically generated by the 'build:file' script
  entry: {
    app: ['./src/index.js']},output: {
    // Generate it in the lib file
    path: path.resolve(process.cwd(), './lib'),
    / / lib/generated index. Js
    filename: 'index.js'.// Generate the UMD module
    libraryTarget: 'umd'.// SRC /index.js files are thrown using the export default syntax, so you need to set libraryExport
    // Otherwise, the introduced UI component library needs to use.default to reference the thrown object
    // if your entry has a default export of `MyDefaultModule`
    // var MyDefaultModule = _entry_return_.default;
    // This is a bit of a pit, so the problem with not configuring is that the introduced UI component library cannot be deconstructed
    libraryExport: 'default',},resolve: {
    extensions: ['.js'.'.vue'.'.json'].// 'element-ui': path.resolve(__dirname, '.. / ')
	// The alias' elements-ui 'is thrown as an NPM package and points to the NPM package path of the business item node_modules
    alias: config.alias
  },
  externals: {
    // Build only excludes vue
    // The UMD module is introduced as a CDN, so all components, utils, i18n, etc. are built in
    // The UMD module has no on-demand import function
    vue: config.vue
  },
  / /... ignore
};
Copy the code

The main function of the build file lib/index.js is to introduce projects in the form of CDN, and it cannot be loaded on demand, resulting in a very large volume, which may not be suitable for simple applications.

webpack --config build/webpack.common.js

Webpack –config build/webpack.common.js script is used to build the commonJs2 total file, and execution of this script will eventually generate the element-ui.mon.js file under lib:

Lib ├─ Element-ui.com/mon.js # CommonJs2 Total fileCopy the code

Since this file needs to be built again at the business level using Webpack, there are many aspects to consider. Before analyzing the Webpack configuration, let’s review what Element can do for us:

  • 1, full import (throws the total commonjs2 file)
  • 2. Import on demand (throw all COMMONJs2 UI components)
  • 3. Support for internationalization (CommonJs2)
  • 4, provideutilsMethod (commonJs2, not officially)

The webpack –config build/webpack.mon.js script is used to build the full import function, and in order to throw the import on demand, support internationalization and other functions at the business level, Building element-ui.mon.js requires the exclusion of the UI components, the source code that supports internationalization, and the Utils method.

The configuration of webpack.mon.js is as follows:

// build/webpack.common.js

/ /... ignore

module.exports = {
  mode: 'production'.entry: {
    app: ['./src/index.js']},output: {
    path: path.resolve(process.cwd(), './lib'),
    publicPath: '/dist/'.filename: 'element-ui.common.js'.chunkFilename: '[id].js'.libraryExport: 'default'.library: 'ELEMENT'.// Generate the CommonJs2 module
    libraryTarget: 'commonjs2'
  },
  resolve: {
    extensions: ['.js'.'.vue'.'.json'].// 'element-ui': path.resolve(__dirname, '.. / ')
    alias: config.alias,
    modules: ['node_modules']},// Here is the source code that excludes UI components, supports internationalization, and uses the utils method, which requires additional scripting to build
  externals: config.externals,
  optimization: {
    // commonjs2 does not require compression
    minimize: false
  },
  / /... ignore
};
Copy the code

The important thing to look at is the config.externals attribute, which prints out the value of the variable:

[{ 
  vue: 'vue'.// Exclude the source code for all UI components
  'element-ui/packages/option':'element-ui/lib/option'.// ...
  // Exclude internationalized source code
  'element-ui/src/locale': 'element-ui/lib/locale'.// Exclude the source code for the utils method
  'element-ui/src/utils/vue-popper': 'element-ui/lib/utils/vue-popper'.'element-ui/src/mixins/emitter': 'element-ui/lib/mixins/emitter'.'element-ui/src/transitions/collapse-transition': 'element-ui/lib/transitions/collapse-transition' 
  // ...
 },
 // var nodeExternals = require('webpack-node-externals');
 // nodeExternals()
 [Function]].Copy the code

The externals attribute removes certain dependencies from the output bundle. For example, if there are dependencies between components in the development state, element-ui/packages/option component is introduced in element-ui/packages/pagination:

pagecages/pagination/src/pagination.js

// Option is required for the pagination component
import ElOption from 'element-ui/packages/option';
// ...
Copy the code

After building the Webpack, we can see that the element-UI /packages/option component is not packaged in the Element-UI ui.mon.js, The introduction of it changed its path element – the UI/lib/option (introduced in implementing on-demand features. We use webpack — config build/webpack.com ponent. Construct the js script files).

// lib/element-ui.common.js
module.exports = require("element-ui/lib/option");
Copy the code

Therefore, the keys and values of the config.externals property listed above can exclude UI components, code that supports internationalization, utils method functionality.

The last value of the config.externals property is [Function], which is generated by webpack-nod-externals. Here’s what webpack-node-externals does:

Webpack allows you to define externals – modules that should not be bundled. When bundling with Webpack for the backend – you usually don’t want to bundle its node_modules dependencies. This library creates an externals function that ignores node_modules when bundling in Webpack.

For example, if you rely on a Deepmerge in the Elment component library development, you do not need to bundle that dependency into the Element-ui.mon.js bundle when you build Webpack. Instead, you add it to the Dependencies in the Element component library (published as an NPM package). This way installing an Element via NPM will also install its dependency Deepmerge, allowing element-ui.mon.js to introduce the dependency via require(“deepmerge”) without error.

Here’s a list of the code excluded from element-ui.common.js:

// Exclude the source code for utils (the source code will be built using the 'NPM run build:utils' script)
module.exports = require("element-ui/lib/utils/dom");
/ / exclude vue
module.exports = require("vue");
// Exclude internationalized source code (internationalized source code will be built with the 'NPM run build:utils' script)
module.exports = require("element-ui/lib/locale");
// Be aware of the JSX dependencies associated with Vue (Vue CLI3 system builds packages that also have a dependency on this functionality)
module.exports = require("babel-helper-vue-jsx-merge-props");
// Exclude other dependencies used by some Elment components
module.exports = require("throttle-debounce/throttle"); 
/ / out of the UI component source (UI component source code will pass ` webpack -- config build/webpack.com ponent. Js ` script build)
module.exports = require("element-ui/lib/option");
Copy the code

Note that The NPM package entry file published by Element is element-ui.mon.js, which can be viewed through the main field information in package.json.

webpack --config build/webpack.component.js

Webpack — config build/webpack.com ponent. Js scripts used to build commonjs2 UI components (provide on-demand introduced functions), Executing this script will eventually generate all the Element supported UI components under lib (and these files will also be referenced by the Element-UI.mon.js general entry file) :

Lib ├ ─ ─ alert. Js # commonjs module ├ ─ ─ value. The js ├ ─ ─ button. The js ├ ─ ─...Copy the code

See build/webpack.com ponent. Js configuration:


/ /... ignore
const Components = require('.. /components.json');

// Components is a list of build entries for all Components
/ / {
// "pagination": "./packages/pagination/index.js",
/ /...
// "timeline-item": "./packages/timeline-item/index.js"
// }


const webpackConfig = {
  mode: 'production'./ / entrance
  entry: Components,
  output: {
    path: path.resolve(process.cwd(), './lib'),
    publicPath: '/dist/'.filename: '[name].js'.chunkFilename: '[id].js'.libraryTarget: 'commonjs2'
  },
  resolve: {
    extensions: ['.js'.'.vue'.'.json'].alias: config.alias,
    modules: ['node_modules']},// Exclude other UI components, internationalized, utils source code, which will be built as an extra
  externals: config.externals,
  },
  / /... ignore
};
Copy the code

The Webpack configuration for building a single component is similar to that for building the overall entry file, element-UI.mon.js, excluding utils, locals, and other dependencies.

npm run build:utils

The build:utils script is used to build commonJS utils (providing internationalization and utils functionality) :

"build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js".Copy the code

You can see that this command is not a multi-file build with Webpack, but a direct escape with Babel (Webpack builds generate extra Webpack code and are cumbersome to configure, but Babel escape builds are very clean). Escape all files in the SRC directory except the Webpack build entry file SRC /index.js. Executing this script will eventually generate all the utils files under lib:

Lib ├── Directives # Commonjs locale # CommonJS Internationalization API and language pack ├─ Mixins # CommonJS Mix with ── Transitions # CommonJS -Utils # CommonJsCopy the code

The generated tool methods will be referenced by the Element-ui.mon.js and various components under lib, and can also be referenced at the business level. Babelrc file configuration information:

{
  "presets": [["env",
      {
        "loose": true."modules": false."targets": {
          "browsers": ["1%" >."last 2 versions"."not ie <= 8"]}}],"stage-2"]."plugins": ["transform-vue-jsx"]."env": {
    // cross-env BABEL_ENV=utils
    "utils": {
      "presets": [["env",
          {
            // Loose mode, more like human handwriting ES5 code
            "loose": true.// es6 to commonjs
            "modules": "commonjs"."targets": {
              "browsers": ["1%" >."last 2 versions"."not ie <= 8"]}}],],"plugins": [["module-resolver", {
          "root": ["element-ui"]."alias": {
           // Externals function similar to Webpack
           // Change the import path of source code to the import path of object code
            "element-ui/src": "element-ui/lib"}}}]],"test": {
      "plugins": ["istanbul"]}}}Copy the code

The source code of the utils file is referenced to each other by element-ui/ SRC, and to each other by escaping to object code by element-ui/lib, so you need a function like the Externals of Webpack to change the reference path of object code. Babel-plugin-module-resolver implements this function when Babel escapes.

npm run build:theme

The build: Theme script is used to build CSS styles for UI components:

"build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib  lib/theme-chalk".Copy the code

The gulp build — gulpFile Packages /theme- Chalk /gulpfile.js script uses the Gulp build tool to build CSS style files. Finally, the content in the packages/ theme-Chalk /lib directory built currently is copied to the lib/ theme-Chalk directory for external services:

Lib ├ ─ ─ the theme - chalk # CSS style file │ ├ ─ ─ fonts # ICONS │ ├ ─ ─ alert. The introduction of CSS # on-demand component style │ ├ ─ ─... │ ├ ─ index.css │ ├ ─ index.cssCopy the code

View the gulpfile.js file:

'use strict';

const { series, src, dest } = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

function compile() {
  return src('./src/*.scss')
    // Convert sass to CSS
    .pipe(sass.sync())
    // Parse CSS and add vendor prefixes to rules by Can I Use 
    // CSS browser compatibility processing
    .pipe(autoprefixer({
      browsers: ['ie > 9'.'last 2 versions'].cascade: false
    }))
    / / compress CSS
    .pipe(cssmin())
    .pipe(dest('./lib'));
}

function copyfont() {
  return src('./src/fonts/**')
    .pipe(cssmin())
    .pipe(dest('./lib/fonts'));
}

exports.build = series(compile, copyfont);
Copy the code

Vue CLI 3 & Lerna

There are a lot of scripts that build the entire Element library, and the code that is built is referenced to each other, which imposes constraints on the development reference path. Therefore, designing a UI framework similar to Element requires a certain threshold of development for developers.

Here is a UI framework based on Vue CLI 3’s development/build objectives/library capabilities and Lerna tools. This UI framework integrates the following features:

  • 1. Structural features: Each UI component is an NPM package. Multiple languages, tools and styles are self-contained NPM packages that can be flexibly referenced by business or UI components and naturally loaded on demand.
  • 2. Configuration features: If build processing is required, each NPM package can be configured separately to make configuration easier. Combined with Vue CLI3’s component library capabilities, it is almost possible to build simple UI components with webPack zero configuration, except for a special WebPack Loader.
  • 3,Release characteristics: Component libraries can iterate faster, do not require a whole build, and each component can be released quickly on its ownPATCHorMINORVersion.

It is set that the business layer requires WebPack build processing, so the components of the UI framework can not be built, except if the UI component design requires special WebPack Loader processing, otherwise the business layer needs to do additional WebPack configuration. Of course, not building processing is relative to certain usage scenarios, and not building processing may also create additional problems.

The UI framework design also has some drawbacks:

  • 1. Not fully introduced functionality (you can build it as a whole, but not recommended here)
  • 2. UMD module is not provided
  • 3. Tedious introduction at the business level (additional introduction tools can be provided to simplify the introduction of UI components in the business)

Vue CLI 3

Construction of the library

In order to simplify the Webpack configuration of the UI framework, Vue CLI 3 is introduced here as a container for development, and the build library functionality of Vue CLI 3 (it would be more appropriate to build web-Components-component functionality, which is not verified here) allows for almost zero configuration of UI component building. By reviewing the -webpack-configuration capabilities of the project, you can see the generic WebPack configuration that Vue CLI 3 pre-set for us (which is sufficient for almost most UI component builds).

The plug-in system

Here, several Preset plug-ins are developed using Vue CLI 3 and Preset function, so as to quickly build the STARTING UI design framework, the specific Preset. Json configuration is as follows:

{
  "useConfigFiles": true."router": true."routerHistoryMode": true."vuex": false."cssPreprocessor": "less"."plugins": {
    "@vue/cli-plugin-babel": {},
    "@vue/cli-plugin-eslint": {
      "lintOn": ["save"."commit"]},"@ziyi2/vue-cli-plugin-ui-base": {},
    "@ziyi2/vue-cli-plugin-ui-cz": {},
    "@ziyi2/vue-cli-plugin-ui-lint": {}}}Copy the code

Here we take the official @vue/cli-plugin-babel and @vue/ cli-plugin-esLint plugins and design three additional plugins to support the whole new UI framework to get started:

  • @ziyi2/vue-cli-plugin-ui-base: UI framework base plug-in, generate source directory of Monorepo structure (add Lerna management tool), generate basic common Webpack configuration (reconfigure on VUE CLI3 webpack configuration, VUE CLI3 providesvue.config.jsFile for developers to reconfigure webPack), provides examples of several basic UI components (for reference only).
  • @ziyi2/vue-cli-plugin-ui-cz: UI frameworkczThe adapter plug-in is addedcz-customizable,commitlint,conventional-changelogTo generate Angular specification Git commit notes, check for specification compliance, and automatically generate UI framework update logs.
  • @ziyi2/vue-cli-plugin-ui-lint: UI frameworklint-stagedPlugin – Eslint checks the code before it is submitted, failing which code will not be submitted.

These three plug-ins have been published in the NPM repository. If you are an existing Vue CLI 3 project, you can use the Vue add@ziyi2 /ui-cz command to install the plugins directly. If you want to learn how to design Vue CLI 3 plug-ins, you can refer to the Plug-in Development Guide. However, the official documentation may not be detailed enough.

Lerna

Lerna is a Monorepo management tool that integrates all component (NPM package) designs into a Git repository. It also uses the Workspace feature of YARN to simulate the distributed component environment, making component development and testing easy. There is no need to do multiple release tests of components (Lerna is also very handy here for Vue CLI plug-in development).

At the same time, Lerna also integrates version release tool, which can quickly release the UI framework.

UI components can fix problems or add new functions to quickly release PATCH and MINOR versions respectively. If there is an overall incompatibility update of UI components, Lerna can be used to release MAJOR versions. For more information about version release specifications, see the semantic version.

UI Framework Practices

Using the remote Preset of Vue CLI 3, the UI framework designed by myself is shared with you for practical use:

// It may be a little slow to get, so wait patiently
vue create --preset ziyi2/vue-cli3-lerna-ui my-project --packageManager yarn
Copy the code

If the error is “unable to get local issuer certificate”, you can set git config –global http.sslVerify false.

If the remote retrieval of preset. Json fails, copy the preset. Json configuration locally and put it in the newly created PRESET.

vue create --preset ziyi2/vue-cli3-lerna-ui my-project --packageManager yarn
Copy the code

The generation process is as follows:

The script command

// Start the development service
"serve": "vue-cli-service serve".// Generate static resources
"build": "vue-cli-service build"./ / Eslint check
"lint": "vue-cli-service lint".// Install and link Lerna repo dependencies
"bootstrap": "lerna bootstrap".// Update the upgrade log
"cz:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md"./ / build
"lib": "lerna run lib"
Copy the code

To use GitHub Pages to publish static resources, add the “deploy”: “NPM run build && gh-pages -d dist” command to install the GH-page dependency.

Start the

Go to the project directory and run the yarn serve command to start the development view

Examples of UI design for internationalization, selectors, warnings, and buttons are given here.

build

After running lerna run lib (builds can be checked with NPM Run Lint, if not, the build will fail), lerna will run the lib script for each NPM package:

The utils, BTN, and Theme packages are built, with BTN using the Vue CLI 3 default build library configuration.

Monorepo structure

The Monorepo structure after the UI framework is generated and built is as follows:

.├ ── packages # workspaces │ ├── alert # │ ├─ Exercises │ ├── alert.vue #.exercises │ ├── index.js #.exercises │ ├─.exercises Package. Json # NPM package description file │ ├ ─ ─ BTN # button │ │ ├ ─ ─ lib # target file │ │ │ └ ─ ─ lib.com mon. Js # NPM package entry documents │ │ ├ ─ ─ BTN. Vue # component source │ │ │ ├── index.js │ ├── index.js │ ├── index.js │ ├── index.js │ ├── index.js │ ├── index.js │ ├── index.js │ ├── index.js │ │ ├ ─ ─ lang # language pack │ │ │ ├ ─ ─ enjs # English │ │ │ └ ─ ─ zh_CN. Js # Chinese │ │ ├ ─ ─ mixins # each component calls internationalization API │ │ ├ ─ ─ the SRC # source │ │ ├ ─ ─ Index. Js # NPM package entry documents │ │ ├ ─ ─ alert. The vue # component source │ │ ├ ─ ─ index. The js # NPM package entry documents │ │ └ ─ ─ package. The json # NPM package description file │ ├ ─ ─ the select # Selector (similar to alert) │ ├ ─ ─ the theme style # │ │ ├ ─ ─ lib # target file │ │ │ ├ ─ ─ alert. The CSS style # warning │ │ │ ├ ─ ─ BTN. CSS # button style │ │ │ ├ ─ ─ │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─ index.htm │ ├─ ├─.htm │ ├─ ├─.htm │ ├─ ├─.htm │ ├─ ├─.htm │ ├─ ├─.htm ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├─ exercises │ ├── library.htm │ ├── library.htm │ ├── library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm │ ├─ library.htm ├──.browserslistrc # UI Framework Target browser Configuration ├──.cz-config.js # Cz Custom commit instructions configuration ├─.gitignore # Git Ignored Configuration ├─.lintstagedrc # Lint-config.js # Vue CLI Babel Configuration Exercises ── lerna. Json # Package. json # Vue CLI Container description file (container is not NPM package) ├── postcsS.config.js # Exercises ├── readme.md # Exercises ├─ vue.common.jsCopy the code

The SRC file can be selected according to the development needs:

  • 1. Use the defaultCLI serviceFor development and UI framework Demo, here the UI framework is native.vueFile format Demo, if you want to use.mdFile for demonstration, can be usedvue-markdown-loader.
  • 2. Use VuePress, a Vue driven static website generator, which is not very stable at the moment.

release

The release can be done as a semantic version:

  • 1, the respective NPM package can be usednpm publishThe rapid release ofMINORandPATCHVersion.
  • 2. If an NPM package has an incompatible update, you can use itlerna publishreleaseMAJORVersion.

It is recommended to release NPM packages using Lerna tool in the form of Scope. The UI framework example is not provided with Demo. If you want to release NPM packages in the form of Scope, you can check ziyi2/ Wue-cli3-Lerna-UI. For details, see the publishConfig field in vue-cli3-lerna-ui/plugins/vue-cli-plugin-ui-base/package.json.

If the LERna publish fails (for example, a 403 error is reported), run the lerna publish from-package command to publish the data. For details, see lerna /publish/usage.

conclusion

Compared with Element’s UI framework design, the form of Vue CLI 3 & Lerna can simplify the configuration of UI framework and make the construction configuration of each UI component independent of each other. For simple UI components, the default Webpack configuration of Vue CLI 3 can be used. At the same time, the design structure of Monorepo (Why is Babel a Monorepo? Together with Lerna tools, you can make the UI framework more responsive to fixing problems and releasing new features faster.

The Github address of the Generated UI Framework practice project is Ziyi2 / Vue-cli3-Lerna-UI, including PRESET. Json, my designed Vue CLI plug-in and a set of UI components (slightly different from the generated UI framework example), If you think the overall structure is unreasonable or the consideration is not comprehensive enough, you are welcome to raise an issue, so that I can improve it. If you are interested, I hope you can Star, thank you here!

Refer to the link

  • Element – github
  • NPM Scripts User Guide – Yifeng Ruan
  • umd – github
  • Element Official Document
  • Eslint – ESLint documentation
  • Module Definition Systems – Webpack documentation
  • eslint-loader – github
  • webpack-node-externals – github
  • Externals – Webpack documentation
  • babel-plugin-module-resolver – github
  • Gulp – Gulp document
  • Vue CLI 3/ Development/Build target/library – Vue CLI documentation
  • Vue CLI 3/ development/WebPack-related/review project WebPack configuration – Vue CLI documentation
  • Vue CLI 3/ Base/plug-in and Preset – Vue CLI documentation
  • @vue/cli-plugin-babel – Vue CLI Plugin
  • @vue/cli-plugin-eslint – Vue CLI Plugin
  • Cz-git commit description tool
  • Z-customizable – CZ adapter, custom description
  • Commitlint-cz adapter, commitlint-cz adapter, commitlint-Cz adapter
  • Conventional – Changelog-CZ adapter to generate logs
  • Lint-passage – Code submission auditing tool
  • Plug-in Development Guide – Vue CLI documentation
  • Semantic versioning – Versioning specification
  • Vue CLI3/ Basic /CLI Services – Vue CLI documentation
  • Why is Babel a monorepo?