element-plus/build/types-definitions.ts
三咲智子 4e99d0b5ba
build!: simplify build & support esm import (#4018)
* build!: simplify build & support native esm import

* build: refactor build

* refactor: reorganize files

* refactor: refactor build

* build: improve perf

* fix: scripts

* build: add rollup-plugin-filesize

* chore: scripts ignore no-console

* build: disable tree-shaking

* build: improve code

* build: add sourcemap

* build: add banner

* refactor: remove annotation

* build!: improve esm exports (#3871)

* build: improve esm import

* refactor: change mjs for esm version

* chore: improve exports map

* fix: add sideEffects

* refactor: improve alias

* build: upgrade dependencies
2021-10-25 17:07:48 +08:00

126 lines
3.5 KiB
TypeScript

import path from 'path'
import fs from 'fs/promises'
import * as vueCompiler from '@vue/compiler-sfc'
import { Project } from 'ts-morph'
import glob from 'fast-glob'
import { bold } from 'chalk'
import { green, red, yellow } from './utils/log'
import { buildOutput, pkgRoot, projRoot } from './utils/paths'
import { excludeFiles, pathRewriter } from './utils/pkg'
import { run } from './utils/process'
import type { SourceFile } from 'ts-morph'
const TSCONFIG_PATH = path.resolve(projRoot, 'tsconfig.json')
const outDir = path.resolve(buildOutput, 'types')
/**
* fork = require( https://github.com/egoist/vue-dts-gen/blob/main/src/index.ts
*/
export const generateTypesDefinitions = async () => {
const project = new Project({
compilerOptions: {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
noEmitOnError: false,
outDir,
baseUrl: projRoot,
paths: {
'@element-plus/*': ['packages/*'],
},
skipLibCheck: true,
},
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})
const filePaths = excludeFiles(
await glob('**/*.{js,ts,vue}', {
cwd: pkgRoot,
absolute: true,
onlyFiles: true,
})
)
const sourceFiles: SourceFile[] = []
await Promise.all(
filePaths.map(async (file) => {
if (file.endsWith('.vue')) {
const content = await fs.readFile(file, 'utf-8')
const sfc = vueCompiler.parse(content)
const { script, scriptSetup } = sfc.descriptor
if (script || scriptSetup) {
let content = ''
let isTS = false
if (script && script.content) {
content += script.content
if (script.lang === 'ts') isTS = true
}
if (scriptSetup) {
const compiled = vueCompiler.compileScript(sfc.descriptor, {
id: 'xxx',
})
content += compiled.content
if (scriptSetup.lang === 'ts') isTS = true
}
const sourceFile = project.createSourceFile(
path.relative(process.cwd(), file) + (isTS ? '.ts' : '.js'),
content
)
sourceFiles.push(sourceFile)
}
} else if (file.endsWith('.ts')) {
const sourceFile = project.addSourceFileAtPath(file)
sourceFiles.push(sourceFile)
}
})
)
const diagnostics = project.getPreEmitDiagnostics()
console.log(project.formatDiagnosticsWithColorAndContext(diagnostics))
await project.emit({
emitOnlyDtsFiles: true,
})
const tasks = sourceFiles.map(async (sourceFile) => {
const relativePath = path.relative(pkgRoot, sourceFile.getFilePath())
yellow(`Generating definition for file: ${bold(relativePath)}`)
const emitOutput = sourceFile.getEmitOutput()
const emitFiles = emitOutput.getOutputFiles()
if (emitFiles.length === 0) {
red(`Emit no file: ${bold(relativePath)}`)
return
}
const tasks = emitFiles.map(async (outputFile) => {
const filepath = outputFile.getFilePath()
await fs.mkdir(path.dirname(filepath), {
recursive: true,
})
await fs.writeFile(
filepath,
pathRewriter('esm')(outputFile.getText()),
'utf8'
)
green(`Definition for file: ${bold(relativePath)} generated`)
})
await Promise.all(tasks)
})
await Promise.all(tasks)
const epFiles = await glob('**/*', {
cwd: path.resolve(outDir, 'element-plus'),
absolute: true,
})
await run(`mv ${epFiles.join(' ')} ${outDir}`)
await run(`rmdir ${path.resolve(outDir, 'element-plus')}`)
}