如何使用vue cli3 构建组件库的编译配置

2,142 阅读2分钟

在日常研发中,经常会遇到跨项目的通用样式组件,对于任何一家公司而言沉淀一套自己的UI库成本其实不高。这篇文章是关于如何最小成本利用vue-cli快速构建一套组件库的打包编译配置

我们需要打包输出什么

封装一个UI库同时支持按需引入,和全局引入,需要打包出以下文件

  1. 全局引入:一份CommonJS用于NPM
  2. 全局引入:一份UMD用于浏览器
  3. 全局引入:一份公用CSS
  4. 按需引入:按组件打包划分的CommonJS,CSS

如何使用cli打包

  1. cli可以做到什么: 使用命令vue-cli-service build --target lib --name myLib [entry]可以直接打包出CSS,UMD,CommonJS

  2. 总思路:cli满足了我们所有所需的输出打包文件类型,那么只需要配置一份input-output的打包字典。依次循环vue-cli打包即可拿到我们所需的所有文件。

  3. 具体做法

    • runjs循环执行cli打包命令
    • node进行文件控制:移动,复制,文件遍历等(从dist中拿出所需的放入lib对应文件夹)
    • chalk终端console样式控制
  4. demo示例

// cli.build.js

const { run } = require('runjs')
const chalk = require('chalk')
const libList = require('../lib-list.js')
const config = require('./config.js')
const { move, fsExistsSync } = require('./file-handle')
const { chalkConsole } = require('./utils')
const fs = require('fs')
const files = []
const emptyCss = []

function build ({ input, output } = {}, index, arr) {
  chalkConsole.building(index + 1, arr.length)
  run(
    `vue-cli-service build --target ${config.outputPath} --no-clean  --name ${output} --dest dist ${input}`
  )
  files.push(output)
}

// 1打包
let pkg = []
Object.keys(libList).forEach((moduleName) => {
  const { input, output } = libList[moduleName]
  pkg.push({ input, output })
})
pkg.forEach(build)

// 2 移动CommonJS,css重命名文件
fsExistsSync(config.outputPath) || fs.mkdirSync(config.outputPath)
fs.mkdirSync(config.styleOutputPath)
files.forEach((file) => {
  // 移动js
  let path = `dist/${file}.common.js`
  let target = `${config.outputPath}/${file}.js`
  fsExistsSync(path) && move(path, target)
  // 移动css
  path = `dist/${file}.css`
  target = file === 'eqx-ui.common' ? `${config.styleOutputPath}/index.css` : `${config.styleOutputPath}/${file}.css`
  if (!fsExistsSync(path)) {
    emptyCss.push(file)
  }
  fsExistsSync(path) && move(path, target)
})
// 3移动字体文件
fsExistsSync('dist/fonts') && move('dist/fonts', `${config.styleOutputPath}/fonts`)
// 用于给babel-plugin-component 按需加载
fsExistsSync('public/base.css') && fs.copyFile('public/base.css', `${config.styleOutputPath}/base.css`, function (_err) {})

chalkConsole.success()
console.warn(chalk.yellow(`没有css的模块:${emptyCss}`))

// lib-list.js input-output配置

const fs = require('fs')

function getComponents () {
  let arr = fs.readdirSync('./components')
  const ignore = ['scrollbar']
  const rule = new RegExp(/^[\._]/)
  arr = arr.filter(item => !ignore.includes(item) && !rule.test(item))
  return arr
}

function getOpt () {
  const components = getComponents()
  let opt = {}
  components.forEach(file => {
    opt[file] = {
      input: `components/${file}/index.js`,
      output: file
    }
  })
  return opt
}

module.exports = Object.assign({
  index: {
    input: 'index.js',
    output: 'eqx-ui.common'
  }
}, getOpt())

参考链接

  1. vue cli3构建文档
  2.  使用rollup | vue cli3(Webpack) 搭建属于自己的组件库,(按需加载,多入口打包...)