extractStyleDependencies方法前面已经介绍了,所以这一步的操作就是提取并去除script内的样式导入语句。
转换其他导入语句
// varlet-cli/src/compiler/compileScript.ts
export async function compileScript(script: string, file: string) {
// ...
code = replaceVueExt(code as string)
code = replaceTSXExt(code as string)
code = replaceJSXExt(code as string)
code = replaceTSExt(code as string)
// ...
}
这一步的操作是把script中的各种类型的导入语句都修改为导入.js文件,因为这些文件最后都会被编译成js文件,比如button/index.ts文件内导入了Button.vue组件:
import Button from './Button.vue'
// ...
转换后会变成:
import Button from './Button.js'
// ...
继续:
// varlet-cli/src/compiler/compileScript.ts
export async function compileScript(script: string, file: string) {
// ...
removeSync(file)
writeFileSync(replaceExt(file, '.js'), code, 'utf8')
}
最后就是把处理完的script内容写入文件。
到这里.vue,.ts、.tsx文件都已处理完毕:

小节
到这里,打包成module和commonjs格式就完成了,总结一下所做的事情:
- less文件直接使用less包编译成同名的css文件;
- ts、tsx等文件使用babel编译成js文件;提取并去除其中的样式导入语句,并将该样式导入语句写入单独的文件、修改.vue、.ts等类型的导入语句为对应的编译后的js;
- Vue单文件使用@vue/compiler-sfc解析并对各个块分别使用对应的函数进行编译;每个style块也会提取并去除其中的样式导入语句,并将该导入语句写入单独的文件,剩下的样式内容会分别创建一个对应的样式文件,如果是less块,同时会编译并创建一个同名的css文件;template的编译结果会合并到script内,然后script的内容会重复上一步ts文件的处理逻辑;
- 所有组件都编译完了,再动态创建整体的导出文件,一共生成了四个文件:

打包成esm-bundle
打包成esm-bundle格式调用的是compileESMBundle方法:
// varlet-cli/src/compiler/compileModule.ts
import { build } from 'vite'
export function compileESMBundle() {
return new Promise((resolve, reject) => {
const config = getESMBundleConfig(getVarletConfig())
build(config)
.then(() => resolve())
.catch(reject)
})
}
getVarletConfig方法会把varlet-cli/varlet.default.config.js和varlet-ui/varlet.config.js两个配置进行合并,看一下getESMBundleConfig方法:
// varlet-cli/src/config/vite.config.js
export function getESMBundleConfig(varletConfig: Record): InlineConfig {
const name = get(varletConfig, 'name')// name默认为Varlet
const fileName = `${kebabCase(name)}.esm.js`// 输出文件名,varlet.esm.js
return {
logLevel: 'silent',
build: {
emptyOutDir: true,// 清空输出目录
lib: {// 指定构建为库
name,// 库暴露的全局变量
formats: ['es'],// 构建格式
fileName: () => fileName,// 打包出口
entry: resolve(ES_DIR, 'umdIndex.js'),// 打包入口
},
rollupOptions: {// 传给rollup的配置
external: ['vue'],// 外部化处理不需要打包进库的依赖
output: {
dir: ES_DIR,// 输出目录,ES_DIR:varlet-ui/es
exports: 'named',// 既存在命名导出,也存在默认导出,所以设置为named,详情:https://rollupjs.org/guide/en/#outputexports
globals: {// 在umd构建模式下为外部化的依赖提供一个全局变量
vue: 'Vue',
},
},
},
},
plugins: [clear()],
}
}