fix(compiler): use rootDirs compilerOption to affect genDir layout.

Also update package.json to something releasable.
This commit is contained in:
Alex Eagle 2016-05-03 11:50:55 -06:00
parent b98c9e74e1
commit a033f8335b
4 changed files with 40 additions and 24 deletions

View File

@ -1,11 +1,11 @@
{ {
"name": "angular2-template-compiler", "name": "@angular/compiler-cli",
"version": "0.1.9", "version": "0.2.0",
"description": "Execute angular2 template compiler in nodejs.", "description": "Execute angular2 template compiler in nodejs.",
"main": "index.js", "main": "index.js",
"typings": "index.d.ts", "typings": "index.d.ts",
"bin": { "bin": {
"ng2tc": "./main.js" "ngc": "./main.js"
}, },
"dependencies": { "dependencies": {
"ts-metadata-collector": "^0.1.0", "ts-metadata-collector": "^0.1.0",
@ -14,10 +14,10 @@
"parse5": "1.3.2" "parse5": "1.3.2"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^1.8.0 || ^1.9.0-dev", "typescript": "^1.9.0-dev",
"@angular/compiler": "^0.0.0-5", "@angular/compiler": "^2.0.0-rc",
"@angular/platform-server": "^0.0.0-5", "@angular/platform-server": "^2.0.0-rc",
"@angular/core": "^0.0.0-5" "@angular/core": "^2.0.0-rc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -31,6 +31,8 @@ const PREAMBLE = `/**
*/ */
`; `;
// TODO(alexeagle): we end up passing options and ngOptions everywhere.
// Maybe this should extend ts.CompilerOptions so we only need this one.
export interface AngularCompilerOptions { export interface AngularCompilerOptions {
// Absolute path to a directory where generated file structure is written // Absolute path to a directory where generated file structure is written
genDir: string; genDir: string;
@ -46,10 +48,13 @@ export interface AngularCompilerOptions {
// Lookup angular's symbols using the old angular2/... npm namespace. // Lookup angular's symbols using the old angular2/... npm namespace.
legacyPackageLayout: boolean; legacyPackageLayout: boolean;
// Print extra information while running the compiler
trace: boolean;
} }
export class CodeGenerator { export class CodeGenerator {
constructor(private ngOptions: AngularCompilerOptions, private basePath: string, constructor(private options: ts.CompilerOptions, private ngOptions: AngularCompilerOptions,
private program: ts.Program, public host: ts.CompilerHost, private program: ts.Program, public host: ts.CompilerHost,
private staticReflector: StaticReflector, private resolver: CompileMetadataResolver, private staticReflector: StaticReflector, private resolver: CompileMetadataResolver,
private compiler: compiler.OfflineCompiler, private compiler: compiler.OfflineCompiler,
@ -91,16 +96,29 @@ export class CodeGenerator {
return result; return result;
} }
// Write codegen in a directory structure matching the sources.
private calculateEmitPath(filePath: string) {
let root = this.ngOptions.basePath;
for (let eachRootDir of this.options.rootDirs || []) {
if (this.ngOptions.trace) {
console.log(
`Check if ${filePath} is under rootDirs element ${eachRootDir}`);
}
if (path.relative(eachRootDir, filePath).indexOf('.') !== 0) {
root = eachRootDir;
}
}
return path.join(this.ngOptions.genDir, path.relative(root, filePath));
}
// TODO(tbosch): add a cache for shared css files // TODO(tbosch): add a cache for shared css files
// TODO(tbosch): detect cycles! // TODO(tbosch): detect cycles!
private generateStylesheet(filepath: string, shim: boolean): Promise<any> { private generateStylesheet(filepath: string, shim: boolean): Promise<any> {
return this.compiler.loadAndCompileStylesheet(filepath, shim, '.ts') return this.compiler.loadAndCompileStylesheet(filepath, shim, '.ts')
.then((sourceWithImports) => { .then((sourceWithImports) => {
// Write codegen in a directory structure matching the sources. const emitPath = this.calculateEmitPath(sourceWithImports.source.moduleUrl);
// TODO(alexeagle): relativize paths by the rootDirs option // TODO(alexeagle): should include the sourceFile to the WriteFileCallback
const emitPath =
path.join(this.ngOptions.genDir,
path.relative(this.basePath, sourceWithImports.source.moduleUrl));
this.host.writeFile(emitPath, PREAMBLE + sourceWithImports.source.source, false); this.host.writeFile(emitPath, PREAMBLE + sourceWithImports.source.source, false);
return Promise.all( return Promise.all(
sourceWithImports.importedUrls.map(url => this.generateStylesheet(url, shim))); sourceWithImports.importedUrls.map(url => this.generateStylesheet(url, shim)));
@ -128,11 +146,7 @@ export class CodeGenerator {
}); });
const generated = this.generateSource(metadatas); const generated = this.generateSource(metadatas);
const sourceFile = this.program.getSourceFile(absSourcePath); const sourceFile = this.program.getSourceFile(absSourcePath);
const emitPath = this.calculateEmitPath(generated.moduleUrl);
// Write codegen in a directory structure matching the sources.
// TODO(alexeagle): relativize paths by the rootDirs option
const emitPath = path.join(this.ngOptions.genDir,
path.relative(this.basePath, generated.moduleUrl));
this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {}, this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {},
[sourceFile]); [sourceFile]);
return Promise.all(stylesheetPromises); return Promise.all(stylesheetPromises);
@ -161,7 +175,7 @@ export class CodeGenerator {
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector), new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
new compiler.ViewResolver(staticReflector), null, null, staticReflector); new compiler.ViewResolver(staticReflector), null, null, staticReflector);
return new CodeGenerator(ngOptions, ngOptions.basePath, program, compilerHost, staticReflector, return new CodeGenerator(options, ngOptions, program, compilerHost,
resolver, offlineCompiler, reflectorHost); staticReflector, resolver, offlineCompiler, reflectorHost);
} }
} }

View File

@ -42,10 +42,9 @@ export function main(project: string, basePath?: string): Promise<any> {
const errors = program.getOptionsDiagnostics(); const errors = program.getOptionsDiagnostics();
check(errors); check(errors);
const doCodegen = const doCodegen = ngOptions.skipTemplateCodegen ?
ngOptions.skipTemplateCodegen ? Promise.resolve(null) :
Promise.resolve(null) : CodeGenerator.create(ngOptions, program, parsed.options, host).codegen();
CodeGenerator.create(ngOptions, program, parsed.options, host).codegen();
return doCodegen.then(() => { return doCodegen.then(() => {
tsc.typeCheck(host, program); tsc.typeCheck(host, program);

View File

@ -59,6 +59,9 @@ export class NodeReflectorHost implements StaticReflectorHost, ImportGenerator {
// TODO(tbosch): if a file does not yet exist (because we compile it later), // TODO(tbosch): if a file does not yet exist (because we compile it later),
// we still need to create it so that the `resolve` method works! // we still need to create it so that the `resolve` method works!
if (!this.compilerHost.fileExists(importedFile)) { if (!this.compilerHost.fileExists(importedFile)) {
if (this.ngOptions.trace) {
console.log(`Generating empty file ${importedFile} to allow resolution of import`);
}
this.compilerHost.writeFile(importedFile, '', false); this.compilerHost.writeFile(importedFile, '', false);
fs.writeFileSync(importedFile, ''); fs.writeFileSync(importedFile, '');
} }