From ae4310eee3463d4fb3fcb1855211466519e5495c Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 28 Mar 2017 09:24:37 +0200 Subject: [PATCH 1/3] fix(build): fix issue that `extends` in `ts-config.json` property is being ignored. --- src/build.ts | 34 ++++++++++++++++------------------ src/transpile.ts | 4 +++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/build.ts b/src/build.ts index e53d58ac..403d2f61 100644 --- a/src/build.ts +++ b/src/build.ts @@ -10,6 +10,7 @@ import { lint, lintUpdate } from './lint'; import { Logger } from './logger/logger'; import { minifyCss, minifyJs } from './minify'; import { ngc } from './ngc'; +import { getTsConfigAsync, TsConfig } from './transpile'; import { postprocess } from './postprocess'; import { preprocess, preprocessUpdate } from './preprocess'; import { sass, sassUpdate } from './sass'; @@ -34,20 +35,20 @@ export function build(context: BuildContext) { function buildWorker(context: BuildContext) { return Promise.resolve().then(() => { // load any 100% required files to ensure they exist - return validateRequiredFilesExist(); + return validateRequiredFilesExist(context); }) - .then(([_, tsConfigContents]) => { - return validateTsConfigSettings(tsConfigContents); - }) - .then(() => { - return buildProject(context); - }); + .then(([_, tsConfigContents]) => { + return validateTsConfigSettings(tsConfigContents); + }) + .then(() => { + return buildProject(context); + }); } -function validateRequiredFilesExist() { +function validateRequiredFilesExist(context: BuildContext) { return Promise.all([ readFileAsync(process.env[Constants.ENV_APP_ENTRY_POINT]), - readFileAsync(process.env[Constants.ENV_TS_CONFIG]) + getTsConfigAsync(context, process.env[Constants.ENV_TS_CONFIG]) ]).catch((error) => { if (error.code === 'ENOENT' && error.path === process.env[Constants.ENV_APP_ENTRY_POINT]) { error = new BuildError(`${error.path} was not found. The "main.dev.ts" and "main.prod.ts" files have been deprecated. Please create a new file "main.ts" containing the content of "main.dev.ts", and then delete the deprecated files. @@ -68,15 +69,12 @@ function validateRequiredFilesExist() { }); } -function validateTsConfigSettings(tsConfigFileContents: string) { +function validateTsConfigSettings(tsConfigFileContents: TsConfig) { return new Promise((resolve, reject) => { try { - const tsConfigJson = JSON.parse(tsConfigFileContents); - const isValid = tsConfigJson.hasOwnProperty('compilerOptions') && - tsConfigJson.compilerOptions.hasOwnProperty('sourceMap') && - tsConfigJson.compilerOptions.sourceMap === true; - + const isValid = tsConfigFileContents.options && + tsConfigFileContents.options.sourceMap === true; if (!isValid) { const error = new BuildError(['The "tsconfig.json" file must have compilerOptions.sourceMap set to true.', 'For more information please see the default Ionic project tsconfig.json file here:', @@ -285,7 +283,7 @@ function buildUpdateTasks(changedFiles: ChangedFile[], context: BuildContext) { filePath: outputCssFile }; - context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile}); + context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile }); resolveValue.changedFiles.push(changedFile); }); @@ -299,7 +297,7 @@ function buildUpdateTasks(changedFiles: ChangedFile[], context: BuildContext) { filePath: outputCssFile }; - context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile}); + context.fileCache.set(outputCssFile, { path: outputCssFile, content: outputCssFile }); resolveValue.changedFiles.push(changedFile); }); @@ -324,7 +322,7 @@ function loadFiles(changedFiles: ChangedFile[], context: BuildContext) { const promise = readFileAsync(changedFile.filePath); promises.push(promise); promise.then((content: string) => { - context.fileCache.set(changedFile.filePath, { path: changedFile.filePath, content: content}); + context.fileCache.set(changedFile.filePath, { path: changedFile.filePath, content: content }); }); } } diff --git a/src/transpile.ts b/src/transpile.ts index 4afeac39..d25332e8 100644 --- a/src/transpile.ts +++ b/src/transpile.ts @@ -333,11 +333,13 @@ function transpileBundleImpl(context: BuildContext, target: ts.ScriptTarget) { } } +export async function getTsConfigAsync(context: BuildContext, tsConfigPath?: string): Promise { + return await getTsConfig(context, tsConfigPath); +} export function getTsConfig(context: BuildContext, tsConfigPath?: string): TsConfig { let config: TsConfig = null; tsConfigPath = tsConfigPath || getTsConfigPath(context); - const tsConfigFile = ts.readConfigFile(tsConfigPath, path => readFileSync(path, 'utf8')); if (!tsConfigFile) { From d9a5a55e5105fe17f858d6c9e8afe8644b51674b Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 17 Apr 2017 15:47:15 +0200 Subject: [PATCH 2/3] fix merge --- src/transpile.ts | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/transpile.ts b/src/transpile.ts index ae6dbdbe..f0d9f697 100644 --- a/src/transpile.ts +++ b/src/transpile.ts @@ -300,39 +300,6 @@ function writeTranspiledFilesCallback(fileCache: FileCache, sourcePath: string, } } -export function transpileBundle(context: BuildContext, target: ts.ScriptTarget = ts.ScriptTarget.ES5) { - return Promise.resolve() - .then(() => { - return transpileBundleImpl(context, target); - }); -} - -function transpileBundleImpl(context: BuildContext, target: ts.ScriptTarget) { - const logger = new Logger('transpile bundle'); - try { - const files = readdirSync(context.buildDir); - files.forEach((file) => { - if (path.extname(file) === '.js' && file.indexOf('polyfills') === -1 && file.indexOf('sw-toolbox') === -1) { - const bundlePath = path.join(context.buildDir, file); - const bundleContent = readFileSync(bundlePath).toString(); - const tsConfig = getTsConfig(context); - const transpileOptions: ts.TranspileOptions = { - compilerOptions: tsConfig.options, - fileName: bundlePath, - reportDiagnostics: true - }; - // override the target value - transpileOptions.compilerOptions.target = target; - const transpiledOutput = ts.transpileModule(bundleContent, transpileOptions); - writeFileSync(bundlePath, transpiledOutput.outputText); - } - }); - logger.finish(); - } catch (ex) { - throw logger.fail(ex); - } -} - export async function getTsConfigAsync(context: BuildContext, tsConfigPath?: string): Promise { return await getTsConfig(context, tsConfigPath); } From eec97df049fba3148efa86bd8c35638a41dd6230 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 17 Apr 2017 22:03:39 +0200 Subject: [PATCH 3/3] fix unit tests --- src/build.spec.ts | 57 +++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/src/build.spec.ts b/src/build.spec.ts index 1a07154d..15a656d4 100644 --- a/src/build.spec.ts +++ b/src/build.spec.ts @@ -1,11 +1,11 @@ import * as Constants from './util/constants'; import { BuildContext } from './util/interfaces'; import * as helpers from './util/helpers'; -import * as build from './build'; +import * as build from './build'; import * as bundle from './bundle'; import * as copy from './copy'; -import * as clean from './clean'; +import * as clean from './clean'; import * as lint from './lint'; import * as minify from './minify'; import * as ngc from './ngc'; @@ -17,16 +17,15 @@ import * as transpile from './transpile'; describe('build', () => { beforeEach(() => { spyOn(clean, 'clean'); - spyOn(helpers, 'readFileAsync').and.callFake(() => { - return Promise.resolve(`{ - "compilerOptions": { + spyOn(helpers, helpers.readFileAsync.name).and.returnValue(Promise.resolve()); + spyOn(transpile, transpile.getTsConfigAsync.name).and.callFake(() => { + return Promise.resolve({ + "options": { "sourceMap": true } - } - `); + }); }); - spyOn(bundle, bundle.bundle.name).and.returnValue(Promise.resolve()); spyOn(copy, copy.copy.name).and.returnValue(Promise.resolve()); spyOn(minify, minify.minifyCss.name).and.returnValue(Promise.resolve()); @@ -135,7 +134,7 @@ describe('test project requirements before building', () => { spyOn(helpers, 'readFileAsync').and.returnValue(Promise.reject(error)); return build.build({}).catch((e) => { - expect(helpers.readFileAsync).toHaveBeenCalledTimes(2); + expect(helpers.readFileAsync).toHaveBeenCalledTimes(1); expect(e).toEqual(error); }); }); @@ -143,17 +142,14 @@ describe('test project requirements before building', () => { it('should fail if IONIC_TS_CONFIG file does not exist', () => { process.env[Constants.ENV_APP_ENTRY_POINT] = 'src/app/main.ts'; process.env[Constants.ENV_TS_CONFIG] = 'tsConfig.js'; - const error = new Error('App entry point was not found'); + const error = new Error('Config was not found'); - spyOn(helpers, 'readFileAsync').and.callFake((filePath: string) => { - if (filePath === 'src/app/main.ts') { - return Promise.resolve('allgood'); - } - return Promise.reject(error); - }); + spyOn(helpers, helpers.readFileAsync.name).and.returnValues(Promise.resolve()); + spyOn(transpile, transpile.getTsConfigAsync.name).and.returnValues(Promise.reject(error)); return build.build({}).catch((e) => { - expect(helpers.readFileAsync).toHaveBeenCalledTimes(2); + expect(transpile.getTsConfigAsync).toHaveBeenCalledTimes(1); + expect(helpers.readFileAsync).toHaveBeenCalledTimes(1); expect(e).toEqual(error); }); }); @@ -161,9 +157,9 @@ describe('test project requirements before building', () => { it('should fail fataly if IONIC_TS_CONFIG file does not contain valid JSON', () => { process.env[Constants.ENV_APP_ENTRY_POINT] = 'src/app/main.ts'; process.env[Constants.ENV_TS_CONFIG] = 'tsConfig.js'; - spyOn(helpers, 'readFileAsync').and.callFake(() => { + spyOn(transpile, transpile.getTsConfigAsync.name).and.callFake(() => { return Promise.resolve(`{ - "compilerOptions" { + "options" { "sourceMap": false } } @@ -171,7 +167,7 @@ describe('test project requirements before building', () => { }); return build.build({}).catch((e) => { - expect(helpers.readFileAsync).toHaveBeenCalledTimes(2); + expect(transpile.getTsConfigAsync).toHaveBeenCalledTimes(1); expect(e.isFatal).toBeTruthy(); }); }); @@ -179,9 +175,9 @@ describe('test project requirements before building', () => { it('should fail fataly if IONIC_TS_CONFIG file does not contain compilerOptions.sourceMap === true', () => { process.env[Constants.ENV_APP_ENTRY_POINT] = 'src/app/main.ts'; process.env[Constants.ENV_TS_CONFIG] = 'tsConfig.js'; - spyOn(helpers, 'readFileAsync').and.callFake(() => { + spyOn(transpile, transpile.getTsConfigAsync.name).and.callFake(() => { return Promise.resolve(`{ - "compilerOptions": { + "options": { "sourceMap": false } } @@ -189,7 +185,7 @@ describe('test project requirements before building', () => { }); return build.build({}).catch((e) => { - expect(helpers.readFileAsync).toHaveBeenCalledTimes(2); + expect(transpile.getTsConfigAsync).toHaveBeenCalledTimes(1); expect(e.isFatal).toBeTruthy(); }); }); @@ -208,18 +204,17 @@ describe('test project requirements before building', () => { spyOn(postprocess, postprocess.postprocess.name).and.returnValue(Promise.resolve()); spyOn(preprocess, preprocess.preprocess.name).and.returnValue(Promise.resolve()); spyOn(sass, sass.sass.name).and.returnValue(Promise.resolve()); + spyOn(helpers, helpers.readFileAsync.name).and.returnValue(Promise.resolve()); spyOn(transpile, transpile.transpile.name).and.returnValue(Promise.resolve()); - spyOn(helpers, helpers.readFileAsync.name).and.callFake(() => { - return Promise.resolve(`{ - "compilerOptions": { - "sourceMap": true - } + spyOn(transpile, transpile.getTsConfigAsync.name).and.returnValue(Promise.resolve({ + "options": { + "sourceMap": true } - `); - }); + })); return build.build({}).then(() => { - expect(helpers.readFileAsync).toHaveBeenCalledTimes(2); + expect(transpile.getTsConfigAsync).toHaveBeenCalledTimes(1); + expect(helpers.readFileAsync).toHaveBeenCalledTimes(1); }); }); });