七、组件库的打包

概述

  • 把开发完的组件库进行打包操作;
  • 在根目录下,定义打包命令,过滤出子包,去执行不同子包下的命令;
  • 使用 cross-env 设置跨平台的环境变量;
  • 使用 npm-run-all 包下的 run-s 命令串行执行多个命令;
 "scripts": {
    "build": "run-s build-hooks build-comp",
    "build-hooks": "cross-env NODE_ENV=production pnpm --filter @lxx-ui/hooks build",
    "build-comp": "cross-env NODE_ENV=production pnpm --filter lxx-ui build",
  },
  • packages/core/package.json 中定义打包命令
  • run-p 并行打包,--config 设置配置文件,--watch 设置实时监听
"scripts": {
    "build": "run-p build-es build-umd",
    "build:watch": "run-p build-es:watch build-umd:watch",
    "build-umd": "vite build --config build/vite.umd.config.ts",
    "build-es": "vite build --config build/vite.es.config.ts",
    "build-umd:watch": "vite build --watch --config build/vite.umd.config.ts",
    "build-es:watch": "vite build --watch --config build/vite.es.config.ts",
  },
  • packages/core/build/vite.es.config.ts
import { defineConfig } from 'vite' // 导入配置的定义函数
import { resolve } from 'path' // 导入解析路径的方法
import { readdirSync, readdir } from 'fs' // 导入读取目录的方法
import { delay, defer, filter, map } from 'lodash-es' // 导入工具函数
import { visualizer } from 'rollup-plugin-visualizer' // 可视化分析依赖的模块

import vue from '@vitejs/plugin-vue' // 导入在vite中使用的vue插件
import dts from 'vite-plugin-dts' // 导入生成类型文件的插件
import shell from 'shelljs' // 脚本执行工具
import { hooksPlugin as hooks } from '@lxx-ui/vite-plugins' // 导入自定义的钩子函数
import terser from '@rollup/plugin-terser' // 压缩插件

const TRY_MOVE_STYLES_DELAY = 800 as const // 常量,延迟移动样式文件

const isProd = process.env.NODE_ENV === 'production' // 常量,是否是生产环境
const isDev = process.env.NODE_ENV === 'development' // 常量,是否是开发环境
const isTest = process.env.NODE_ENV === 'test' // 常量,是否是测试环境

// 获取给定目录下的目录集合
function getDirectoriesSync(basePath: string) {
  const entries = readdirSync(basePath, { withFileTypes: true })

  return map(
    filter(entries, (entry) => entry.isDirectory()),
    (entry) => entry.name
  )
}
// 移动目录
function moveStyles() {
  readdir('./dist/es/theme', (err) => {
    if (err) return delay(moveStyles, TRY_MOVE_STYLES_DELAY)
    defer(() => shell.mv('./dist/es/theme', './dist'))
  })
}

// 配置选项
export default defineConfig({
  plugins: [
    vue(),
    visualizer({
      filename: 'dist/stats.es.html',
    }),
    dts({
      tsconfigPath: '../../tsconfig.build.json',
      outDir: 'dist/types',
    }),
    hooks({
      rmFiles: ['./dist/es', './dist/theme', './dist/types'],
      afterBuild: moveStyles,
    }),
    terser({
      compress: {
        sequences: isProd,
        arguments: isProd,
        drop_console: isProd && ['log'],
        drop_debugger: isProd,
        passes: isProd ? 4 : 1,
        global_defs: {
          '@DEV': JSON.stringify(isDev),
          '@PROD': JSON.stringify(isProd),
          '@TEST': JSON.stringify(isTest),
        },
      },
      format: {
        semicolons: false,
        shorthand: isProd,
        braces: !isProd,
        beautify: !isProd,
        comments: !isProd,
      },
      mangle: {
        toplevel: isProd,
        eval: isProd,
        keep_classnames: isDev,
        keep_fnames: isDev,
      },
    }),
  ],
  build: {
    outDir: 'dist/es',
    minify: false,
    cssCodeSplit: true,
    lib: {
      entry: resolve(__dirname, '../index.ts'),
      name: 'ToyElement',
      fileName: 'index',
      formats: ['es'],
    },
    rollupOptions: {
      external: [
        'vue',
        '@fortawesome/fontawesome-svg-core',
        '@fortawesome/free-solid-svg-icons',
        '@fortawesome/vue-fontawesome',
        '@popperjs/core',
        'async-validator',
      ],
      output: {
        assetFileNames: (assetInfo) => {
          if (assetInfo.name === 'style.css') return 'index.css'
          if (
            assetInfo.type === 'asset' &&
            /\.(css)$/i.test(assetInfo.name as string)
          ) {
            return 'theme/[name].[ext]'
          }
          return assetInfo.name as string
        },
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return 'vendor'
          }
          if (id.includes('/packages/hooks')) {
            return 'hooks'
          }
          if (
            id.includes('/packages/utils') ||
            id.includes('plugin-vue:export-helper')
          ) {
            return 'utils'
          }
          for (const dirName of getDirectoriesSync('../components')) {
            if (id.includes(`/packages/components/${dirName}`)) {
              return dirName
            }
          }
        },
      },
    },
  },
})
  • packages/core/build/vite.umd.config.ts
import { defineConfig } from 'vite'
import { readFile } from 'fs'
import { resolve } from 'path'
import { delay, defer } from 'lodash-es'
import { compression } from 'vite-plugin-compression2'
import { visualizer } from 'rollup-plugin-visualizer'

import shell from 'shelljs'
import vue from '@vitejs/plugin-vue'
import { hooksPlugin as hooks } from '@lxx-ui/vite-plugins'
import terser from '@rollup/plugin-terser'

const TRY_MOVE_STYLES_DELAY = 800 as const

const isProd = process.env.NODE_ENV === 'production'
const isDev = process.env.NODE_ENV === 'development'
const isTest = process.env.NODE_ENV === 'test'
function moveStyles() {
  readFile('./dist/umd/index.css.gz', (err) => {
    if (err) return delay(moveStyles, TRY_MOVE_STYLES_DELAY)
    defer(() => shell.cp('./dist/umd/index.css', './dist/index.css'))
  })
}

export default defineConfig({
  plugins: [
    vue(),
    visualizer({
      filename: 'dist/stats.umd.html',
    }),
    compression({
      include: /.(cjs|css)$/i,
    }),
    terser({
      compress: {
        drop_console: ['log'],
        drop_debugger: true,
        passes: 3,
        global_defs: {
          '@DEV': JSON.stringify(isDev),
          '@PROD': JSON.stringify(isProd),
          '@TEST': JSON.stringify(isTest),
        },
      },
    }),
    hooks({
      rmFiles: ['./dist/umd', './dist/index.css'],
      afterBuild: moveStyles,
    }),
  ],
  build: {
    outDir: 'dist/umd',
    lib: {
      entry: resolve(__dirname, '../index.ts'),
      name: 'LxxUI',
      fileName: 'index',
      formats: ['umd'],
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        exports: 'named',
        globals: {
          vue: 'Vue',
        },
        assetFileNames: (assetInfo) => {
          if (assetInfo.name === 'style.css') return 'index.css'
          return assetInfo.name as string
        },
      },
    },
  },
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值