从零实现Vue的组件库(零)-基本结构以及构建工具

栏目: CSS · 发布时间: 7年前

内容简介:今年三月份入职以来,一直在做后台运营系统,其中重复性工作有很多,其中组件库就是一项。尽管现阶段有很多优秀的开源组件库,但是为了适应产品奇奇怪怪的需求,还是要手动实现一些组件。将其沉淀下来,积累一些自己东西。环境:win-64位、node-v8.12.0由于

今年三月份入职以来,一直在做后台运营系统,其中重复性工作有很多,其中组件库就是一项。尽管现阶段有很多优秀的开源组件库,但是为了适应产品奇奇怪怪的需求,还是要手动实现一些组件。将其沉淀下来,积累一些自己东西。

概述:首先基于Vue-cli脚手架改装一个组件库的基本构建工具,它具备以下几点功能:

  • webpack3.0 升级 webpack4.0 => 更好地完成组件的开发以及打包工作;
  • 支持sass => 加速组件样式开发;
  • 支持导入markdown以及markdown样式自定义、以及code高亮;
  • 自动配置路由。

1. 实例

实例地址:[Fat-Ge UI library](http://fatge.xyz/blog/juejin-example-3#/)

代码地址:[UI-Library code](https://github.com/FatGe/UI-Library)
复制代码

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以及其相关依赖uninstall

    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

    安装sass相关依赖 npm install -D node-sass sass-loader --save-dev

  • 配置

    • 首先配置webpack的mode,在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')

      之后配置config项

      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')
          }
      }
      复制代码

3. 支持导入markdown以及markdown样式自定义

由于 vue-markdown-loader 与vue-loader版本15有兼容性的问题,所以利用 text-loader 将Markdown文档导入并生成String,再编译为markdown文档。

首先 npm install -D text-loader 安装text-loader,用来引入*.md文件,再修改webpack.base.conf.js文件,添加text-loader

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

在引入 marked 对导入的String进行编译

<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)
    }
  }
}
复制代码

觉得markdown的样式有些丑,可以导入 github-markdown-css

npm install -D github-markdown-css

对样式进行修改。如果markdown中存在着某些code,可以通过 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 解析某个目录下的文件,将其生成Router的配置

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
        ]
    }
)
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换