美文网首页
七、组件库的打包

七、组件库的打包

作者: _未完待续 | 来源:发表于2024-09-28 08:33 被阅读0次

概述

  • 把开发完的组件库进行打包操作;
  • 在根目录下,定义打包命令,过滤出子包,去执行不同子包下的命令;
  • 使用 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
        },
      },
    },
  },
})

相关文章

  • 2018-06-17

    基于rollup的组件库打包体积优化 背景 前段时间对公司内部的组件库(类似element-ui)做了打包体积优化...

  • vue自定义组件库如何按需加载

    写好的组件库不要打包!不要打包!不要打包!直接引入源码在使用时把单个组件导入就行。打包了之后就没办法做到按需引入了

  • npm link

    npm 打包自己的组件库后,要修改组件库,怎么验证修改后的组件库被其他项目引用后达到了想要的效果? 这时可以使用n...

  • npm 打包组件库

    为了方便代码公用,打造简易组件库,下面写的教大家打包到发布,基于react 初始化项目 mkdir compone...

  • Vite打包组件库

    动机 去年使用vue3 + TSX封装组件,结果卡在了打包上,直到最近发现,vite提供了tsx的打包插件。 组件...

  • rollup 打包vue3组件库报错 'createElemen

    rollup 打包vue3组件库报错 'createElementVNode' is not exported b...

  • @ant-design/icons-vue按需引入icon

    正常引入icon组件库 此时打包npm run build icons组件占用的资源很多,但是我们用到的icon不...

  • npm打包组件库2

    .eslintrc .gitignore .npmignore README.md 这个可以自己yy CODE_...

  • 私有库组件化-组件更新步骤

    项目中用到pod私有库中,自定义的组件需更新的操作 从Git上clone组件代码到本地 更新组件代码,运行打包脚本...

  • webpack之打造Javascript类库

    最近有个需求,需要将组件库打包为类库,提供给各项目使用,并且不打包进项目中,优化各项目切换时的资源加载,但是又不想...

网友评论

      本文标题:七、组件库的打包

      本文链接:https://www.haomeiwen.com/subject/izzkrjtx.html