Skip to content

Commit

Permalink
Change to use incremental builds API
Browse files Browse the repository at this point in the history
Add debug and time logging
Minor re-factoring
Update unit tests

Urigo/angular2-meteor#102
  • Loading branch information
barbatus committed Mar 7, 2016
1 parent 4cac0d7 commit 80c0425
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 75 deletions.
29 changes: 29 additions & 0 deletions debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const util = Npm.require('util');

DebugLog = class DebugLog {
constructor(event) {
this.debug = process.env.TYPESCRIPT_DEBUG;
this.event = event;
this.start();
}

start() {
if (this.debug) {
console.log('%s started', this.event);
console.time(util.format('%s time', this.event));
}
}


log(msg, ...args) {
if (this.debug) {
console.log.apply(null, [msg].concat(args));
}
}

end() {
if (this.debug) {
console.timeEnd(util.format('%s time', this.event));
}
}
};
10 changes: 10 additions & 0 deletions file-mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FileMixin = {
warn(error) {
console.log(`${error.sourcePath} (${error.line}, ${error.column}): ${error.message}`);
},

isBare() {
let fileOptions = this.getFileOptions();
return fileOptions.bare;
}
};
6 changes: 4 additions & 2 deletions package.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Package.describe({
name: 'barbatus:typescript-compiler',
version: '0.5.0-beta.5',
version: '0.5.0-beta.6',
summary: 'TypeScript Compiler for Meteor',
git: 'https://github.com/barbatus/ts-compilers',
documentation: 'README.md'
});

Npm.depends({
'meteor-typescript': '0.6.0-beta.2',
'meteor-typescript': 'https://github.com/barbatus/meteor-typescript/tarball/52fc6c7f3b5b5df9483a927bc96e7a901b61c4ab',
'async': '1.4.0'
});

Expand All @@ -19,6 +19,8 @@ Package.onUse(function(api) {
], 'server');

