build(offline compiler): package the compiler-cli for users
Closes #8341
This commit is contained in:
parent
ca13f1c024
commit
db95fd6ca9
11
gulpfile.js
11
gulpfile.js
@ -300,7 +300,14 @@ function doCheckFormat() {
|
|||||||
var clangFormat = require('clang-format');
|
var clangFormat = require('clang-format');
|
||||||
var gulpFormat = require('gulp-clang-format');
|
var gulpFormat = require('gulp-clang-format');
|
||||||
|
|
||||||
return gulp.src(['modules/**/*.ts', 'tools/**/*.ts', '!**/typings/**/*.d.ts', 'gulpfile.js'])
|
return gulp.src([
|
||||||
|
'modules/**/*.ts',
|
||||||
|
'tools/**/*.ts',
|
||||||
|
'!**/typings/**/*.d.ts',
|
||||||
|
// workaround https://github.com/angular/clang-format/issues/28
|
||||||
|
'!tools/compiler_cli/src/main.ts',
|
||||||
|
'gulpfile.js'
|
||||||
|
])
|
||||||
.pipe(gulpFormat.checkFormat('file', clangFormat));
|
.pipe(gulpFormat.checkFormat('file', clangFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,7 +1058,7 @@ gulp.task('!build.compiler_cli', ['build.js.cjs'],
|
|||||||
|
|
||||||
gulp.task('!test.compiler_cli.codegen', function(done) {
|
gulp.task('!test.compiler_cli.codegen', function(done) {
|
||||||
try {
|
try {
|
||||||
require('./dist/js/cjs/compiler_cli')
|
require('./dist/js/cjs/compiler_cli/main')
|
||||||
.main("tools/compiler_cli/test")
|
.main("tools/compiler_cli/test")
|
||||||
.then(function() { runTsc('tools/compiler_cli/test', done); })
|
.then(function() { runTsc('tools/compiler_cli/test', done); })
|
||||||
.catch(function(rej) { done(new Error(rej)); });
|
.catch(function(rej) { done(new Error(rej)); });
|
||||||
|
@ -10,16 +10,31 @@ requires that the compiler be included in the code downloaded to the client.
|
|||||||
You can produce smaller, faster applications by running Angular's compiler as a build step,
|
You can produce smaller, faster applications by running Angular's compiler as a build step,
|
||||||
and then downloading only the executable JS to the client.
|
and then downloading only the executable JS to the client.
|
||||||
|
|
||||||
|
## Install and use
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm install angular2-template-compiler typescript rxjs
|
||||||
|
# Optional sanity check, make sure TypeScript can compile
|
||||||
|
$ ./node_modules/.bin/tsc -p path/to/project
|
||||||
|
$ ./node_modules/.bin/ng2tc -p path/to/project
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to write a `bootstrap` that imports the generated code, you should first write your
|
||||||
|
top-level component, and run `ng2tc` once to produce a generated `.ngfactory.ts` file.
|
||||||
|
Then you can add an import statement in the `bootstrap` allowing you to bootstrap off the
|
||||||
|
generated code.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The `tsconfig.json` file is expected to contain an additional configuration block:
|
The `tsconfig.json` file may contain an additional configuration block:
|
||||||
```
|
```
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
"genDir": "."
|
"genDir": "."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
the `genDir` option controls the path (relative to `tsconfig.json`) where the generated file tree
|
the `genDir` option controls the path (relative to `tsconfig.json`) where the generated file tree
|
||||||
will be written. More options may be added as we implement more features.
|
will be written. If `genDir` is not set, then the code will be generated in the source tree, next
|
||||||
|
to your original sources. More options may be added as we implement more features.
|
||||||
|
|
||||||
We recommend you avoid checking generated files into version control. This permits a state where
|
We recommend you avoid checking generated files into version control. This permits a state where
|
||||||
the generated files in the repository were created from sources that were never checked in,
|
the generated files in the repository were created from sources that were never checked in,
|
||||||
@ -70,3 +85,11 @@ gulp build.js.cjs
|
|||||||
# Run it on the test project
|
# Run it on the test project
|
||||||
node ./dist/js/cjs/compiler_cli -p tools/compiler_cli/test
|
node ./dist/js/cjs/compiler_cli -p tools/compiler_cli/test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Release:
|
||||||
|
```
|
||||||
|
$ gulp test.compiler_cli
|
||||||
|
$ cp tools/compiler_cli/README.md tools/compiler_cli/package.json dist/js/cjs/compiler_cli
|
||||||
|
# npm login as angularcore
|
||||||
|
$ npm publish dist/js/cjs/compiler_cli
|
||||||
|
```
|
||||||
|
37
tools/compiler_cli/package.json
Normal file
37
tools/compiler_cli/package.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "angular2-template-compiler",
|
||||||
|
"version": "0.1.3",
|
||||||
|
"description": "Execute angular2 template compiler in nodejs.",
|
||||||
|
"main": "index.js",
|
||||||
|
"typings": "index.d.ts",
|
||||||
|
"bin": {
|
||||||
|
"ng2tc": "./main.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"angular2": "angular/angular#2.0.0-build.cacdead.js",
|
||||||
|
"ts-metadata-collector": "^0.1.0",
|
||||||
|
"tsickle": "^0.1.0",
|
||||||
|
"reflect-metadata": "^0.1.2",
|
||||||
|
"parse5": "1.3.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^1.8.0 || ^1.9.0-dev"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/angular/angular.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"angular",
|
||||||
|
"compiler"
|
||||||
|
],
|
||||||
|
"contributors": [
|
||||||
|
"Tobias Bosch <tbosch@google.com> (https://angular.io/)",
|
||||||
|
"Alex Eagle <alexeagle@google.com> (https://angular.io/)"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/angular/angular/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/angular/angular/tree/master/tools/compiler_cli"
|
||||||
|
}
|
@ -79,7 +79,7 @@ export class CodeGenerator {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
codegen() {
|
codegen(): Promise<void[]> {
|
||||||
Parse5DomAdapter.makeCurrent();
|
Parse5DomAdapter.makeCurrent();
|
||||||
const generateOneFile = (absSourcePath: string) =>
|
const generateOneFile = (absSourcePath: string) =>
|
||||||
Promise.all(this.readComponents(absSourcePath))
|
Promise.all(this.readComponents(absSourcePath))
|
||||||
|
@ -1,55 +1,3 @@
|
|||||||
// TODO(alexeagle): use --lib=node when available; remove this reference
|
export {CodeGenerator} from './codegen';
|
||||||
// https://github.com/Microsoft/TypeScript/pull/7757#issuecomment-205644657
|
export {NodeReflectorHost} from './reflector_host';
|
||||||
/// <reference path="../../typings/node/node.d.ts"/>
|
export {wrapCompilerHost, CodeGeneratorHost} from './compiler_host';
|
||||||
|
|
||||||
// Must be imported first, because angular2 decorators throws on load.
|
|
||||||
import 'reflect-metadata';
|
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as ts from 'typescript';
|
|
||||||
import {tsc, check} from './tsc';
|
|
||||||
|
|
||||||
import {CodeGenerator} from './codegen';
|
|
||||||
|
|
||||||
const DEBUG = false;
|
|
||||||
|
|
||||||
function debug(msg: string, ...o: any[]) {
|
|
||||||
if (DEBUG) console.log(msg, ...o);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function main(project: string, basePath?: string): Promise<number> {
|
|
||||||
// file names in tsconfig are resolved relative to this absolute path
|
|
||||||
basePath = path.join(process.cwd(), basePath || project);
|
|
||||||
|
|
||||||
// read the configuration options from wherever you store them
|
|
||||||
const {parsed, ngOptions} = tsc.readConfiguration(project, basePath);
|
|
||||||
|
|
||||||
const host = ts.createCompilerHost(parsed.options, true);
|
|
||||||
const {errors, generator} = CodeGenerator.create(ngOptions, parsed, basePath, host);
|
|
||||||
check(errors);
|
|
||||||
|
|
||||||
return generator.codegen()
|
|
||||||
// use our compiler host, which wraps the built-in one from TypeScript
|
|
||||||
// This allows us to add features like --stripDesignTimeDecorators to optimize your
|
|
||||||
// application more.
|
|
||||||
.then(() => tsc.typeCheckAndEmit(generator.host, generator.program))
|
|
||||||
.catch(rejected => {
|
|
||||||
console.error('Compile failed\n', rejected.message);
|
|
||||||
throw new Error(rejected);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLI entry point
|
|
||||||
if (require.main === module) {
|
|
||||||
const args = require('minimist')(process.argv.slice(2));
|
|
||||||
try {
|
|
||||||
main(args.p || args.project || '.', args.basePath)
|
|
||||||
.then(exitCode => process.exit(exitCode))
|
|
||||||
.catch(r => { process.exit(1); });
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e.stack);
|
|
||||||
console.error("Compilation failed");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
56
tools/compiler_cli/src/main.ts
Normal file
56
tools/compiler_cli/src/main.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// TODO(alexeagle): use --lib=node when available; remove this reference
|
||||||
|
// https://github.com/Microsoft/TypeScript/pull/7757#issuecomment-205644657
|
||||||
|
/// <reference path="../../typings/node/node.d.ts"/>
|
||||||
|
|
||||||
|
// Must be imported first, because angular2 decorators throws on load.
|
||||||
|
import 'reflect-metadata';
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
import {tsc, check} from './tsc';
|
||||||
|
|
||||||
|
import {CodeGenerator} from './codegen';
|
||||||
|
|
||||||
|
const DEBUG = false;
|
||||||
|
|
||||||
|
function debug(msg: string, ...o: any[]) {
|
||||||
|
if (DEBUG) console.log(msg, ...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function main(project: string, basePath?: string): Promise<any> {
|
||||||
|
// file names in tsconfig are resolved relative to this absolute path
|
||||||
|
basePath = path.join(process.cwd(), basePath || project);
|
||||||
|
|
||||||
|
// read the configuration options from wherever you store them
|
||||||
|
const {parsed, ngOptions} = tsc.readConfiguration(project, basePath);
|
||||||
|
|
||||||
|
const host = ts.createCompilerHost(parsed.options, true);
|
||||||
|
const {errors, generator} = CodeGenerator.create(ngOptions, parsed, basePath, host);
|
||||||
|
check(errors);
|
||||||
|
|
||||||
|
return generator.codegen()
|
||||||
|
// use our compiler host, which wraps the built-in one from TypeScript
|
||||||
|
// This allows us to add features like --stripDesignTimeDecorators to optimize your
|
||||||
|
// application more.
|
||||||
|
.then(() => tsc.typeCheckAndEmit(generator.host, generator.program))
|
||||||
|
.catch(rejected => {
|
||||||
|
console.error('Compile failed\n', rejected.message);
|
||||||
|
throw new Error(rejected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLI entry point
|
||||||
|
if (require.main === module) {
|
||||||
|
const args = require('minimist')(process.argv.slice(2));
|
||||||
|
try {
|
||||||
|
main(args.p || args.project || '.', args.basePath)
|
||||||
|
.then(exitCode => process.exit(exitCode))
|
||||||
|
.catch(r => { process.exit(1); });
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e.stack);
|
||||||
|
console.error("Compilation failed");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ export class NodeReflectorHost implements StaticReflectorHost {
|
|||||||
* they are resolvable by the moduleResolution strategy from the CompilerHost.
|
* they are resolvable by the moduleResolution strategy from the CompilerHost.
|
||||||
*/
|
*/
|
||||||
private getModuleId(declarationFile: string, containingFile: string) {
|
private getModuleId(declarationFile: string, containingFile: string) {
|
||||||
const parts = declarationFile.replace(EXT, '').split(path.sep);
|
const parts = declarationFile.replace(EXT, '').split(path.sep).filter(p => !!p);
|
||||||
|
|
||||||
for (let index = parts.length - 1; index >= 0; index--) {
|
for (let index = parts.length - 1; index >= 0; index--) {
|
||||||
let candidate = parts.slice(index, parts.length).join(path.sep);
|
let candidate = parts.slice(index, parts.length).join(path.sep);
|
||||||
@ -51,7 +51,7 @@ export class NodeReflectorHost implements StaticReflectorHost {
|
|||||||
throw new Error("Resolution of relative paths requires a containing file.");
|
throw new Error("Resolution of relative paths requires a containing file.");
|
||||||
}
|
}
|
||||||
// Any containing file gives the same result for absolute imports
|
// Any containing file gives the same result for absolute imports
|
||||||
containingFile = 'index.ts';
|
containingFile = path.join(this.compilerHost.getCurrentDirectory(), 'index.ts');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user