Skip to content

Commit 18e6634

Browse files
committed
fix(miniprogram-typescript): logic on file created/removed
1 parent 43d4611 commit 18e6634

File tree

2 files changed

+90
-23
lines changed

2 files changed

+90
-23
lines changed

glass-easel-miniprogram-typescript/src/project.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ export class ProjectDirManager {
142142
wxmlEnvGetter: (tsFullPath: string, wxmlFullPath: string) => string | null = () => null
143143
onEntranceFileAdded: (fullPath: string) => void = () => {}
144144
onEntranceFileRemoved: (fullPath: string) => void = () => {}
145+
onScriptFileAdded: (fullPath: string) => void = () => {}
146+
onScriptFileRemoved: (fullPath: string) => void = () => {}
145147
onConvertedExprCacheUpdated: (wxmlFullPath: string) => void = () => {}
146148
onPendingAsyncTasksEmpty: () => void = () => {}
147149

@@ -178,6 +180,9 @@ export class ProjectDirManager {
178180

179181
private handleFileOpened(fullPath: string) {
180182
const compPath = possibleComponentPath(fullPath)
183+
if (isTsFile(fullPath)) {
184+
this.onScriptFileAdded(fullPath)
185+
}
181186
if (compPath !== null) {
182187
if (isJsonFile(fullPath)) {
183188
const isComp = !!this.trackingComponents[compPath]
@@ -186,6 +191,11 @@ export class ProjectDirManager {
186191
this.asyncWxmlConvertedExprUpdate(`${compPath}.wxml`)
187192
this.onEntranceFileAdded(`${compPath}.wxml`)
188193
}
194+
} else if (isTsFile(fullPath)) {
195+
this.checkConvertedExprCache(`${compPath}.wxml`)
196+
this.forEachDirectDependantComponents(compPath, (compPath) => {
197+
this.checkConvertedExprCache(`${compPath}.wxml`)
198+
})
189199
}
190200
}
191201
}
@@ -202,6 +212,7 @@ export class ProjectDirManager {
202212
this.onEntranceFileAdded(`${compPath}.wxml`)
203213
}
204214
} else if (isComp) {
215+
delete this.trackingComponents[compPath]
205216
this.deleteConvertedExprCache(`${compPath}.wxml`)
206217
this.onEntranceFileRemoved(`${compPath}.wxml`)
207218
}
@@ -218,10 +229,14 @@ export class ProjectDirManager {
218229

219230
private handleFileRemoved(fullPath: string) {
220231
const compPath = possibleComponentPath(fullPath)
232+
if (isTsFile(fullPath)) {
233+
this.onScriptFileRemoved(fullPath)
234+
}
221235
if (compPath !== null) {
222236
if (isJsonFile(fullPath)) {
223237
const isComp = !!this.trackingComponents[compPath]
224238
if (isComp) {
239+
delete this.trackingComponents[compPath]
225240
this.deleteConvertedExprCache(`${compPath}.wxml`)
226241
this.onEntranceFileRemoved(`${compPath}.wxml`)
227242
}
@@ -273,12 +288,21 @@ export class ProjectDirManager {
273288
this.convertedExpr[wxmlFullPath] = cache
274289
}
275290
const content = this.getFileContent(wxmlFullPath)
276-
if (!content) return
291+
if (!content) {
292+
this.deleteConvertedExprCache(wxmlFullPath)
293+
return
294+
}
277295
const relPath = path.relative(this.vfs.rootPath, wxmlFullPath).split(path.sep).join('/')
278-
if (relPath.startsWith('../')) return
296+
if (relPath.startsWith('../')) {
297+
this.deleteConvertedExprCache(wxmlFullPath)
298+
return
299+
}
279300
this.tmplGroup.addTmpl(relPath, content)
280301
const env = this.wxmlEnvGetter(tsFullPath, wxmlFullPath)
281-
if (!env) return
302+
if (!env) {
303+
this.deleteConvertedExprCache(wxmlFullPath)
304+
return
305+
}
282306
this.pendingAsyncTasks += 1
283307
// eslint-disable-next-line @typescript-eslint/no-floating-promises
284308
;(async () => {

glass-easel-miniprogram-typescript/src/server.ts

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@ type LocationLink = {
3636
targetRange: PositionRange
3737
}
3838

39+
class Cache<T> {
40+
private cache: T
41+
private dirty: boolean
42+
private updater: (this: void, cache: T) => T
43+
44+
constructor(updater: (this: void, cache: T) => T, init: T) {
45+
this.cache = init
46+
this.dirty = false
47+
this.updater = updater
48+
}
49+
50+
get(): T {
51+
if (this.dirty) {
52+
this.cache = this.updater(this.cache)
53+
}
54+
return this.cache
55+
}
56+
57+
invalidate(): void {
58+
this.dirty = true
59+
}
60+
}
61+
3962
const getDefaultExportOfSourceFile = (
4063
tc: ts.TypeChecker,
4164
source: ts.SourceFile,
@@ -77,7 +100,8 @@ export class Server {
77100
private workingDirectory: string
78101
private tsLangService: ts.LanguageService
79102
private projectDirManager: ProjectDirManager
80-
private rootFilePaths: string[]
103+
private rootFilePaths: Cache<string[]>
104+
private rootTsFileCount: number
81105
private rootFilePathsVersion: number
82106
private configErrors: ts.Diagnostic[]
83107
private pendingAsyncTasksListeners: (() => void)[] = []
@@ -100,17 +124,18 @@ export class Server {
100124
this.logVerboseMessage(`Opened component WXML: ${fullPath}`)
101125
const p = getWxmlConvertedTsPath(fullPath)
102126
if (p) {
103-
this.rootFilePaths.push(p)
127+
this.rootFilePaths.get().push(p)
104128
this.rootFilePathsVersion += 1
105129
}
106130
}
107131
this.projectDirManager.onEntranceFileRemoved = (fullPath) => {
108132
this.logVerboseMessage(`Closed component WXML: ${fullPath}`)
109133
const p = getWxmlConvertedTsPath(fullPath)
110134
if (p) {
111-
const index = this.rootFilePaths.lastIndexOf(p)
135+
const rootFilePaths = this.rootFilePaths.get()
136+
const index = rootFilePaths.lastIndexOf(p)
112137
if (index >= 0) {
113-
this.rootFilePaths[index] = this.rootFilePaths.pop()!
138+
rootFilePaths[index] = rootFilePaths.pop()!
114139
this.rootFilePathsVersion += 1
115140
}
116141
}
@@ -126,6 +151,14 @@ export class Server {
126151
f.forEach((f) => f.call(this))
127152
}
128153

154+
// handling root ts file changes
155+
const handleRootTsFileChanges = () => {
156+
this.rootFilePathsVersion += 1
157+
this.rootFilePaths.invalidate()
158+
}
159+
this.projectDirManager.onScriptFileAdded = handleRootTsFileChanges
160+
this.projectDirManager.onScriptFileRemoved = handleRootTsFileChanges
161+
129162
// initialize ts language service
130163
/* eslint-disable @typescript-eslint/unbound-method, arrow-body-style */
131164
const configPath = tsc.findConfigFile(this.projectPath, tsc.sys.fileExists, 'tsconfig.json')
@@ -134,30 +167,40 @@ export class Server {
134167
if (configPath !== undefined) {
135168
// eslint-disable-next-line @typescript-eslint/unbound-method
136169
const configFile = tsc.readJsonConfigFile(configPath, tsc.sys.readFile)
137-
config = tsc.parseJsonSourceFileConfigFileContent(
138-
configFile,
139-
{
140-
useCaseSensitiveFileNames: false,
141-
readDirectory: tsc.sys.readDirectory,
142-
fileExists: tsc.sys.fileExists,
143-
readFile: tsc.sys.readFile,
144-
},
145-
path.dirname(configPath),
146-
{ noEmit: true },
147-
// undefined,
148-
// undefined,
149-
// [{ extension: '.wxml', isMixedContent: true, scriptKind: ts.ScriptKind.TS }],
150-
)
170+
const getConfig = () =>
171+
tsc.parseJsonSourceFileConfigFileContent(
172+
configFile,
173+
{
174+
useCaseSensitiveFileNames: false,
175+
readDirectory: tsc.sys.readDirectory,
176+
fileExists: tsc.sys.fileExists,
177+
readFile: tsc.sys.readFile,
178+
},
179+
path.dirname(configPath),
180+
{ noEmit: true },
181+
// undefined,
182+
// undefined,
183+
// [{ extension: '.wxml', isMixedContent: true, scriptKind: ts.ScriptKind.TS }],
184+
)
185+
config = getConfig()
186+
this.rootFilePaths = new Cache((old) => {
187+
const extra = old.slice(this.rootTsFileCount)
188+
const ret = getConfig().fileNames
189+
this.rootTsFileCount = ret.length
190+
return ret.concat(extra)
191+
}, config.fileNames)
192+
this.rootTsFileCount = config.fileNames.length
151193
} else {
152194
const compilerOptions = tsc.getDefaultCompilerOptions()
153195
config = {
154196
options: compilerOptions,
155197
fileNames: [],
156198
errors: [],
157199
}
200+
this.rootFilePaths = new Cache((x) => x, [] as string[])
201+
this.rootTsFileCount = 0
158202
}
159203
this.configErrors = config.errors
160-
this.rootFilePaths = config.fileNames
161204
this.rootFilePathsVersion = 1
162205
const servicesHost: ts.LanguageServiceHost = {
163206
getCompilationSettings() {
@@ -167,7 +210,7 @@ export class Server {
167210
return String(this.rootFilePathsVersion)
168211
},
169212
getScriptFileNames: () => {
170-
return this.rootFilePaths
213+
return this.rootFilePaths.get()
171214
},
172215
getScriptVersion: (fullPath) => {
173216
return this.projectDirManager.getFileVersion(fullPath)?.toString() ?? ''

0 commit comments

Comments
 (0)