Базовая структура библиотеки компонентов библиотеки и инструменты сборки

Vue.js

С тех пор, как я присоединился к компании в марте этого года, я работаю над фоновой операционной системой, и у меня много повторяющихся задач, одной из которых является библиотека компонентов. Хотя на данном этапе существует множество отличных библиотек компонентов с открытым исходным кодом, чтобы удовлетворить странные потребности продукта, некоторые компоненты должны быть реализованы вручную. Успокойтесь и накопите что-то свое.

Обзор: Во-первых, на основе скаффолдинга Vue-cli изменен базовый инструмент построения библиотеки компонентов, который имеет следующие функции:

  • webpack3.0 обновить webpack4.0 => лучше завершить разработку и упаковку компонентов;
  • Поддержка sass => ускорение разработки стилей компонентов;
  • Поддержка импорта уценки и настройки стиля уценки, а также подсветка кода;
  • Маршрутизация настраивается автоматически.

Добавлено 25 декабря 2018 г.

  • Пакет выделения слишком велик, а языковой пакет уменьшен;
  • проверка дублирования кода jscpd.

предыдущийv-highlightинструкция

// 这样加载了highlight所有的代码语言包,有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)
    })
})

превратиться в

import hljs from 'highlight.js/lib/highlight';
import 'highlight.js/styles/github.css';
// 只加载Html、JavaScript
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)
    })
})

установить jscpd,npm i --save-dev jscpd, изменить packjson.json

{
  ....
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    // 添加
    "check": "jscpd src",
    "build": "node build/build.js"
  },
  ...
}

результат операции


1. Примеры

Кодовый адрес:UI-Library code

2. Процесс установки

Среда: win-64 бит, node-v8.12.0

  • Установить

    npm install --global vue-cli

    Установите vue-cli, затем создайте проект ui-library.

    vue init webpack ui-library

    В package.json созданного проекта версия webpack 3.6.0

    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
    

    Чтобы обновить webpack4.1.2, сначала удалите текущий webpack и связанные с ним зависимости.

    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
    

    Установите webpack4, так как webpack4 зависит от 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
    

    ручная заменаextract-text-webpack-pluginплагинnpm uninstall -D extract-text-webpack-pluginзаменитьnpm install -D mini-css-extract-plugin

    Установите зависимости, связанные с sassnpm install -D node-sass sass-loader --save-dev

  • настроить

    • Сначала настройте режим веб-пакета и добавьте его в webpack.dev.conf.js и webpack.prod.conf.js соответственно.

      const devWebpackConfig = merge(baseWebpackConfig, {
          mode: 'production',
          ...
      })
      
      const webpackConfig = merge(baseWebpackConfig, {
          mode: 'development',
          ...
      })
      
    • Настройте файл webpack.base.conf.js

      // 引入VueLoaderPlugin
      const { VueLoaderPlugin } = require('vue-loader')
      // 添加至
      const devWebpackConfig = merge(baseWebpackConfig, {
          ...
          plugins: [
              new VueLoaderPlugin(),
              ...
          ]
      })
      
    • Настройте файл webpack.prod.conf.js

      нужно удалить

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

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

      Затем настройте элемент конфигурации

      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: [
              // 添加VueLoaderPlugin
              new VueLoaderPlugin(),
              ...
              // 引入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: ['.*']
                }
              ])
          ]
      
    • Изменить 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')
          }
      }
      
    • представлятьsass-resources-loaderОбработка общедоступных файлов css

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

      изменить вышеуказанноеreturnценность

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

3. Поддержка уценки импорта и настройки стиля уценки

из-заvue-markdown-loaderСуществуют проблемы совместимости с vue-loader версии 15, поэтому используйтеtext-loaderИмпортируйте документ Markdown и создайте String, а затем скомпилируйте его в документ Markdown.

первыйnpm install -D text-loaderУстановите текстовый загрузчик для импорта файлов *.md, а затем измените файл webpack.base.conf.js, чтобы добавить текстовый загрузчик.

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

Во введении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: {
    markdowonText () {
      // 编译markdown
      return marked(markdown)
    }
  }
}

Я думаю, что стиль уценки немного уродлив, вы можете импортировать егоgithub-markdown-css

npm install -D github-markdown-css

Измените стиль. Если в уценке есть какой-то код, можно передатьhighlightЧтобы выделить

npm install -D highlight

import hljs from 'highlight.js'
// 调整高亮code的样式
import 'highlight.js/styles/vs2015.css'

hljs.configure({ useBR: true })
// 注册一个directive用来添加code高亮
Vue.directive('highlight',function (el) {
    let blocks = el.querySelectorAll('code')

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

4. Автоматически настраивать маршрутизацию

использоватьrequire.contextПроанализируйте файлы в каталоге и сгенерируйте конфигурацию маршрутизатора.

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
        ]
    }
)

Прошлые статьи:

Оригинальное заявление: Данная статья является оригинальной, при перепечатке просьба указывать источник.