mirror of https://github.com/vuejs/core.git
wip: cache fileToScope + improve vue file offset
This commit is contained in:
parent
c93c11710e
commit
8451b92a7a
|
@ -3,6 +3,7 @@ import { parse } from '../../src'
|
|||
import { ScriptCompileContext } from '../../src/script/context'
|
||||
import {
|
||||
inferRuntimeType,
|
||||
invalidateTypeCache,
|
||||
recordImports,
|
||||
resolveTypeElements
|
||||
} from '../../src/script/resolveType'
|
||||
|
@ -369,6 +370,10 @@ function resolve(code: string, files: Record<string, string> = {}) {
|
|||
}
|
||||
})
|
||||
|
||||
for (const file in files) {
|
||||
invalidateTypeCache(file)
|
||||
}
|
||||
|
||||
// ctx.userImports is collected when calling compileScript(), but we are
|
||||
// skipping that here, so need to manually register imports
|
||||
ctx.userImports = recordImports(ctx.scriptSetupAst!.body) as any
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import LRU from 'lru-cache'
|
||||
|
||||
export function createCache<T>(size = 500) {
|
||||
return __GLOBAL__ || __ESM_BROWSER__
|
||||
? new Map<string, T>()
|
||||
: (new LRU(size) as any as Map<string, T>)
|
||||
if (__GLOBAL__ || __ESM_BROWSER__) {
|
||||
return new Map<string, T>()
|
||||
}
|
||||
const cache = new LRU(size)
|
||||
// @ts-expect-error
|
||||
cache.delete = cache.del.bind(cache)
|
||||
return cache as any as Map<string, T>
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export { compileTemplate } from './compileTemplate'
|
|||
export { compileStyle, compileStyleAsync } from './compileStyle'
|
||||
export { compileScript } from './compileScript'
|
||||
export { rewriteDefault, rewriteDefaultAST } from './rewriteDefault'
|
||||
export { invalidateTypeCache } from './script/resolveType'
|
||||
export {
|
||||
shouldTransform as shouldTransformRef,
|
||||
transform as transformRef,
|
||||
|
|
|
@ -126,7 +126,7 @@ export class ScriptCompileContext {
|
|||
}
|
||||
|
||||
error(msg: string, node: Node & WithScope, scope?: TypeScope): never {
|
||||
const offset = scope ? scope.offset || 0 : this.startOffset!
|
||||
const offset = scope ? scope.offset : this.startOffset!
|
||||
throw new Error(
|
||||
`[@vue/compiler-sfc] ${msg}\n\n${
|
||||
(scope || this.descriptor).filename
|
||||
|
|
|
@ -27,6 +27,7 @@ import { capitalize, hasOwn } from '@vue/shared'
|
|||
import path from 'path'
|
||||
import { parse as babelParse } from '@babel/parser'
|
||||
import { parse } from '../parse'
|
||||
import { createCache } from '../cache'
|
||||
|
||||
type Import = Pick<ImportBinding, 'source' | 'imported'>
|
||||
|
||||
|
@ -539,23 +540,35 @@ function resolveExt(
|
|||
)
|
||||
}
|
||||
|
||||
const fileToScopeCache = createCache<TypeScope>()
|
||||
|
||||
export function invalidateTypeCache(filename: string) {
|
||||
fileToScopeCache.delete(filename)
|
||||
}
|
||||
|
||||
function fileToScope(
|
||||
ctx: ScriptCompileContext,
|
||||
filename: string,
|
||||
fs: NonNullable<SFCScriptCompileOptions['fs']>
|
||||
): TypeScope {
|
||||
// TODO cache
|
||||
const cached = fileToScopeCache.get(filename)
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
const source = fs.readFile(filename)
|
||||
const [body, offset] = parseFile(ctx, filename, source)
|
||||
const body = parseFile(ctx, filename, source)
|
||||
const scope: TypeScope = {
|
||||
filename,
|
||||
source,
|
||||
offset,
|
||||
offset: 0,
|
||||
types: Object.create(null),
|
||||
exportedTypes: Object.create(null),
|
||||
imports: recordImports(body)
|
||||
}
|
||||
recordTypes(body, scope)
|
||||
|
||||
fileToScopeCache.set(filename, scope)
|
||||
return scope
|
||||
}
|
||||
|
||||
|
@ -563,12 +576,10 @@ function parseFile(
|
|||
ctx: ScriptCompileContext,
|
||||
filename: string,
|
||||
content: string
|
||||
): [Statement[], number] {
|
||||
let body: Statement[] = []
|
||||
let offset = 0
|
||||
): Statement[] {
|
||||
const ext = path.extname(filename)
|
||||
if (ext === '.ts' || ext === '.tsx') {
|
||||
body = babelParse(content, {
|
||||
return babelParse(content, {
|
||||
plugins: resolveParserPlugins(
|
||||
ext.slice(1),
|
||||
ctx.options.babelParserPlugins
|
||||
|
@ -579,15 +590,33 @@ function parseFile(
|
|||
const {
|
||||
descriptor: { script, scriptSetup }
|
||||
} = parse(content)
|
||||
const scriptContent = (script?.content || '') + (scriptSetup?.content || '')
|
||||
if (!script && !scriptSetup) {
|
||||
return []
|
||||
}
|
||||
|
||||
// ensure the correct offset with original source
|
||||
const scriptOffset = script ? script.loc.start.offset : Infinity
|
||||
const scriptSetupOffset = scriptSetup
|
||||
? scriptSetup.loc.start.offset
|
||||
: Infinity
|
||||
const firstBlock = scriptOffset < scriptSetupOffset ? script : scriptSetup
|
||||
const secondBlock = scriptOffset < scriptSetupOffset ? scriptSetup : script
|
||||
|
||||
let scriptContent =
|
||||
' '.repeat(Math.min(scriptOffset, scriptSetupOffset)) +
|
||||
firstBlock!.content
|
||||
if (secondBlock) {
|
||||
scriptContent +=
|
||||
' '.repeat(secondBlock.loc.start.offset - script!.loc.end.offset) +
|
||||
secondBlock.content
|
||||
}
|
||||
const lang = script?.lang || scriptSetup?.lang
|
||||
body = babelParse(scriptContent, {
|
||||
return babelParse(scriptContent, {
|
||||
plugins: resolveParserPlugins(lang!, ctx.options.babelParserPlugins),
|
||||
sourceType: 'module'
|
||||
}).program.body
|
||||
offset = scriptSetup ? scriptSetup.loc.start.offset : 0
|
||||
}
|
||||
return [body, offset]
|
||||
return []
|
||||
}
|
||||
|
||||
function ctxToScope(ctx: ScriptCompileContext): TypeScope {
|
||||
|
|
Loading…
Reference in New Issue