mirror of https://github.com/vuejs/core.git
perf(compiler-sfc): lazy require typescript
This commit is contained in:
parent
6f45f76df2
commit
d2c3d8b70b
|
@ -10,7 +10,7 @@ import {
|
||||||
} from '../../src/script/resolveType'
|
} from '../../src/script/resolveType'
|
||||||
|
|
||||||
import ts from 'typescript'
|
import ts from 'typescript'
|
||||||
registerTS(ts)
|
registerTS(() => ts)
|
||||||
|
|
||||||
describe('resolveType', () => {
|
describe('resolveType', () => {
|
||||||
test('type literal', () => {
|
test('type literal', () => {
|
||||||
|
|
|
@ -708,13 +708,14 @@ function resolveGlobalScope(ctx: TypeResolveContext): TypeScope[] | undefined {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ts: typeof TS
|
let ts: typeof TS | undefined
|
||||||
|
let loadTS: (() => typeof TS) | undefined
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function registerTS(_ts: any) {
|
export function registerTS(_loadTS: () => typeof TS) {
|
||||||
ts = _ts
|
loadTS = _loadTS
|
||||||
}
|
}
|
||||||
|
|
||||||
type FS = NonNullable<SFCScriptCompileOptions['fs']>
|
type FS = NonNullable<SFCScriptCompileOptions['fs']>
|
||||||
|
@ -723,7 +724,10 @@ function resolveFS(ctx: TypeResolveContext): FS | undefined {
|
||||||
if (ctx.fs) {
|
if (ctx.fs) {
|
||||||
return ctx.fs
|
return ctx.fs
|
||||||
}
|
}
|
||||||
const fs = ctx.options.fs || ts.sys
|
if (!ts && loadTS) {
|
||||||
|
ts = loadTS()
|
||||||
|
}
|
||||||
|
const fs = ctx.options.fs || ts?.sys
|
||||||
if (!fs) {
|
if (!fs) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -779,22 +783,25 @@ function importSourceToScope(
|
||||||
} else {
|
} else {
|
||||||
// module or aliased import - use full TS resolution, only supported in Node
|
// module or aliased import - use full TS resolution, only supported in Node
|
||||||
if (!__NODE_JS__) {
|
if (!__NODE_JS__) {
|
||||||
ctx.error(
|
return ctx.error(
|
||||||
`Type import from non-relative sources is not supported in the browser build.`,
|
`Type import from non-relative sources is not supported in the browser build.`,
|
||||||
node,
|
node,
|
||||||
scope
|
scope
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!ts) {
|
if (!ts) {
|
||||||
ctx.error(
|
if (loadTS) ts = loadTS()
|
||||||
`Failed to resolve import source ${JSON.stringify(source)}. ` +
|
if (!ts) {
|
||||||
`typescript is required as a peer dep for vue in order ` +
|
return ctx.error(
|
||||||
`to support resolving types from module imports.`,
|
`Failed to resolve import source ${JSON.stringify(source)}. ` +
|
||||||
node,
|
`typescript is required as a peer dep for vue in order ` +
|
||||||
scope
|
`to support resolving types from module imports.`,
|
||||||
)
|
node,
|
||||||
|
scope
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resolved = resolveWithTS(scope.filename, source, fs)
|
resolved = resolveWithTS(scope.filename, source, ts, fs)
|
||||||
}
|
}
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
resolved = scope.resolvedImportSources[source] = normalizePath(resolved)
|
resolved = scope.resolvedImportSources[source] = normalizePath(resolved)
|
||||||
|
@ -839,6 +846,7 @@ const tsConfigRefMap = new Map<string, string>()
|
||||||
function resolveWithTS(
|
function resolveWithTS(
|
||||||
containingFile: string,
|
containingFile: string,
|
||||||
source: string,
|
source: string,
|
||||||
|
ts: typeof TS,
|
||||||
fs: FS
|
fs: FS
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
if (!__NODE_JS__) return
|
if (!__NODE_JS__) return
|
||||||
|
@ -853,7 +861,7 @@ function resolveWithTS(
|
||||||
const normalizedConfigPath = normalizePath(configPath)
|
const normalizedConfigPath = normalizePath(configPath)
|
||||||
const cached = tsConfigCache.get(normalizedConfigPath)
|
const cached = tsConfigCache.get(normalizedConfigPath)
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
configs = loadTSConfig(configPath, fs).map(config => ({ config }))
|
configs = loadTSConfig(configPath, ts, fs).map(config => ({ config }))
|
||||||
tsConfigCache.set(normalizedConfigPath, configs)
|
tsConfigCache.set(normalizedConfigPath, configs)
|
||||||
} else {
|
} else {
|
||||||
configs = cached
|
configs = cached
|
||||||
|
@ -918,7 +926,11 @@ function resolveWithTS(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTSConfig(configPath: string, fs: FS): TS.ParsedCommandLine[] {
|
function loadTSConfig(
|
||||||
|
configPath: string,
|
||||||
|
ts: typeof TS,
|
||||||
|
fs: FS
|
||||||
|
): TS.ParsedCommandLine[] {
|
||||||
// The only case where `fs` is NOT `ts.sys` is during tests.
|
// The only case where `fs` is NOT `ts.sys` is during tests.
|
||||||
// parse config host requires an extra `readDirectory` method
|
// parse config host requires an extra `readDirectory` method
|
||||||
// during tests, which is stubbed.
|
// during tests, which is stubbed.
|
||||||
|
@ -940,7 +952,7 @@ function loadTSConfig(configPath: string, fs: FS): TS.ParsedCommandLine[] {
|
||||||
if (config.projectReferences) {
|
if (config.projectReferences) {
|
||||||
for (const ref of config.projectReferences) {
|
for (const ref of config.projectReferences) {
|
||||||
tsConfigRefMap.set(ref.path, configPath)
|
tsConfigRefMap.set(ref.path, configPath)
|
||||||
res.unshift(...loadTSConfig(ref.path, fs))
|
res.unshift(...loadTSConfig(ref.path, ts, fs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
if (typeof require !== 'undefined') {
|
if (typeof require !== 'undefined') {
|
||||||
try {
|
try {
|
||||||
require('@vue/compiler-sfc').registerTS(require('typescript'))
|
require('@vue/compiler-sfc').registerTS(() => require('typescript'))
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue