Since I was employed in March this year, I have been working on background operation system, among which there are many repetitive tasks, including component library. Although there are many excellent open source component libraries available today, some components have to be implemented manually to accommodate the oddity of the product. Settle it down and accumulate something of your own.

Overview: A basic build tool for modifying a component library based on vue-CLI scaffolding, which has the following features:

  • Webpackage 3.0 Upgrade WebPackage 4.0 to better complete component development and packaging.
  • Support for SASS => accelerate component style development;
  • Support for markDown import, markDown style customization, and code highlighting;
  • Automatically configure routes.

Added on 25 December 2018

  • Highlight packs too much, reduces the language pack;
  • JSCPD checks for duplicate code.

Place the previous V-highlight directive

// This loads the highlight code language package, which is 300KB +
import hljs from 'highlight.js'
import 'highlight.js/styles/vs2015.css'

hljs.configure({ useBR: true })

Vue.directive('highlight'.function (el) {
    let blocks = el.querySelectorAll('code')

    blocks.forEach(block= > {
        hljs.highlightBlock(block)
    })
})
Copy the code

Modified to

import hljs from 'highlight.js/lib/highlight';
import 'highlight.js/styles/github.css'; // Import JavaScript from'highlight.js/lib/languages/javascript';
import xml from 'highlight.js/lib/languages/xml';

hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('xml', xml);
Vue.directive('highlight'.function (el) {
        let blocks = el.querySelectorAll('code')
        Array.prototype.forEach.call(blocks, block => {
        hljs.highlightBlock(block)
    })
})
Copy the code

Install JSCPD, NPM I –save-dev JSCPD, modify packjson.json

