feat(tsc-wrapped): Support of vinyl like config file was added (#13987)
This feature was implemented in order to provide easier way of use in gulp
This commit is contained in:
parent
83361d811d
commit
0c7726dd74
|
@ -15,6 +15,7 @@ import {check, tsc} from './tsc';
|
|||
import NgOptions from './options';
|
||||
import {MetadataWriterHost, DecoratorDownlevelCompilerHost, TsickleCompilerHost} from './compiler_host';
|
||||
import {CliOptions} from './cli_options';
|
||||
import {VinylFile, isVinylFile} from './vinyl_file';
|
||||
|
||||
export {UserError} from './tsc';
|
||||
|
||||
|
@ -23,11 +24,16 @@ export type CodegenExtension =
|
|||
Promise<void>;
|
||||
|
||||
export function main(
|
||||
project: string, cliOptions: CliOptions, codegen?: CodegenExtension,
|
||||
project: string | VinylFile, cliOptions: CliOptions, codegen?: CodegenExtension,
|
||||
options?: ts.CompilerOptions): Promise<any> {
|
||||
try {
|
||||
let projectDir = project;
|
||||
if (fs.lstatSync(project).isFile()) {
|
||||
// project is vinyl like file object
|
||||
if (isVinylFile(project)) {
|
||||
projectDir = path.dirname(project.path);
|
||||
}
|
||||
// project is path to project file
|
||||
else if (fs.lstatSync(project).isFile()) {
|
||||
projectDir = path.dirname(project);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import * as path from 'path';
|
|||
import * as ts from 'typescript';
|
||||
|
||||
import AngularCompilerOptions from './options';
|
||||
import {VinylFile, isVinylFile} from './vinyl_file';
|
||||
|
||||
/**
|
||||
* Our interface to the TypeScript standard compiler.
|
||||
|
@ -18,7 +19,8 @@ import AngularCompilerOptions from './options';
|
|||
* you should implement a similar interface.
|
||||
*/
|
||||
export interface CompilerInterface {
|
||||
readConfiguration(project: string, basePath: string, existingOptions?: ts.CompilerOptions):
|
||||
readConfiguration(
|
||||
project: string|VinylFile, basePath: string, existingOptions?: ts.CompilerOptions):
|
||||
{parsed: ts.ParsedCommandLine, ngOptions: AngularCompilerOptions};
|
||||
typeCheck(compilerHost: ts.CompilerHost, program: ts.Program): void;
|
||||
emit(program: ts.Program): number;
|
||||
|
@ -97,20 +99,30 @@ export class Tsc implements CompilerInterface {
|
|||
|
||||
constructor(private readFile = ts.sys.readFile, private readDirectory = ts.sys.readDirectory) {}
|
||||
|
||||
readConfiguration(project: string, basePath: string, existingOptions?: ts.CompilerOptions) {
|
||||
readConfiguration(
|
||||
project: string|VinylFile, basePath: string, existingOptions?: ts.CompilerOptions) {
|
||||
this.basePath = basePath;
|
||||
|
||||
// Allow a directory containing tsconfig.json as the project value
|
||||
// Note, TS@next returns an empty array, while earlier versions throw
|
||||
try {
|
||||
if (this.readDirectory(project).length > 0) {
|
||||
if (!isVinylFile(project) && this.readDirectory(project).length > 0) {
|
||||
project = path.join(project, 'tsconfig.json');
|
||||
}
|
||||
} catch (e) {
|
||||
// Was not a directory, continue on assuming it's a file
|
||||
}
|
||||
|
||||
const {config, error} = ts.readConfigFile(project, this.readFile);
|
||||
let {config, error} = (() => {
|
||||
// project is vinyl like file object
|
||||
if (isVinylFile(project)) {
|
||||
return {config: JSON.parse(project.contents.toString()), error: null};
|
||||
}
|
||||
// project is path to project file
|
||||
else {
|
||||
return ts.readConfigFile(project, this.readFile);
|
||||
}
|
||||
})();
|
||||
check([error]);
|
||||
|
||||
// Do not inline `host` into `parseJsonConfigFileContent` until after
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
export interface VinylFile extends Object {
|
||||
// Absolute path to the virtual file
|
||||
path: string;
|
||||
|
||||
// Content of the virtual file
|
||||
contents: Buffer;
|
||||
}
|
||||
;
|
||||
|
||||
export function isVinylFile(obj: any): obj is VinylFile {
|
||||
return (typeof obj === 'object') && ('path' in obj) && ('contents' in obj);
|
||||
};
|
|
@ -91,6 +91,35 @@ describe('tsc-wrapped', () => {
|
|||
.catch(e => done.fail(e));
|
||||
});
|
||||
|
||||
it('should pre-process sources using config from vinyl like object', (done) => {
|
||||
const config = {
|
||||
path: basePath + '/tsconfig.json',
|
||||
contents: new Buffer(JSON.stringify({
|
||||
compilerOptions: {
|
||||
experimentalDecorators: true,
|
||||
types: [],
|
||||
outDir: 'built',
|
||||
declaration: true,
|
||||
moduleResolution: 'node',
|
||||
target: 'es2015'
|
||||
},
|
||||
angularCompilerOptions: {annotateForClosureCompiler: true},
|
||||
files: ['test.ts']
|
||||
}))
|
||||
};
|
||||
|
||||
main(config, {basePath})
|
||||
.then(() => {
|
||||
const out = readOut('js');
|
||||
// Expand `export *` and fix index import
|
||||
expect(out).toContain(`export { A, B } from './dep/index'`);
|
||||
// Annotated for Closure compiler
|
||||
expect(out).toContain('* @param {?} x');
|
||||
done();
|
||||
})
|
||||
.catch(e => done.fail(e));
|
||||
});
|
||||
|
||||
it('should allow all options disabled', (done) => {
|
||||
write('tsconfig.json', `{
|
||||
"compilerOptions": {
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
*/
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import {Tsc} from '../src/tsc';
|
||||
import {Tsc, tsc as pureTsc} from '../src/tsc';
|
||||
import {VinylFile} from '../src/vinyl_file';
|
||||
|
||||
describe('options parsing', () => {
|
||||
|
||||
const tsc = new Tsc(
|
||||
() => `
|
||||
const configData = `
|
||||
{
|
||||
"angularCompilerOptions": {
|
||||
"googleClosureOutput": true
|
||||
|
@ -21,8 +21,10 @@ describe('options parsing', () => {
|
|||
"module": "commonjs",
|
||||
"outDir": "built"
|
||||
}
|
||||
}`,
|
||||
() => ['tsconfig.json']);
|
||||
}`;
|
||||
|
||||
const tsc = new Tsc(() => configData, () => ['tsconfig.json']);
|
||||
const config = {path: 'basePath/tsconfig.json', contents: new Buffer(configData)};
|
||||
|
||||
it('should combine all options into ngOptions', () => {
|
||||
const {parsed, ngOptions} =
|
||||
|
@ -37,4 +39,16 @@ describe('options parsing', () => {
|
|||
target: ts.ScriptTarget.ES2015
|
||||
});
|
||||
});
|
||||
|
||||
it('should combine all options into ngOptions from vinyl like object', () => {
|
||||
const {parsed, ngOptions} = pureTsc.readConfiguration(config as VinylFile, 'basePath');
|
||||
|
||||
expect(ngOptions).toEqual({
|
||||
genDir: 'basePath',
|
||||
googleClosureOutput: true,
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
outDir: 'basePath/built',
|
||||
configFilePath: undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue