From 40bf654054f75b25e6a9782dea55f23644602662 Mon Sep 17 00:00:00 2001 From: harttle Date: Fri, 31 Jul 2020 15:45:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=BE=93=E5=85=A5=E4=B8=BA=20TypeScript?= =?UTF-8?q?=20=E6=97=B6=E4=B8=8D=E8=B0=83=E7=94=A8=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原则上 SSR 期间不调用 san 核心代码,构造函数会调用基类,而基类在 san 核心里,因此违反了这一点。 --- src/models/san-project.ts | 2 +- src/parsers/typescript-san-parser.ts | 15 +++++++------- .../parsers/typescript-san-parser.spec.ts | 20 ++++++++++++++++++- test/unit/target-js/index.spec.ts | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/models/san-project.ts b/src/models/san-project.ts index efa6e3ac..d0565092 100644 --- a/src/models/san-project.ts +++ b/src/models/san-project.ts @@ -60,7 +60,7 @@ export class SanProject { if (/\.ts$/.test(filePath)) { if (!this.tsProject) throw new Error(`Error parsing ${input}, tsconfig not specified`) const sourceFile = this.createOrRefreshSourceFile(this.tsProject, filePath, fileContent) - return new TypeScriptSanParser(sourceFile).parse() + return new TypeScriptSanParser().parse(sourceFile) } return new ComponentClassParser(require(filePath), filePath).parse() } diff --git a/src/parsers/typescript-san-parser.ts b/src/parsers/typescript-san-parser.ts index 9850ea59..d4cfc83c 100644 --- a/src/parsers/typescript-san-parser.ts +++ b/src/parsers/typescript-san-parser.ts @@ -13,15 +13,11 @@ const debug = debugFactory('ts-component-parser') * 把包含 San 组件定义的 TypeScript 源码,通过静态分析(AST),得到组件信息。 */ export class TypeScriptSanParser { - constructor ( - private readonly sourceFile: SourceFile - ) {} - - parse () { - const classDeclarations = getComponentDeclarations(this.sourceFile).map(normalizeComponentClass) + parse (sourceFile: SourceFile) { + const classDeclarations = getComponentDeclarations(sourceFile).map(normalizeComponentClass) const defaultClassDeclaration = classDeclarations.find(clazz => clazz.isDefaultExport()) const componentInfos: TypedComponentInfo[] = classDeclarations.map(decl => this.parseComponentClassDeclaration(decl, defaultClassDeclaration)) - return new TypedSanSourceFile(componentInfos, this.sourceFile, componentInfos.find(info => info.classDeclaration.isDefaultExport())) + return new TypedSanSourceFile(componentInfos, sourceFile, componentInfos.find(info => info.classDeclaration.isDefaultExport())) } private parseComponentClassDeclaration (classDeclaration: ClassDeclaration, defaultClassDeclaration?: ClassDeclaration): TypedComponentInfo { @@ -29,6 +25,11 @@ export class TypeScriptSanParser { const trimWhitespace = getPropertyStringValue<'none' | 'blank' | 'all'>(classDeclaration, 'trimWhitespace') const delimiters = getPropertyStringArrayValue<[string, string]>(classDeclaration, 'delimiters') const childComponents = getChildComponents(classDeclaration, defaultClassDeclaration) + + for (const constructorDelcaration of classDeclaration.getConstructors()) { + constructorDelcaration.remove() + } + return new TypedComponentInfo( classDeclaration.isDefaultExport() ? getDefaultExportedComponentID() : getExportedComponentID(classDeclaration.getName()!), template, diff --git a/test/unit/parsers/typescript-san-parser.spec.ts b/test/unit/parsers/typescript-san-parser.spec.ts index 388e30f1..21bb790b 100644 --- a/test/unit/parsers/typescript-san-parser.spec.ts +++ b/test/unit/parsers/typescript-san-parser.spec.ts @@ -12,8 +12,26 @@ describe('.parseFromTypeScript()', () => { class Foo extends Component {} export default class Bar extends Component {} `) - const sourceFile = new TypeScriptSanParser(file).parse() + const sourceFile = new TypeScriptSanParser().parse(file) expect(sourceFile.componentInfos[0].classDeclaration.isDefaultExport()).toBe(false) expect(sourceFile.componentInfos[1].classDeclaration.isDefaultExport()).toBe(true) }) + + it('should remove constructors', function () { + const file = proj.createSourceFile('foo.ts', ` + import { Component } from 'san' + function foo () {} + export class MyComponent extends Component { + foo = 'bar' + constructor() { + foo() + } + } + `) + const sourceFile = new TypeScriptSanParser().parse(file) + expect(sourceFile.componentInfos).toHaveLength(1) + + const [info] = sourceFile.componentInfos + expect(info.classDeclaration.getConstructors()).toHaveLength(0) + }) }) diff --git a/test/unit/target-js/index.spec.ts b/test/unit/target-js/index.spec.ts index a6d31bc3..3f783945 100644 --- a/test/unit/target-js/index.spec.ts +++ b/test/unit/target-js/index.spec.ts @@ -12,7 +12,7 @@ describe('ToJSCompiler', () => { import { Component } from 'san'; class Foo extends Component {} `) - expect(() => cc.compileToSource(new TypeScriptSanParser(sourceFile).parse())).not.toThrow() + expect(() => cc.compileToSource(new TypeScriptSanParser().parse(sourceFile))).not.toThrow() }) }) })