api.addFiles([
'debug.js',
'file-mixin.js',
'typescript-compiler.js',
'typescript.js'
], 'server');
Expand Down
14 changes: 6 additions & 8 deletions tests/server/unit/compiler-tests_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ describe('typescript-compiler', () => {

describe('testing diagnostics', () => {
it('should log out diagnostics by default', () => {
let logger = jasmine.createSpy();
let compiler = new TypeScriptCompiler(null, null, logger);
let compiler = new TypeScriptCompiler();

let configFile = new ConfigFile({
compilerOptions: {
Expand All @@ -57,18 +56,17 @@ describe('typescript-compiler', () => {
});
let wrongImport = 'import {api} from "lib";';
let inputFile = new InputFile(wrongImport, 'foo4.ts');
inputFile.warn = jasmine.createSpy();
compiler.processFilesForTarget([inputFile, configFile]);

expect(logger).toHaveBeenCalled();
expect(logger.calls.first().args[0]).toBeDefined();
expect(inputFile.warn).toHaveBeenCalled();
expect(inputFile.warn.calls.first().args[0]).toBeDefined();
});
});

describe('testing modules', () => {
it('should render bare source code if module is none', () => {
let compiler = new TypeScriptCompiler({
module: 'none'
});
it('should render bare source code if there is no ES6 exports', () => {
let compiler = new TypeScriptCompiler();
let moduleFoo = 'module foo {}';
let inputFile = new InputFile(moduleFoo, 'foo5.ts');
compiler.processFilesForTarget([inputFile]);
Expand Down
4 changes: 4 additions & 0 deletions tests/server/unit/input-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ InputFile = class InputFile {
getArch() {
return 'os';
}

warn(error) {
this.error = error;
}
}

ConfigFile = class ConfigFile extends InputFile {
Expand Down
134 changes: 71 additions & 63 deletions typescript-compiler.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,106 @@
'use strict';

const async = Npm.require('async');
const Future = Npm.require('fibers/future');
const TSBuild = Npm.require('meteor-typescript').TSBuild;

TypeScriptCompiler = class TypeScriptCompiler {
constructor(extraOptions, maxParallelism, logFn) {
constructor(extraOptions, maxParallelism) {
TypeScript.validateExtraOptions(extraOptions);

this.extraOptions = extraOptions;
this.maxParallelism = maxParallelism || 10;
this.tsconfig = null;
this.tsconfig = TypeScript.getDefaultOptions();
this.cfgHash = null;
this.logFn = logFn || console.log;
}

processFilesForTarget(inputFiles) {
this.extendFiles(inputFiles);

// If tsconfig.json has changed, create new one.
this.processConfig(inputFiles);

let filesSourceMap = new Map();
let archMap = {};
let filesMap = {};
inputFiles.forEach((inputFile, index) => {
if (this.isConfigFile(inputFile)) return;

filesSourceMap.set(this.getExtendedPath(inputFile), index);
let arch = inputFile.getArch();
let archFiles = archMap[arch];
if (! archFiles) {
archFiles = [];
archMap[arch] = archFiles;
}
archFiles.push(inputFile);
filesMap[this.getExtendedPath(inputFile)] = index;
});

let getFileContent = filePath => {
let index = filesSourceMap.get(filePath);
let index = filesMap[filePath];
return index !== undefined ?
inputFiles[index].getContentsAsString() : null;
};

// Filters out typings and tsconfig.
// Other files should be compiled.
let tsFiles = inputFiles.filter(inputFile =>
!(this.isConfigFile(inputFile) || this.isDeclarationFile(inputFile)));
// Assemble options.
let typings = this.tsconfig.typings;
let compilerOptions = this.tsconfig.compilerOptions;
compilerOptions = TypeScript.getCompilerOptions(
compilerOptions, this.extraOptions);
let buildOptions = { compilerOptions, typings };

let compileDebug = new DebugLog('compilation');
const future = new Future;
async.eachLimit(tsFiles, this.maxParallelism, (inputFile, cb) => {
let compilerOptions = this.tsconfig ?
this.tsconfig.compilerOptions : null;

compilerOptions = TypeScript.getCompilerOptions(
compilerOptions, this.extraOptions);

let source = inputFile.getContentsAsString();
let inputFilePath = inputFile.getPathInPackage();
let outputFilePath = removeTsExt(inputFilePath) + '.js';
let toBeAdded = {
sourcePath: inputFilePath,
path: outputFilePath,
data: source,
hash: inputFile.getSourceHash(),
sourceMap: null,
bare: this.isBareFile(inputFile, compilerOptions)
};

let filePath = this.getExtendedPath(inputFile);
let typings = this.tsconfig ? this.tsconfig.typings : [];
let moduleName = this.getFileModuleName(inputFile, compilerOptions);
let arch = inputFile.getArch();
let tsOptions = {
compilerOptions,
moduleName,
filePath,
typings,
arch
};

let error = null;
try {
let result = TypeScript.compile(getFileContent, tsOptions);
this.processDiagnostics(inputFile,
result.diagnostics, compilerOptions);
async.each(_.keys(archMap), (arch, cb) => {
let archFiles = archMap[arch];
let filePaths = archFiles.map(inputFile => this.getExtendedPath(inputFile));
compileDebug.log('process files: %s', filePaths);
buildOptions.arch = arch;

let buildDebug = new DebugLog('tsBuild');
let tsBuild = new TSBuild(filePaths, getFileContent, buildOptions);

archFiles.forEach(inputFile => {
if (this.isDeclarationFile(inputFile)) return;

let co = compilerOptions;
let source = inputFile.getContentsAsString();
let inputFilePath = inputFile.getPathInPackage();
let outputFilePath = removeTsExt(inputFilePath) + '.js';
let toBeAdded = {
sourcePath: inputFilePath,
path: outputFilePath,
data: source,
hash: inputFile.getSourceHash(),
sourceMap: null,
bare: inputFile.isBare()
};

let filePath = this.getExtendedPath(inputFile);
let moduleName = this.getFileModuleName(inputFile, co);

let emitDebug = new DebugLog('tsEmit');
let result = tsBuild.emit(filePath, moduleName);
this.processDiagnostics(inputFile, result.diagnostics, co);
emitDebug.end();

toBeAdded.data = result.code;
toBeAdded.bare = toBeAdded.bare || ! result.isExternal;
toBeAdded.hash = result.hash;
toBeAdded.sourceMap = result.sourceMap;

inputFile.addJavaScript(toBeAdded);
} catch (e) {
error = e;
} finally {
cb(error);
}
});

cb();

buildDebug.end();
}, future.resolver());

future.wait();

compileDebug.end();
}

extendFiles(inputFiles) {
inputFiles.forEach(inputFile => _.defaults(inputFile, FileMixin));
}

processDiagnostics(inputFile, diagnostics, compilerOptions) {
Expand All @@ -104,13 +120,12 @@ TypeScriptCompiler = class TypeScriptCompiler {
// And log out other errors except package files.
if (compilerOptions && compilerOptions.diagnostics) {
diagnostics.semanticErrors.forEach(diagnostic => {
let error = {
inputFile.warn({
message: diagnostic.message,
sourcePath: this.getExtendedPath(inputFile),
line: diagnostic.line,
column: diagnostic.column
};
this.logFn(`${error.sourcePath} (${error.line}, ${error.column}): ${error.message}`);
});
});
}
}
Expand All @@ -125,13 +140,6 @@ TypeScriptCompiler = class TypeScriptCompiler {
return noExt ? removeTsExt(filePath) : filePath;
}

isBareFile(inputFile, compilerOptions) {
let fileOptions = inputFile.getFileOptions();
let packageName = inputFile.getPackageName();
return (fileOptions.bare ||
(! packageName && compilerOptions.module === 'none'));
}

getFileModuleName(inputFile, options) {
return options.module !== 'none' ?
this.getExtendedPath(inputFile, true): null;
Expand Down
2 changes: 0 additions & 2 deletions typescript.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

const meteorTS = Npm.require('meteor-typescript');

TypeScript = {
Expand Down

0 comments on commit 80c0425

Please sign in to comment.