generated from thzxcx/vue3
120 lines
3.4 KiB
TypeScript
120 lines
3.4 KiB
TypeScript
/*
|
|
* @Author: zhaojinfeng 121016171@qq.com
|
|
* @Date: 2023-06-19 16:41:12
|
|
* @LastEditors: zhaojinfeng 121016171@qq.com
|
|
* @LastEditTime: 2023-06-21 10:23:39
|
|
* @FilePath: \tianheng-design\bin\dts.ts
|
|
* @Description:
|
|
*
|
|
*/
|
|
/* eslint-env node */
|
|
import { dirname, resolve } from 'node:path'
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
import glob = require('fast-glob')
|
|
import consola from 'consola'
|
|
import { mkdir, readFile, writeFile } from 'fs-extra'
|
|
import { Project } from 'ts-morph'
|
|
import { compileScript, parse } from '@vue/compiler-sfc'
|
|
import type { SourceFile } from 'ts-morph'
|
|
|
|
let index = 1
|
|
|
|
const packageRoot = resolve(process.cwd(), 'es/packages')
|
|
const esRoot = resolve(process.cwd(), 'es')
|
|
|
|
async function writeDTS(sourceFiles: SourceFile[]) {
|
|
// 随后将解析完的文件写道打包路径
|
|
for (const sourceFile of sourceFiles) {
|
|
const emitOutput = sourceFile.getEmitOutput()
|
|
|
|
for (const outputFile of emitOutput.getOutputFiles()) {
|
|
const filePath = resolve(outputFile.getFilePath())
|
|
if (!filePath.endsWith('.d.ts') && !filePath.endsWith('index.js')) {
|
|
// 过滤非ts文件
|
|
continue
|
|
}
|
|
|
|
const newPath = filePath.replace(packageRoot, esRoot)
|
|
|
|
await mkdir(dirname(newPath), { recursive: true })
|
|
await writeFile(newPath, outputFile.getText(), 'utf8')
|
|
consola.success(newPath)
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
// 这部份内容具体能够查阅 ts-morph 的文档
|
|
// 这里仅须要知道这是用来处理 ts 文件并生成类型声明文件便可
|
|
const project = new Project({
|
|
compilerOptions: {
|
|
// composite: true,
|
|
// declaration: false,
|
|
// emitDeclarationOnly: true,
|
|
// noEmitOnError: true,
|
|
allowJs: true, // 若是想兼容 js 语法须要加上
|
|
outDir: 'es', // 能够设置自定义的打包文件夹,如 'types'
|
|
},
|
|
tsConfigFilePath: resolve(process.cwd(), './tsconfig.app.json'),
|
|
skipAddingFilesFromTsConfig: true,
|
|
})
|
|
|
|
// 获取 src 下的 .vue 和 .ts 文件
|
|
const files = await glob(['packages/**/*.ts', 'packages/**/*.vue'])
|
|
const sourceFiles: SourceFile[] = []
|
|
|
|
await Promise.all(
|
|
files.map(async (file) => {
|
|
if (!file.endsWith('.vue')) {
|
|
// 若是是 ts 文件则直接添加便可
|
|
sourceFiles.push(project.addSourceFileAtPath(file))
|
|
return
|
|
}
|
|
// 对于 vue 文件,借助 @vue/compiler-sfc 的 parse 进行解析
|
|
const sfc = parse(await readFile(file, 'utf-8'))
|
|
// 提取出 script 中的内容
|
|
const { script, scriptSetup } = sfc.descriptor
|
|
|
|
if (script || scriptSetup) {
|
|
let content = ''
|
|
let isTs = false
|
|
|
|
if (script?.content) {
|
|
content += script.content
|
|
|
|
if (script.lang === 'ts')
|
|
isTs = true
|
|
}
|
|
|
|
if (scriptSetup) {
|
|
const compiled = compileScript(sfc.descriptor, {
|
|
id: `${index++}`,
|
|
})
|
|
|
|
content += compiled.content
|
|
|
|
if (scriptSetup.lang === 'ts')
|
|
isTs = true
|
|
}
|
|
|
|
sourceFiles.push(
|
|
// 建立一个同路径的同名 ts/js 的映射文件
|
|
project.createSourceFile(file + (isTs ? '.ts' : '.js'), content),
|
|
)
|
|
}
|
|
}),
|
|
)
|
|
|
|
const diagnostics = project.getPreEmitDiagnostics()
|
|
|
|
// 输出解析过程当中的错误信息
|
|
consola.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
|
|
|
|
project.emitToMemory()
|
|
|
|
await writeDTS(sourceFiles)
|
|
}
|
|
|
|
main()
|