Skip to content

Commit

Permalink
Controller编译器
Browse files Browse the repository at this point in the history
  • Loading branch information
meepobrother committed May 3, 2019
1 parent 5e91025 commit 4ecbbad
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 918 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
/**/.rts2_cache_umd
/**/node_modules
/app
/hooks
/hooks
3 changes: 3 additions & 0 deletions addon/nger-todo/template/admin/task-edit/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.task-edit{
display: block;
}
3 changes: 3 additions & 0 deletions addon/nger-todo/template/admin/task-list/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.task-list{
display: block;
}
10 changes: 10 additions & 0 deletions framework/inc/home.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Controller, Get } from 'nger-core'

// 首页
@Controller({
path: '/api'
})
export class NgerHome {
@Get()
getSystemInfo() { }
}
5 changes: 3 additions & 2 deletions packages/nger-compiler-preact/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { NgerCompilerPreactController } from './controller'

import { StaticProvider, Injector } from 'nger-di';
import { NgerCompilerNgMetadata } from 'nger-compiler'
import { NgModuleBootstrap, NgerConfig } from 'nger-core'
import { NgModuleBootstrap, NgerConfig, Logger } from 'nger-core'
import ngerCompiler, { NgerPlatformStyle } from 'nger-compiler'
const provider: StaticProvider[] = [...ngerCompiler, {
provide: NgModuleBootstrap,
Expand All @@ -19,7 +19,8 @@ const provider: StaticProvider[] = [...ngerCompiler, {
NgerCompilerPreactTypescript,
NgerCompilerNgMetadata,
NgerCompilerPreactController,
NgerConfig
NgerConfig,
Logger
],
multi: true
}, {
Expand Down
35 changes: 19 additions & 16 deletions packages/nger-compiler-preact/lib/preact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,32 @@ export class NgerCompilerPreact extends NgModuleBootstrap {
) {
super();
}
// 这里需要记录一下
cache: Map<any,any> = new Map();
// 任务是去除无用代码
async run(ref: NgModuleRef<any>) {
try {
// 拿到ngModule的文件名
const framework = join(root, 'framework');
const addon = join(root, 'addon');
const handlerFile = async (opt: string, fileName: string, stats: Stats) => {
this.logger.info(`${opt}:${fileName}@${stats.atime}`)
if (fileName && stats.isFile() && (opt === 'add' || opt === 'change')) {
this.logger.info(`${opt}: ${fileName} @${stats && stats.atime}`)
const isFile = stats && stats.isFile()
if (fileName && !!isFile && (opt === 'add' || opt === 'change')) {
// 拿到ngModuleMetadata
const metadata = this.metadata.getMetadata(fileName);
if (metadata) {
// 处理component
const component: NgerComponentConfig = this.metadata.getComponentConfig(metadata)
if (component) {
component.sourceRoot = fileName;
await Promise.all([
this.html.run(component),
this.style.run(component),
this.assets.run(component),
this.ts.run(component),
]);
}
// 不用处理component
// const component: NgerComponentConfig = this.metadata.getComponentConfig(metadata)
// if (component) {
// component.sourceRoot = fileName;
// await Promise.all([
// this.html.run(component),
// this.style.run(component),
// this.assets.run(component),
// this.ts.run(component),
// ]);
// }
// 处理Controller
const controller: NgerControllerConfig = this.metadata.getControllerConfig(metadata);
if (controller) {
Expand All @@ -58,10 +62,9 @@ export class NgerCompilerPreact extends NgModuleBootstrap {
}
}
chokidar.watch([addon, framework])
.on('add', (opt, file, stats) => handlerFile(opt, file, stats))
.on('change', (opt, file, stats) => handlerFile(opt, file, stats))
.on('add', (file, stats) => handlerFile('add', file, stats))
.on('change', (file, stats) => handlerFile('change', file, stats))
.on('error', () => { });

} catch (e) { }
}
}
7 changes: 7 additions & 0 deletions packages/nger-compiler/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createPlatformFactory, NgModule } from 'nger-core'
import ngerPlatformNode from 'nger-platform-node'
import providers from '../lib'
@NgModule()
export class NgerCompilerTestModule { }
createPlatformFactory(ngerPlatformNode, 'test', providers)([]).bootstrapModule(NgerCompilerTestModule)

54 changes: 54 additions & 0 deletions packages/nger-compiler/lib/compiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { NgModuleBootstrap, NgModuleRef, FileSystem,Logger } from 'nger-core';
import chokidar from 'chokidar';
import { join, relative, extname } from 'path'
import { Stats } from 'fs-extra'
import { NgerCompilerNgMetadata } from './helper/ng_metadata'
const root = process.cwd();
import { NgerUtil } from 'nger-util'
import { NgerCompilerBabel } from './ts/babel'
export class NgerCompilerBootstrap extends NgModuleBootstrap {
constructor(
public metadata: NgerCompilerNgMetadata,
public fs: FileSystem,
public util: NgerUtil,
public babel: NgerCompilerBabel,
public logger: Logger
) {
super();
}
async run(ref: NgModuleRef<any>) {
await this.watchTsx();
}
async watchTsx() {
// 监听ts文件变更并生成metadata.json文件
const framework = join(root, 'framework');
const addon = join(root, 'addon');
await this.util.rimraf(join(root, '.temp'));
chokidar.watch([`${addon}/**/*.(ts|tsx)`, `${framework}/**/*.(ts|tsx)`])
.on('add', (file, stats) => this.handlerTsxFile('add', file, stats))
.on('change', (file, stats) => this.handlerTsxFile('change', file, stats))
.on('error', () => { });
}
metadataCache: Map<string, string> = new Map();
ngModuleMetadataCache: Map<string, any> = new Map();
handlerTsxFile(opt: 'add' | 'change', file: string, stats: Stats) {
const metadata = this.metadata.getMetadata(file);
const relativePath = relative(root, file)
const ext = extname(relativePath);
const noExtPath = relativePath.replace(ext, '')
const metadataPath = join(root, '.temp', `${noExtPath}.metadata.json`);
this.fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2))
this.metadataCache.set(file, metadataPath)
// 解析Controller成浏览器端接口
if (metadata) {
this.logger.info(`compiler controller`)
const config = this.metadata.getControllerConfig(metadata);
if (config) {
// 是controller
const code = this.babel.compile(file);
const controllerPath = join(root, '.temp', `${noExtPath}.js`);
this.fs.writeFileSync(controllerPath, code)
}
}
}
}
23 changes: 21 additions & 2 deletions packages/nger-compiler/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { StaticProvider } from 'nger-di'
import { NgerCompilerImage } from './assets/image'
import { NgerCompilerUglify } from './ts/uglify'
import { NgerCompilerBabel } from './ts/babel'
import { TraverVisitor, Resolver } from 'nger-core'
import { TraverVisitor, Resolver, NgModuleBootstrap, FileSystem,Logger } from 'nger-core'
import { NgerCompilerTypescript } from './ts/typescript'
import { NgerCompilerRollup } from './ts/rollup'
import { NgerCompilerNgTemplate } from './html/ng'
Expand All @@ -18,10 +18,29 @@ export {
NgerCompilerRollup,
NgerCompilerNgTemplate,
NgerCompilerCid,
NgerCompilerNgMetadata
NgerCompilerNgMetadata,
NgerCompilerBootstrap
}
import { NgerCompilerBootstrap } from './compiler'
import { NgerUtil } from 'nger-util'
import { controllerVisitor } from './visitors/controller'
const provides: StaticProvider[] = [
...styleProviders,
{
provide: TraverVisitor,
useValue: controllerVisitor,
multi: true
},
{
provide: NgModuleBootstrap,
useExisting: NgerCompilerBootstrap,
multi: true
},
{
provide: NgerCompilerBootstrap,
useClass: NgerCompilerBootstrap,
deps: [NgerCompilerNgMetadata, FileSystem, NgerUtil, NgerCompilerBabel,Logger],
},
{
provide: NgerCompilerNgMetadata,
useClass: NgerCompilerNgMetadata,
Expand Down
5 changes: 2 additions & 3 deletions packages/nger-compiler/lib/ts/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import fs from 'fs-extra';
import { Injectable } from 'nger-core';
import { NgerCompilerTypescript } from 'nger-compiler';


function mergeVisitors(visitors: Visitor[], that: NgerCompilerBabel): Visitor {
if (visitors && visitors.length > 0) {
if (visitors.length === 1) {
Expand Down Expand Up @@ -55,14 +54,14 @@ export class NgerCompilerBabel {
}
return code;
}
copy(from: string) {
compile(from: string) {
// 如果已经处理过了则忽略
// 拿到文件内容
let code = this.getFileContent(from);
// 解析
const ast = parse(code, {});
// 替换处理
traverse(ast, this.visitor);
traverse(ast, this.visitor || {});
code = generator(ast).code;
return code;
}
Expand Down
64 changes: 62 additions & 2 deletions packages/nger-compiler/lib/ts/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,73 @@ import ts from 'typescript'
import { join } from 'path'
const root = process.cwd();
const options = require(join(root, 'tsconfig.json')).compilerOptions;
import { CompilerOptions } from 'typescript'
import { CompilerOptions, CustomTransformers, TransformationContext, Transformer } from 'typescript'
// 遍历吧 没啥好方法

// 这个是负责任Controller处理器
const ConstructorTransformerFactory = (context: TransformationContext): Transformer<ts.SourceFile> => {
return (node: ts.SourceFile): ts.SourceFile => {
// 骚年在这里处理吧
node.statements = ts.createNodeArray(
node.statements.map((node: ts.Statement) => {
if (ts.isImportDeclaration(node)) {
return node;
} else if (ts.isClassDeclaration(node)) {
return ts.createClassDeclaration(
node.decorators,
node.modifiers,
node.name,
node.typeParameters,
node.heritageClauses,
node.members.map(member => {
if (ts.isMethodDeclaration(member)) {
// 先判断是否Get/Post等方法
// 这里需要创建一个type
const isController = hasControllerMetadata(member.decorators);
if (isController) {
debugger;
return ts.createProperty(member.decorators, member.modifiers, member.name, null, null, null)
} else {
return member;
}
} else {
return member;
}
})
)
} else {
return node;
}
})
)
return node;
}
}

function hasControllerMetadata(nodes: ts.NodeArray<ts.Decorator>) {
return !!nodes.find(node => {
if (ts.isDecorator(node)) {
if (ts.isIdentifier(node.expression)) {
return ['Get', 'Post'].indexOf(node.expression.text) > -1;
}
}
return false;
})
}
const customTransformer: CustomTransformers = {
before: [
ConstructorTransformerFactory
],
after: [],
afterDeclarations: []
}
@Injectable()
export class NgerCompilerTypescript {
options: CompilerOptions = options;
constructor() { }
compile(content: string, config: ts.TranspileOptions = {
compilerOptions: this.options
compilerOptions: this.options,
transformers: customTransformer
}): string {
const output = ts.transpileModule(content, config)
return output.outputText
Expand Down
8 changes: 8 additions & 0 deletions packages/nger-compiler/lib/visitors/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Visitor, NodePath } from '@babel/traverse';
import t from '@babel/types';

export const controllerVisitor: Visitor = {
// 转义Controller里面的Get/Post等,删除Injector
ClassMethod(path: NodePath<t.ClassMethod>) { }
}

9 changes: 8 additions & 1 deletion packages/nger-util/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ import { execSync } from 'child_process';
import { join } from 'path';
import { Logger, NgerConfig } from 'nger-core';
import { CompilerOptions } from 'typescript'
import rimraf = require('rimraf');

export class NgerUtil {
root: string = process.cwd()
constructor(public logger: Logger, public config: NgerConfig) { }
rimraf(dir: string) {
return new Promise((resolve, reject) => {
rimraf(dir, () => resolve())
});
}
getCompilerOptions(): CompilerOptions {
return require(join(this.root, 'tsconfig')).compilerOptions
}
Expand All @@ -32,7 +39,7 @@ export class NgerUtil {
// cnpm 优先
if (this.shouldUseCnpm()) {
this.config.set('npm', 'cnpm')
}else if (this.shouldUseYarn()) {
} else if (this.shouldUseYarn()) {
this.config.set('npm', 'yarn')
} else {
this.config.set('npm', 'npm')
Expand Down
Loading

0 comments on commit 4ecbbad

Please sign in to comment.