首页 > 社交 > 科普中国

Vue3组件库打包指南,一次生成esm、esm

常驻编辑 科普中国 2022-10-09 组件   语句   语法   样式   函数   插件   格式   文件   目录   指南   方法

本文为Varlet组件库源码主题阅读系列第二篇,读完本篇,你可以了解到如何将一个Vue3组件库打包成各种格式sci拜客生活常识网

上一篇里提到了启动服务前会先进行一下组件库的打包,运行的命令为:sci拜客生活常识网

varlet-cli compile

显然是varlet-cli提供的一个命令:sci拜客生活常识网

sci拜客生活常识网

处理函数为compile,接下来我们详细看一下这个函数都做了什么。sci拜客生活常识网

// varlet-cli/src/commands/compile.ts
export async function compile(cmd: { noUmd: boolean }) {
    process.env.NODE_ENV = 'compile'
    await removeDir()
    // ...
}

// varlet-cli/src/commands/compile.ts
export function removeDir() {
    // ES_DIR:varlet-ui/es
    // LIB_DIR:varlet-ui/lib
    // HL_DIR:varlet-ui/highlight
    // UMD_DIR:varlet-ui/umd
    return Promise.all([remove(ES_DIR), remove(LIB_DIR), remove(HL_DIR), remove(UMD_DIR)])
}

首先设置了一下当前的环境变量,然后清空相关的输出目录。sci拜客生活常识网

// varlet-cli/src/commands/compile.ts
export async function compile(cmd: { noUmd: boolean }) {
    // ...
    process.env.TARGET_MODULE = 'module'
    await runTask('module', compileModule)

    process.env.TARGET_MODULE = 'esm-bundle'
    await runTask('esm bundle', () => compileModule('esm-bundle'))

    process.env.TARGET_MODULE = 'commonjs'
    await runTask('commonjs', () => compileModule('commonjs'))

    process.env.TARGET_MODULE = 'umd'
    !cmd.noUmd && (await runTask('umd', () => compileModule('umd')))
}

接下来依次打包了四种类型的产物,方法都是同一个compileModule,这个方法后面会详细分析。sci拜客生活常识网

组件的基本组成

以Button组件为例看一下未打包前的组件结构:sci拜客生活常识网

sci拜客生活常识网

一个典型组件的构成主要是四个文件:sci拜客生活常识网

.less:样式sci拜客生活常识网

.vue:组件sci拜客生活常识网

index.ts:导出组件,提供组件注册方法sci拜客生活常识网

props.ts:组件的props定义sci拜客生活常识网

样式部分Varlet使用的是less语言,样式比较少的话会直接内联写到Vue单文件的style块中,否则会单独创建一个样式文件,比如图中的button.less,每个组件除了引入自己本身的样式外,还会引入一些基本样式、其他组件的样式:sci拜客生活常识网

sci拜客生活常识网

index.ts文件用来导出组件,提供组件的注册方法:sci拜客生活常识网

sci拜客生活常识网

props.ts文件用来声明组件的props类型:sci拜客生活常识网

sci拜客生活常识网

有的组件没有使用.vue,而是.tsx,也有些组件会存在其他文件,比如有些组件就还存在一个provide.ts文件,用于向子孙组件注入数据。sci拜客生活常识网

打包的整体流程

首先大致过一遍整体的打包流程,主要函数为compileModule:sci拜客生活常识网

// varlet-cli/src/compiler/compileModule.ts
export async function compileModule(modules: 'umd' | 'commonjs' | 'esm-bundle' | boolean = false) {
  if (modules === 'umd') {
    // 打包umd格式
    await compileUMD()
    return
  }

  if (modules === 'esm-bundle') {
    // 打包esm-bundle格式
    await compileESMBundle()
    return
  }
    
  // 打包commonjs和module格式
  // 打包前设置一下环境变量
  process.env.BABEL_MODULE = modules === 'commonjs' ? 'commonjs' : 'module'
  // 输出目录
  // ES_DIR:varlet-ui/es
  // LIB_DIR:varlet-ui/lib
  const dest = modules === 'commonjs' ? LIB_DIR : ES_DIR
  // SRC_DIR:varlet-ui/src,直接将组件的源码目录复制到输出目录
  await copy(SRC_DIR, dest)
  // 读取输出目录
  const moduleDir: string[] = await readdir(dest)
  // 遍历打包每个组件
  await Promise.all(
    // 遍历每个组件目录
    moduleDir.map((filename: string) => {
      const file: string = resolve(dest, filename)
      if (isDir(file)) {
        // 在每个组件目录下新建两个样式入口文件
        ensureFileSync(resolve(file, './style/index.js'))
        ensureFileSync(resolve(file, './style/less.js'))
      }
      // 打包组件
      return isDir(file) ? compileDir(file) : null
    })
  )
  // 遍历varlet-ui/src/目录,找出所有存在['index.vue', 'index.tsx', 'index.ts', 'index.jsx', 'index.js']这些文件之一的目录
  const publicDirs = await getPublicDirs()
  // 生成整体的入口文件
  await (modules === 'commonjs' ? compileCommonJSEntry(dest, publicDirs) : compileESEntry(dest, publicDirs))
}    

相关阅读:

  • iis如何安装(怎样安装iis组件)
  • 理解了状态管理,就理解了前端开发的核心​
  • Windows在中国失去了号召能力
  • 马化腾、曾毓群冲进这个全新赛道,三位清华校友刚刚拿下
  • C#开源之敏感词检测过滤组件
  • Deno
  • 前端开源之PDF在线浏览组件PDFObject.js
  • JavaGUI
  • 鸿蒙
  • Go
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。