feat(@vant/cli): generate type declaration for sfc (#9675)

This commit is contained in:
neverland 2021-10-14 14:44:21 +08:00 committed by GitHub
parent 66cf1dabba
commit 7eb9344446
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 30 deletions

View File

@ -1,13 +1,13 @@
import execa from 'execa'; import execa from 'execa';
import { join, relative } from 'path'; import { join, relative } from 'path';
import { remove, copy, readdirSync, existsSync } from 'fs-extra'; import { remove, copy, readdir, existsSync } from 'fs-extra';
import { clean } from './clean'; import { clean } from './clean';
import { CSS_LANG } from '../common/css'; import { CSS_LANG } from '../common/css';
import { ora, consola } from '../common/logger'; import { ora, consola } from '../common/logger';
import { installDependencies } from '../common/manager'; import { installDependencies } from '../common/manager';
import { compileJs } from '../compiler/compile-js';
import { compileSfc } from '../compiler/compile-sfc'; import { compileSfc } from '../compiler/compile-sfc';
import { compileStyle } from '../compiler/compile-style'; import { compileStyle } from '../compiler/compile-style';
import { compileScript } from '../compiler/compile-script';
import { compilePackage } from '../compiler/compile-package'; import { compilePackage } from '../compiler/compile-package';
import { genPackageEntry } from '../compiler/gen-package-entry'; import { genPackageEntry } from '../compiler/gen-package-entry';
import { genStyleDepsMap } from '../compiler/gen-style-deps-map'; import { genStyleDepsMap } from '../compiler/gen-style-deps-map';
@ -29,27 +29,25 @@ import {
} from '../common'; } from '../common';
async function compileFile(filePath: string) { async function compileFile(filePath: string) {
if (isSfc(filePath)) {
return compileSfc(filePath);
}
if (isScript(filePath)) { if (isScript(filePath)) {
return compileJs(filePath); return compileScript(filePath);
} }
if (isStyle(filePath)) { if (isStyle(filePath)) {
return compileStyle(filePath); return compileStyle(filePath);
} }
if (isAsset(filePath)) { if (isAsset(filePath)) {
return Promise.resolve(); return Promise.resolve();
} }
return remove(filePath); return remove(filePath);
} }
async function compileDir(dir: string) { /**
const files = readdirSync(dir); * Pre-compile
* 1. Remove unneeded dirs
* 2. compile sfc into scripts/styles
*/
async function preCompileDir(dir: string) {
const files = await readdir(dir);
await Promise.all( await Promise.all(
files.map((filename) => { files.map((filename) => {
@ -58,19 +56,29 @@ async function compileDir(dir: string) {
if (isDemoDir(filePath) || isTestDir(filePath)) { if (isDemoDir(filePath) || isTestDir(filePath)) {
return remove(filePath); return remove(filePath);
} }
if (isDir(filePath)) { if (isDir(filePath)) {
return compileDir(filePath); return preCompileDir(filePath);
} }
if (isSfc(filePath)) {
return compileSfc(filePath);
}
return Promise.resolve();
})
);
}
return compileFile(filePath); async function compileDir(dir: string) {
const files = await readdir(dir);
await Promise.all(
files.map((filename) => {
const filePath = join(dir, filename);
return isDir(filePath) ? compileDir(filePath) : compileFile(filePath);
}) })
); );
} }
async function copySourceCode() { async function copySourceCode() {
await copy(SRC_DIR, ES_DIR); return Promise.all([copy(SRC_DIR, ES_DIR), copy(SRC_DIR, LIB_DIR)]);
await copy(SRC_DIR, LIB_DIR);
} }
async function buildESMOutputs() { async function buildESMOutputs() {
@ -86,6 +94,8 @@ async function buildCJSOutputs() {
} }
async function buildTypeDeclarations() { async function buildTypeDeclarations() {
await Promise.all([preCompileDir(ES_DIR), preCompileDir(LIB_DIR)]);
const tsConfig = join(process.cwd(), 'tsconfig.declaration.json'); const tsConfig = join(process.cwd(), 'tsconfig.declaration.json');
if (existsSync(tsConfig)) { if (existsSync(tsConfig)) {

View File

@ -5,7 +5,7 @@ import { replaceExt } from '../common';
import { replaceCSSImportExt } from '../common/css'; import { replaceCSSImportExt } from '../common/css';
import { replaceScriptImportExt } from './get-deps'; import { replaceScriptImportExt } from './get-deps';
export async function compileJs(filePath: string): Promise<void> { export async function compileScript(filePath: string): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (filePath.includes('.d.ts')) { if (filePath.includes('.d.ts')) {
resolve(); resolve();

View File

@ -1,10 +1,8 @@
import hash from 'hash-sum'; import hash from 'hash-sum';
import path from 'path'; import path from 'path';
import { parse, SFCBlock, compileTemplate } from '@vue/compiler-sfc'; import { parse, SFCBlock, compileTemplate } from '@vue/compiler-sfc';
import { remove, writeFileSync, readFileSync } from 'fs-extra'; import { remove, readFileSync, outputFile } from 'fs-extra';
import { replaceExt } from '../common'; import { replaceExt } from '../common';
import { compileJs } from './compile-js';
import { compileStyle } from './compile-style';
const RENDER_FN = '__vue_render__'; const RENDER_FN = '__vue_render__';
const VUEIDS = '__vue_sfc__'; const VUEIDS = '__vue_sfc__';
@ -78,10 +76,16 @@ export async function compileSfc(filePath: string): Promise<any> {
const scriptFilePath = replaceExt(filePath, `.${lang}`); const scriptFilePath = replaceExt(filePath, `.${lang}`);
tasks.push( tasks.push(
new Promise((resolve, reject) => { new Promise((resolve) => {
let script = descriptor.script!.content; let script = '';
script = injectStyle(script, styles, filePath);
// the generated render fn lacks type definitions
if (lang === 'ts') {
script += '// @ts-nocheck\n';
}
script += descriptor.script!.content;
script = injectStyle(script, styles, filePath);
script = script.replace(EXPORT, `const ${VUEIDS} =`); script = script.replace(EXPORT, `const ${VUEIDS} =`);
if (template) { if (template) {
@ -100,15 +104,14 @@ export async function compileSfc(filePath: string): Promise<any> {
script += `\n${EXPORT} ${VUEIDS}`; script += `\n${EXPORT} ${VUEIDS}`;
writeFileSync(scriptFilePath, script); outputFile(scriptFilePath, script).then(resolve);
compileJs(scriptFilePath).then(resolve).catch(reject);
}) })
); );
} }
// compile style part // compile style part
tasks.push( tasks.push(
...styles.map((style, index: number) => { ...styles.map(async (style, index: number) => {
const cssFilePath = getSfcStylePath(filePath, style.lang || 'css', index); const cssFilePath = getSfcStylePath(filePath, style.lang || 'css', index);
const styleSource = trim(style.content); const styleSource = trim(style.content);
@ -124,9 +127,7 @@ export async function compileSfc(filePath: string): Promise<any> {
// }).code; // }).code;
// } // }
writeFileSync(cssFilePath, styleSource); return outputFile(cssFilePath, styleSource);
return compileStyle(cssFilePath);
}) })
); );