{... "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": NPM run dev, // add "check": "JSCPD SRC ", "build": "node build/build.js"},... }Copy the code

The results


Example 1.

Code address: UI-Library code

2. Installation process

Environment: WIN-64-bit, Node-V8.12.0

  • The installation

    npm install --global vue-cli

    Install vuE-CLI and create a UI-Library project

    vue init webpack ui-library

    In package.json of the project you created, the version of Webpack is 3.6.0

    "Webpack" : "^ 3.6.0," "webpack - bundle - analyzer" : "^ 2.9.0", "webpack - dev - server" : "^ 2.9.1", "webpack - merge" : "^ 4.1.0." "Copy the code

    To upgrade WebPack 4.1.2, first uninstall the current Webpack and its associated dependencies

    npm uninstall -D webpack webpack-bundle-analyzer webpack-dev-server webpack-merge
    npm uninstall -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader  friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin vue-loader
    Copy the code

    Install WebPack 4, which depends on WebPack-CLI

    npm install -D webpack webpack-cli webpack-bundle-analyzer webpack-dev-server webpack-merge
    npm install -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader  friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin vue-loader
    Copy the code

    Replace extract-text-webpack-plugin plugin with NPM install -d for extract-text-webpack-plugin mini-css-extract-plugin

    Install sass dependency NPM install -d node-sass sass-loader –save-dev

  • configuration

    • First, configure the mode of webpack and add it to webpack.dev.conf.js and webpack.prod.conf.js respectively

      const devWebpackConfig = merge(baseWebpackConfig, {
          mode: 'production'. })Copy the code
      const webpackConfig = merge(baseWebpackConfig, {
          mode: 'development'. })Copy the code
    • Configure the webpack.base.conf.js file

      / / introduce VueLoaderPlugin
      const { VueLoaderPlugin } = require('vue-loader')
      / / add to
      const devWebpackConfig = merge(baseWebpackConfig, {
          ...
          plugins: [
              new VueLoaderPlugin(),
              ...
          ]
      })
      Copy the code
    • Configure the webpack.prod.conf.js file

      You need to remove

      const ExtractTextPlugin = require('extract-text-webpack-plugin')

      const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

      Then configure the config item

      const ExtractTextPlugin = require('extract-text-webpack-plugin')
      const { VueLoaderPlugin } = require('vue-loader')
      
      const webpackConfig = merge(baseWebpackConfig, {
          optimization: {
              splitChunks: {
                cacheGroups: {
                  vendors: {
                    test: /[\\/]node_modules[\\/]/.chunks: 'initial'.name: 'vendors',},'async-vendors': {
                    test: /[\\/]node_modules[\\/]/.minChunks: 2.chunks: 'async'.name: 'async-vendors'}}},runtimeChunk: { name: 'runtime'}},plugins: [
              / / add VueLoaderPlugin
              new VueLoaderPlugin(),
              ...
              / / introduce MiniCssExtractPlugin
              new MiniCssExtractPlugin({
                filename: utils.assetsPath('css/[name].[contenthash:7].css')}),// Compress extracted CSS. We are using this plugin so that possible
              // duplicated CSS from different components can be deduped.
              new OptimizeCSSPlugin({
                cssProcessorOptions: config.build.productionSourceMap
                  ? { safe: true.map: { inline: false}}, {safe: true}}),// see https://github.com/ampedandwired/html-webpack-plugin
              new HtmlWebpackPlugin({
                filename: config.build.index,
                template: 'index.html'.inject: true.minify: {
                  removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true
                  // more options:
                  // https://github.com/kangax/html-minifier#options-quick-reference
                },
                // necessary to consistently work with multiple chunks via CommonsChunkPlugin
                chunksSortMode: 'dependency'
              }),
              // keep module.id stable when vendor modules does not change
              new webpack.HashedModuleIdsPlugin(),
              // copy custom static assets
              new CopyWebpackPlugin([
                {
                  from: path.resolve(__dirname, '.. /static'),
                  to: config.build.assetsSubDirectory,
                  ignore: ['*']}])]Copy the code
    • Modify the utils. Js

      exports.cssLoaders = function(options) {
          options = options || {}
      
          // generate loader string to be used with extract text plugin
          function generateLoaders(loader, loaderOptions) {
              let loaders = []
              if (loader) {
                  loaders = [{
                      loader: loader + '-loader'.options: Object.assign({}, loaderOptions, {
                          sourceMap: options.sourceMap
                      })
                  }]
              }
      
              if (options.extract) {
                  let extractLoader = {
                      loader: MiniCssExtractPlugin.loader,
                      options: {}}return [extractLoader, 'css-loader'].concat(['postcss-loader'], loaders)
              } else {
      
                  return ['vue-style-loader'.'css-loader'].concat(['postcss-loader'], loaders)
              }
          }
      
          return {
              css: generateLoaders(),
              postcss: generateLoaders(),
              less: generateLoaders('less'),
              sass: generateLoaders('sass', { indentedSyntax: true }),
              scss: generateLoaders('sass'),
              stylus: generateLoaders('stylus'),
              styl: generateLoaders('stylus')}}Copy the code
    • Introduce sass-Resources-loader to handle public CSS files

      npm install -D sass-resources-loader --save-dev

      Change the value of return to

      {... scss: generateLoaders('sass').concat({
              loader: 'sass-resources-loader'.options: {
                  resources: path.resolve(__dirname, '.. /src/assets/styles/common.scss')}})... }Copy the code

3. Support markDown import and markDown style customization

Because vue-Markdown-loader is incompatible with vue-Loader version 15, the text loader is used to import the Markdown document, generate String, and compile it into markdown document.

NPM install -d text-loader: NPM install -d text-loader: NPM install -d text-loader: NPM install -d text-loader: NPM

rules: [
    ...(config.dev.useEslint ? [createLintingRule()] : []),
    {
        test: /.md$/.loader: 'text-loader'},... ]Copy the code

Compile the imported String in marked

<template> <div class="markdown-body" v-html="compiledMarkdown" v-highlight></div> </template> import markdown from '.. /.. /README.md' import marked from 'marked' export default { computed: Markdown return marked(markdown)}}}Copy the code

If the markDown style is a little ugly, you can import github-markdown-CSS

npm install -D github-markdown-css

Modify the style. If some code exists in markdown, it can be highlighted with Highlight

npm install -D highlight

import hljs from 'highlight.js'
// Adjust the style of the highlighted code
import 'highlight.js/styles/vs2015.css'

hljs.configure({ useBR: true })
// Register a directive to add code highlighting
Vue.directive('highlight'.function (el) {
    let blocks = el.querySelectorAll('code')

    blocks.forEach(block= > {
        hljs.highlightBlock(block)
    })
})
Copy the code

4. Automatically configure routes

Use require.context to parse a file in a directory to generate a Router configuration

const context = require.context('@/components/'.true, /demo\.vue$/)
const componentRouters = context.keys().map(url= > {
    const start = url.indexOf('/')
    const end = url.lastIndexOf('/')
    const name = url.substring(start + 1, end)
    const path = ` /${name}`
    
    return {
        name,
        path,
        component: require(`@/components${path}/demo`).default
    }
})

export default new Router({
    routes: [{path: '/'.name: 'mainPage'.component: mainPage }, ... componentRouters ] } )Copy the code

Previous articles:

  • Component library for Vue from zero (zero) – basic structure and build tools
  • From zero implementation Vue component library (I) – Toast implementation
  • Implementation from zero Vue component library (ii) – Slider implementation
  • From zero Vue component library (iii) – Tabs implementation
  • Vue component library from zero (four) – file-reader implementation
  • Vue component library from zero (v) – Breadcrumb implementation
  • From zero to implement Vue component library (vi) – hover-tip implementation
  • Vue component library from zero (7) – message-box implementation
  • Implement Vue from zero component library (eight) – Input implementation
  • Implement Vue component library from zero (9) – InputNumber implementation
  • Implement Vue from zero component library (x) – Select implementation
  • Implement Vue component library from zero (eleven) – date-picker implementation
  • Vue component library from zero implementation (twelve) – Table implementation
  • Implement Vue from zero component library (xiII) – Pagination implementation
  • Implement Vue from zero component library (xiv) – RadioGroup implementation
  • Implement Vue from zero component library (XV) – CheckboxGroup implementation

Original statement: This article is an original article, please indicate the source.