其实就是使用如上的配置来调用Vite的build方法进行打包,可参考库模式,可以看到打包入口为前面打包module格式时生成的umdIndex.js文件。
因为Vite开发环境使用的是esbuild,生产环境打包使用的是rollup,所以想要深入玩转Vite,这几个东西都需要了解,包括各自的配置选项、插件开发等,还是不容易的。
打包完成后会在varlet-ui/es/目录下生成两个文件:

打包成umd格式
打包成umd格式调用的是compileUMD方法:
// varlet-cli/src/compiler/compileModule.ts
import { build } from 'vite'
export function compileUMD() {
return new Promise((resolve, reject) => {
const config = getUMDConfig(getVarletConfig())
build(config)
.then(() => resolve())
.catch(reject)
})
}
整体和打包esm-bundle是一样的,只不过获取的配置不一样:
// varlet-cli/src/config/vite.config.js
export function getUMDConfig(varletConfig: Record): InlineConfig {
const name = get(varletConfig, 'name')// name默认为Varlet
const fileName = `${kebabCase(name)}.js`// 将驼峰式转换成-连接
return {
logLevel: 'silent',
build: {
emptyOutDir: true,
lib: {
name,
formats: ['umd'],// 设置为umd
fileName: () => fileName,
entry: resolve(ES_DIR, 'umdIndex.js'),// ES_DIR:varlet-ui/es,打包入口
},
rollupOptions: {
external: ['vue'],
output: {
dir: UMD_DIR,// 输出目录,UMD_DIR:varlet-ui/umd
exports: 'named',
globals: {
vue: 'Vue',
},
},
},
},
// 使用了两个插件,作用如其名
plugins: [inlineCSS(fileName, UMD_DIR), clear()],
}
}
大部分配置是一样的,打包入口同样也是varlet-ui/es/umdIndex.js,打包结果会在varlet-ui/umd/目录下生成一个varlet.js文件,Varlet和其他组件库稍微有点不一样的地方是它把样式也都打包进了js文件,省去了使用时需要再额外引入样式文件的麻烦,这个操作是inlineCSS插件做的,这个插件也是Varlet自己编写的,代码也很简单:
// varlet-cli/src/config/vite.config.js
function inlineCSS(fileName: string, dir: string): PluginOption {
return {
name: 'varlet-inline-css-vite-plugin',// 插件名称
apply: 'build',// 设置插件只在构建时被调用
closeBundle() {// rollup钩子,打包完成后调用的钩子
const cssFile = resolve(dir, 'style.css')
if (!pathExistsSync(cssFile)) {
return
}
const jsFile = resolve(dir, fileName)
const cssCode = readFileSync(cssFile, 'utf-8')
const jsCode = readFileSync(jsFile, 'utf-8')
const injectCode = `;(function(){var style=document.createElement('style');style.type='text/css';
style.rel='stylesheet';style.appendChild(document.createTextNode(`${cssCode.replace(//g, '\')}`));
var head=document.querySelector('head');head.appendChild(style)})();`
// 将【动态将样式插入到页面】的代码插入到js代码内
writeFileSync(jsFile, `${injectCode}${jsCode}`)
// 将该样式文件复制到varlet-ui/lib/style.css文件里
copyFileSync(cssFile, resolve(LIB_DIR, 'style.css'))
// 删除样式文件
removeSync(cssFile)
},
}
}
这个插件所做的事情就是在打包完成后,读取生成的style.css文件,然后拼接一段js代码,这段代码会把样式动态插入到页面,然后把这段js合并到生成的js文件中,这样就不用自己手动引入样式文件了。
同时,也会把样式文件复制一份到lib目录下,也就是commonjs产物的目录。
最后再回顾一下这个打包顺序:

你会发现这个顺序是有原因的,ems-bundle的打包入口依赖module的产物,umd打包会给commonjs复制一份样式文件,所以打包umd需要在commonjs后面。