Skip to content

Commit

Permalink
fix: common-js not caching the actual file path
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed Dec 23, 2019
1 parent acf57f7 commit aee90ea
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 35 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 17 additions & 14 deletions src/loaders/common-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class CommonJS {
public cache = new Map()

constructor (modules: Modules = {}, readFile: FileLoader = defaultFileLoader) {
debug('CommonJS created')
this.modules = modules
if (typeof readFile === 'function') {
this.readFileImpl = readFile
Expand All @@ -40,10 +41,9 @@ export class CommonJS {

require (filepath: string, specifier: string = filepath) {
debug('global require called with', filepath)
if (!this.cache.has(filepath)) {
const [actualFilePath, fileContent] = this.readModuleContent(filepath, specifier)
if (!this.cache.has(actualFilePath)) {
debug('cache miss, reading', filepath)

const fileContent = this.readModuleContent(filepath, specifier)
const mod = new Module(filepath, fileContent)
const fn = new Function('module', 'exports', 'require', mod.content) // eslint-disable-line

Expand All @@ -60,27 +60,30 @@ export class CommonJS {

return require(path)
})
return mod.exports
this.cache.set(actualFilePath, mod.exports)
}
return this.cache.get(filepath)
return this.cache.get(actualFilePath)
}

private readModuleContent (filepath: string, specifier: string) {
if (this.modules[specifier] !== undefined) {
return this.modules[specifier]
return [specifier, this.modules[specifier]]
}
if (this.modules[filepath] !== undefined) {
return this.modules[filepath]
return [filepath, this.modules[filepath]]
}

const fileContent = this.readFileImpl(filepath, specifier) ||
this.readFileImpl(filepath + '.ts') ||
this.readFileImpl(filepath + '.js')

if (fileContent === undefined) {
throw new Error(`file ${filepath} not found`)
let fileContent
if ((fileContent = this.readFileImpl(filepath, specifier))) {
return [filepath, fileContent]
}
if ((fileContent = this.readFileImpl(filepath + '.ts', specifier))) {
return [filepath + '.ts', fileContent]
}
if ((fileContent = this.readFileImpl(filepath + '.js', specifier))) {
return [filepath + '.js', fileContent]
}
return fileContent
throw new Error(`file ${filepath} not found`)
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/models/san-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ export class SanProject {
}

public parseSanApp (filepath: string) {
const parser = new SanAppParser(this.tsProject)
return parser.parseSanApp(resolve(filepath), this.modules)
return this.getParser().parseSanApp(resolve(filepath), this.modules)
}

private getOrCreateCompilerInstance (target: string | CompilerClass) {
Expand All @@ -58,6 +57,10 @@ export class SanProject {
return this.compilers.get(CompilerClass)
}

private getParser () {
return new SanAppParser(this.tsProject)
}

private loadCompilerClass (target: string | CompilerClass) {
if (typeof target === 'string') return loadCompilerClassByTarget(target)
return target
Expand Down
41 changes: 23 additions & 18 deletions src/parsers/san-app-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ import debugFactory from 'debug'
const debug = debugFactory('component-parser')

export class SanAppParser {
public project: Project
private root: string
private id: number = 0
private cache: Map<SourceFile, SanSourceFile> = new Map()
public project: Project
private cache: Map<string, SanSourceFile> = new Map()
private projectFiles: Map<string, SanSourceFile> = new Map()
private commonJS: CommonJS
private modules = {}

constructor (project: Project) {
debug('SanAppParser created')
this.project = project
this.commonJS = new CommonJS(this.modules, filepath => {
if (!this.projectFiles.has(filepath)) return undefined
const sourceFile = this.projectFiles.get(filepath)
return tsSourceFile2js(sourceFile.tsSourceFile, this.project.getCompilerOptions())
})
}

static createUsingTsconfig (tsConfigFilePath: string) {
Expand All @@ -38,18 +47,17 @@ export class SanAppParser {
? SanSourceFile.createFromJSFilePath(entryFilePath)
: this.parseSanSourceFile(this.project.getSourceFileOrThrow(entryFilePath))

const projectFiles: Map<string, SanSourceFile> = new Map()
projectFiles.set(entryFilePath, entrySourceFile)
this.projectFiles.set(entryFilePath, entrySourceFile)

if (entrySourceFile.fileType === SourceFileType.ts) {
const sourceFiles = getDependenciesRecursively(entrySourceFile.tsSourceFile)

for (const [path, file] of sourceFiles) {
projectFiles.set(path, this.parseSanSourceFile(file))
this.projectFiles.set(path, this.parseSanSourceFile(file))
}
}

const entryClass = this.evaluateFile(entrySourceFile, projectFiles, modules)
const entryClass = this.evaluateFile(entrySourceFile, modules)
const componentClasses = new ComponentClassFinder(entryClass).find()

if (entrySourceFile.fileType === SourceFileType.js) {
Expand All @@ -58,26 +66,23 @@ export class SanAppParser {
componentClass.sanssrCid = i
}
}
return new SanApp(entrySourceFile, projectFiles, componentClasses)
return new SanApp(entrySourceFile, this.projectFiles, componentClasses)
}

private evaluateFile (sourceFile: SanSourceFile, projectFiles: Map<string, SanSourceFile>, modules: Modules) {
private evaluateFile (sourceFile: SanSourceFile, modules: Modules) {
if (sourceFile.fileType === SourceFileType.js) {
return new CommonJS().require(sourceFile.getFilePath())
return this.commonJS.require(sourceFile.getFilePath())
}
const commonJS = new CommonJS(modules, filepath => {
if (!projectFiles.has(filepath)) return undefined
const sourceFile = projectFiles.get(filepath)
return tsSourceFile2js(sourceFile.tsSourceFile, this.project.getCompilerOptions())
})
return commonJS.require(sourceFile.getFilePath()).default
Object.assign(this.modules, modules)
return this.commonJS.require(sourceFile.getFilePath()).default
}

private parseSanSourceFile (sourceFile: SourceFile) {
if (!this.cache.has(sourceFile)) {
this.cache.set(sourceFile, this.doParseSanSourceFile(sourceFile))
const filePath = sourceFile.getFilePath()
if (!this.cache.has(filePath)) {
this.cache.set(filePath, this.doParseSanSourceFile(sourceFile))
}
return this.cache.get(sourceFile)
return this.cache.get(filePath)
}

private doParseSanSourceFile (sourceFile: SourceFile) {
Expand Down

0 comments on commit aee90ea

Please sign in to comment.