目标
在使用微应用中, 通常子应用都是基于一套技术栈开发。其中就包括ui组件,很多二次封装组件需要在各个子应用中使用到。
所以将这些公共组件独立出来,作为第三方库使用。需要注意的是,这里的ui库也是基于已有开源库的扩展,而非fork后的二次开发。
背景
技术栈 : antdv
TS
Vue3.0
目录
- root
- vue.config.js
- script 打包脚本
- gulpfile.js
- components 组件源文件
- src 测试用例
配置打包命令
vue-cli 已经提供了对于独立ui包的打包配置详情 , 这里我们使用了Ts
所以除了打包资源文件外,还需要生成对应的 file.d.ts 类型定义。 这部分需要我们自己动手生成, 参考 antdv
iview
我们使用 gulp
实现相关功能
// pakcage.json
{
// 新增打包命令
"script": {
// 统一构建任务
"build": "gulp -f ./script/gulpfile.js default",
// 类型生成
"types": "gulp -f ./script/gulpfile.js types",
// vue 打包命令
"lib": "vue-cli-service build --target lib --name zz-ui components/index.ts",
....
}
}
lib 命令 --traget lib 【指定构建目标为库】, --name zz-ui 【打包后的引入名称】 components/index.ts 【入口文件】
package.json 包信息配置
代码语言:javascript复制{
"name": "@micro/zz-ui", //包名
"version": "0.1.0", //版本
"main": "lib/zz-ui.umd.js", // 入口文件
"unpkg": "lib/zz-ui.umd.min.js", // 打包压缩版
"types": "lib/types/index.d.ts" // 类型定义入口
}
这里主要配置包的基础信息, 提供npm使用
gulpfile.js
代码语言:javascript复制const exec = require('child_process').exec;
const rimraf = require('rimraf');
const merge2 = require('merge2')
const gulp = require('gulp')
const ts = require('gulp-typescript')
const tsConfigBase = require('../tsconfig.json')
const tsDefaultReporter = ts.reporter.defaultReporter()
// 构建时,ts 配置
const tsconfig = {
noUnusedParameters: true,
noUnusedLocals: true,
strictNullChecks: true,
target: 'es6',
jsx: 'preserve',
moduleResolution: 'node',
declaration: true, // 生成类型定义
allowSyntheticDefaultImports: true,
...tsConfigBase.compilerOptions
}
// 清除上次打包文件
function clean (done){
rimraf.sync('../lib');
done()
}
// ts引入源
const TS_SOURCE = [
'../components/**/*.js',
'../components/**/*.jsx',
'../components/**/*.tsx',
'../components/**/*.ts',
'!components/*/__tests__/*',
]
function compileDTS(){
let error = 0
const tsResult = gulp.src(TS_SOURCE).pipe(
ts(tsconfig, {
error(e){
tsDefaultReporter.error(e)
error = 1
},
finish: tsDefaultReporter.finish,
})
)
function check() {
if (error && !argv['ignore-error']) {
process.exit(1)
}
}
tsResult.on('finish', check)
tsResult.on('end', check)
// 因为 vue-cli 构建配置已经包含了对ts文件的处理,所以这里只生成对应的类型文件
const tsd = tsResult.dts.pipe(gulp.dest('../lib/types'))
return merge2([
tsd
])
}
function buildLib(cb){
return exec(`yarn lib`, (err, stdout, stderr) => {
console.log('info: ', stdout)
console.error('error: ', stderr)
cb(err)
})
}
// 配置对应的命令任务
exports.types = gulp.series(compileDTS)
exports.buildLib = gulp.series(buildLib)
exports.default = gulp.series(clean, buildLib, compi
vue.config.js
构建业务组件时, 难免需要依赖其他第三方或自定义包,而这些包,可能已经包含在应用依赖中。所以打包时需要屏蔽相关依赖包。
代码语言:javascript复制module.exports = {
outputDir: 'lib',
productionSourceMap: false,
css:{
sourceMap: false
},
chainWebpack: conf => {
// 生产环境下屏蔽公共依赖
if(process.env.NODE_ENV === 'production') {
conf.externals({
vue: "vue",
'@micro/api': '@micro/api',
'@micro/utils': '@micro/utils',
'@micro/hooks': '@micro/hooks',
'ant-design-vue': 'ant-design-vue'
})
}
}
}
总结
这里只是使用vue-cli 的预设配置打包出自己的ui组件库, 使用gulp导出类型定义。
可以看到通过gulp我们可以分离 ts 编译文件 和 类型定义文件,只生产我们所需的目标文件。
除了生产 umd 模块外, 如需要提供ES6 模块, 我们需要自己配置相关打包处理,可以参考 antdv
官方的打包方案。