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

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

内容简介:今年三月份入职以来,一直在做后台运营系统,其中重复性工作有很多,其中组件库就是一项。尽管现阶段有很多优秀的开源组件库,但是为了适应产品奇奇怪怪的需求,还是要手动实现一些组件。将其沉淀下来,积累一些自己东西。环境: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
        ]
    }
)
复制代码

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

查看所有标签

猜你喜欢:

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

内容算法

内容算法

闫泽华 / 中信出版社 / 2018-4-30 / 58.00元

近两年来,伴随着BAT纷纷涌入自媒体平台,自媒体发展可谓迎来爆发。自媒体平台火爆起来是从今日头条异军突起而引发的。它是一款基于数据挖掘的推荐引擎产品,为用户推荐有价值的、个性化的信息,是国内移动互联网领域成长最快的产品服务之一。推荐引擎也将迎来高速发展,针对推荐引擎的优化技术也将会迎来新的机遇。 本书作者从事推荐引擎相关的内容分发相关工作,在书中对内容推荐系统进行了介绍,书的最后,介绍了自媒......一起来看看 《内容算法》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码