前言
上个章节我们主要是把基本的架子搭建了一下,这节我们主要写一个基础组件,然后用rollup来进行打包,我们一步步来,先打包组件,先讲如何打包组件
下载打包必要的依赖
rollup 这个就不用说了
@vitejs/plugin-vue 解析编译vue单文件组件(.vue文件)
rollup-plugin-esbuild 将 ESBuild 的功能集成到现有的 Rollup 项目中
@rollup/plugin-node-resolve 用于解析Node.js模块,代码中使用 require() 或 import 导入 Node.js 模块时,此插件会解析这些导入并找到对应的文件路径
@rollup/plugin-commonjs 是一个用于将 CommonJS 模块转换为 ES6 模块的 Rollup 插件
我们在internal/build目录下新建modules.ts来写逻辑,build结构如下
├── build
│ ├── package.json
│ └── src
│ ├── index.ts
│ └── tasks
│ ├── index.ts
│ └── modules.ts
在build 目录下执行 pnpm add rollup @vitejs/plugin-vue rollup-plugin-esbuild @rollup/plugin-node-resolve @rollup/plugin-commonjs 来安装这些必要插件。
创建一个基础组件并进行打包测试
在play中搭建项目,以用来引入测试
这里我没有仿element-puls,而是直接使用vite命令来快速搭建一个项目,因为本质上是为了在项目中测试我们写的组件代码,所以我没有去看ele里那套逻辑,就直接一键生成了
我们直接删掉play,在根下执行npm create vite@latest 然后选择Vue+TypeScript
创建组件libTable.vue
├── components
│ ├── index.ts
│ ├── package.json
│ └── table
│ ├── index.ts
│ └── src
│ └── libTable.vue
内容先简单写一点我们主要先测试打包
<script lang="ts" setup>
import {ref} from 'vue'
defineOptions({
name: 'libTable'
})
const nowValue = ref(0)
const add = () => {
nowValue.value++
}
</script>
<template>
<div>
当前值为{{nowValue}}
<button @click="add">点击+1</button>
</div>
</template>
import libTable from './src/libTable.vue'
export const LibTable = libTable
然后在play里的app.vue里先直接引入试了下,其实也可以安装依赖来测试,我这里就先粗暴引入。
<script setup lang="ts">
import {LibTable} from '../../packages/components'
</script>
<template>
<div>
<LibTable/>
</div>
</template>
这里亲测可以用,然后我们开始配rollup来打包这个组件,其实也可以直接打包,但是还是建议大家每次在play测试一下自己的组件,再打包,保证没问题
在modules.ts中配置rollup打包
在build下安装gulp+ @esbuild-kit/cjs-loader两个依赖,@esbuild-kit/cjs-loader 是esbuild 工具的一个加载器插件,用于在esbuild 中支持CommonJS 模块格式的加载,gulp装4版本,装5版本我执行esbuild-kit/cjs-loader会报错,我看ele是4,gulp换4版本确实可以成功。在根下装@types/gulp。打包配置如下
import { rollup } from 'rollup'
import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import esbuild from 'rollup-plugin-esbuild'
import commonjs from '@rollup/plugin-commonjs'
import glob from 'fast-glob'
import type { TaskFunction } from 'gulp'
import type { Plugin } from 'rollup'
//项目根目录
const projRoot = resolve(__dirname, '..', '..', '..','..')
//包目录
const pkgRoot = resolve(projRoot, 'packages')
//输出目录
const epOutput = resolve(projRoot,'dist')
//打包入口文件过滤
export const excludeFiles = (files: string[]) => {
const excludes = ['node_modules', 'mock', 'gulpfile', 'dist']
return files.filter(path => !excludes.some(exclude => path.includes(exclude)))
}
export const buildModules:TaskFunction = async () =>{
const input = excludeFiles(
await glob('**/*.{js,ts,vue}', {
cwd: pkgRoot,
absolute: true,
onlyFiles: true
})
)
const plugins: Plugin[] = [
nodeResolve({
extensions: ['.mjs', '.js', '.json', '.ts']
}),
esbuild(),
commonjs(),
vue()
]
const bundle = await rollup({
input,
plugins,
external: ['vue',/@vue/g] //这里我们先写死,因为我们组件目前比较简单
})
bundle.write({
format: 'esm', //输出的模块格式
dir: resolve(epOutput, 'es'), //输出的目录
preserveModules: true, //保持原模块的目录结构,而不是打包成一个文件
preserveModulesRoot: pkgRoot, //指定根目录,这里我们先指定我们的组件目录,
entryFileNames: `[name].mjs` //输出为 `.mjs`,name是入口
})
}
简单介绍gulp的任务
在gulp中,我们可以这样理解,每个task就是一个函数。
任务(tasks)可以是 public(公开) 或 private(私有) 类型的。
公开任务(Public tasks) 从 gulpfile 中被导出(export),可以通过 gulp 命令直接调用。
私有任务(Private tasks) 被设计为在内部使用,通常作为 series() 或 parallel() 组合的组成部分。
后面具体用到,我们再深入介绍,现在我们简单用下,想了解更多的可以去官网学习。
现在我们gulpfile.ts可以这样写
import { buildModules } from './src/index'
export default buildModules
我们把打包任务导出,然后在package.json里配置start命令
"start": "gulp --require @esbuild-kit/cjs-loader -f gulpfile.ts"
这样我们在build目录下,执行 pnpm run start 就可以执行打包命令。
执行,可以打包成功
打开打包出来的内容看下,理论上是没问题了。
写在最后
这节大概介绍了一下,打包的流程,里面有很多地址其实一开始是可以整合出来的,很多东西看起来比较糙,是因为我基于复现我当时自己学习的一个思路,从无到有,从有到优。欢迎大家批评指正