Skip to content

Commit f0477e1

Browse files
committed
chore(build): add typescript to the cjs build.
Refactor the file extension logic in traceur plugin to simplify
1 parent b5002fb commit f0477e1

8 files changed

Lines changed: 154 additions & 55 deletions

File tree

Brocfile-js_cjs.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ var Funnel = require('broccoli-funnel');
22
var mergeTrees = require('broccoli-merge-trees');
33
var stew = require('broccoli-stew');
44
var TraceurCompiler = require('./tools/broccoli/traceur');
5+
var TypescriptCompiler = require('./tools/broccoli/typescript');
56
var renderLodashTemplate = require('broccoli-lodash');
67

7-
var modulesTree = new Funnel('modules', {include: ['**/**'], exclude: ['angular2/src/core/zone/vm_turn_zone.es6']});
8+
var modulesTree = new Funnel(
9+
'modules', {include: ['**/**'], exclude: ['angular2/src/core/zone/vm_turn_zone.es6']});
810

9-
// Use Traceur to transpile original sources to ES6
10-
var cjsTree = new TraceurCompiler(modulesTree, '.js', {
11+
// Use Traceur to transpile original sources to ES5
12+
var traceurOpts = {
1113
sourceMaps: true,
1214
annotations: true, // parse annotations
1315
types: true, // parse types
@@ -17,18 +19,13 @@ var cjsTree = new TraceurCompiler(modulesTree, '.js', {
1719
// Don't use type assertions since this is partly transpiled by typescript
1820
typeAssertions: false,
1921
modules: 'commonjs'
20-
}, true);
21-
22-
// Munge the filenames since we use an '.es6' extension
23-
cjsTree = stew.rename(cjsTree, function(relativePath) {
24-
return relativePath.replace(/\.(js|es6)\.map$/, '.map').replace(/\.es6$/, '.js');
25-
});
22+
};
23+
var cjsTree = new TraceurCompiler(modulesTree, '.js', '.map', traceurOpts);
2624

27-
// Now we add a few more files to the es6 tree that Traceur should not see
25+
// Add the LICENSE file in each module
2826
['angular2', 'benchmarks', 'benchmarks_external', 'benchpress', 'examples', 'rtts_assert'].forEach(
2927
function(destDir) {
30-
var extras = new Funnel('.', {files: ['LICENSE'], destDir: destDir});
31-
cjsTree = mergeTrees([cjsTree, extras]);
28+
cjsTree = mergeTrees([cjsTree, new Funnel('.', {files: ['LICENSE'], destDir: destDir})]);
3229
});
3330

3431
extras = new Funnel(modulesTree, {include: ['**/*.md', '**/*.png'], exclude: ['**/*.dart.md']});
@@ -53,12 +50,25 @@ var COMMON_PACKAGE_JSON = {
5350
};
5451

5552
// Add a .template extension since renderLodashTemplate strips one extension
56-
var packageJsons = stew.rename(new Funnel(modulesTree, {include: ['**/package.json']}), '.json', '.json.template');
57-
packageJsons = renderLodashTemplate(packageJsons, {
58-
files: ["**/**"],
59-
context: { 'packageJson': COMMON_PACKAGE_JSON }
53+
var packageJsons =
54+
stew.rename(new Funnel(modulesTree, {include: ['**/package.json']}), '.json', '.json.template');
55+
packageJsons = renderLodashTemplate(
56+
packageJsons, {files: ["**/**"], context: {'packageJson': COMMON_PACKAGE_JSON}});
57+
58+
var typescriptTree = new TypescriptCompiler(modulesTree, {
59+
target: 'ES5',
60+
sourceMap: true,
61+
mapRoot: '', /* force sourcemaps to use relative path */
62+
module: /*system.js*/'commonjs',
63+
allowNonTsExtensions: false,
64+
typescript: require('typescript'),
65+
//declarationFiles: true,
66+
noEmitOnError: true,
67+
outDir: 'angular2'
6068
});
6169

70+
// For now, we just overwrite the Traceur-compiled files with their Typescript equivalent
71+
cjsTree = mergeTrees([cjsTree, typescriptTree], { overwrite: true });
6272
cjsTree = mergeTrees([cjsTree, extras, packageJsons]);
6373

6474
module.exports = stew.mv(cjsTree, 'js/cjs');

Brocfile-js_dev.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var path = require('path');
1010
var modulesTree = new Funnel('modules', {include: ['**/**'], exclude: ['**/*.cjs'], destDir: '/'});
1111

1212
// Use Traceur to transpile original sources to ES6
13-
var es6DevTree = new TraceurCompiler(modulesTree, '.es6', {
13+
var es6DevTree = new TraceurCompiler(modulesTree, '.es6', '.map', {
1414
sourceMaps: true,
1515
annotations: true, // parse annotations
1616
types: true, // parse types
@@ -21,14 +21,9 @@ var es6DevTree = new TraceurCompiler(modulesTree, '.es6', {
2121
typeAssertions: true,
2222
outputLanguage: 'es6'
2323
});
24-
// Munge the filenames since we use an '.es6' extension
25-
es6DevTree = stew.rename(es6DevTree, function(relativePath) {
26-
return relativePath.replace(/\.(js|es6)\.map$/, '.map').replace(/\.js$/, '.es6');
27-
});
2824

2925
// Call Traceur again to lower the ES6 build tree to ES5
30-
var es5DevTree = new TraceurCompiler(es6DevTree, '.js', {modules: 'instantiate', sourceMaps: true});
31-
es5DevTree = stew.rename(es5DevTree, '.es6.map', '.js.map');
26+
var es5DevTree = new TraceurCompiler(es6DevTree, '.js', '.js.map', {modules: 'instantiate', sourceMaps: true});
3227

3328
// Now we add a few more files to the es6 tree that Traceur should not see
3429
['angular2', 'benchmarks', 'benchmarks_external', 'benchpress', 'examples', 'rtts_assert'].forEach(

Brocfile-js_prod.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var path = require('path');
1010
var modulesTree = new Funnel('modules', {include: ['**/**'], destDir: '/'});
1111

1212
// Use Traceur to transpile original sources to ES6
13-
var es6ProdTree = new TraceurCompiler(modulesTree, '.es6', {
13+
var es6ProdTree = new TraceurCompiler(modulesTree, '.es6', '.map', {
1414
sourceMaps: true,
1515
annotations: true, // parse annotations
1616
types: true, // parse types
@@ -21,14 +21,9 @@ var es6ProdTree = new TraceurCompiler(modulesTree, '.es6', {
2121
typeAssertions: false,
2222
outputLanguage: 'es6'
2323
});
24-
// Munge the filenames since we use an '.es6' extension
25-
es6ProdTree = stew.rename(es6ProdTree, function(relativePath) {
26-
return relativePath.replace(/\.(js|es6)\.map$/, '.map').replace(/\.js$/, '.es6');
27-
});
2824

2925
// Call Traceur again to lower the ES6 build tree to ES5
30-
var es5ProdTree = new TraceurCompiler(es6ProdTree, '.js', {modules: 'instantiate', sourceMaps: true});
31-
es5ProdTree = stew.rename(es5ProdTree, '.es6.map', '.js.map');
26+
var es5ProdTree = new TraceurCompiler(es6ProdTree, '.js', '.js.map', {modules: 'instantiate', sourceMaps: true});
3227

3328
// Now we add a few more files to the es6 tree that Traceur should not see
3429
['angular2', 'benchmarks', 'benchmarks_external', 'benchpress', 'examples', 'rtts_assert'].forEach(

gulpfile.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,10 +761,6 @@ gulp.task('broccoli.js.cjs', function() {
761761
gulp.task('build.js.cjs', function(done) {
762762
runSequence(
763763
'broccoli.js.cjs',
764-
//['build/transpile.js.cjs', 'build/copy.js.cjs', 'build/multicopy.js.cjs'],
765-
// Overwrite the .js.cjs transpilation with typescript outputs
766-
// We still need traceur outputs everywhere else, for now.
767-
'build/transpile.ts.cjs',
768764
['build/linknodemodules.js.cjs'],
769765
'build/transformCJSTests',
770766
done

tools/broccoli/traceur/index.js

Lines changed: 5 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/broccoli/traceur/index.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ var Writer = require('broccoli-writer');
77
var xtend = require('xtend');
88

99
class TraceurFilter extends Writer {
10-
constructor(private inputTree, private destExtension: string = '.js',
11-
private options = {}, private hackSourceMapExtension: boolean = false) {}
1210
static RUNTIME_PATH = traceur.RUNTIME_PATH;
11+
12+
constructor(private inputTree, private destExtension: string,
13+
private destSourceMapExtension: string, private options = {}) {}
14+
1315
write(readTree, destDir) {
1416
return readTree(this.inputTree)
1517
.then(srcDir => {
@@ -29,21 +31,15 @@ class TraceurFilter extends Writer {
2931

3032
// TODO: we should fix the sourceMappingURL written by Traceur instead of overriding
3133
// (but we might switch to typescript first)
32-
var url = path.basename(filepath).replace(/\.es6$/, '') +
33-
(this.destExtension === '.js' ? '.js.map' : '.map');
34-
if (this.hackSourceMapExtension) {
35-
url = path.basename(filepath).replace(/\.\w+$/, '') + '.map';
36-
}
37-
result.js = result.js + `\n//# sourceMappingURL=./${url}`;
34+
var mapFilepath = filepath.replace(/\.\w+$/, '') + this.destSourceMapExtension;
35+
result.js = result.js + `\n//# sourceMappingURL=./${path.basename(mapFilepath)}`;
3836

3937
var destFilepath = filepath.replace(/\.\w+$/, this.destExtension);
4038
var destFile = path.join(destDir, destFilepath);
4139
fse.mkdirsSync(path.dirname(destFile));
42-
var destMap = path.join(destDir, destFilepath + '.map');
43-
44-
4540
fs.writeFileSync(destFile, result.js, fsOpts);
4641

42+
var destMap = path.join(destDir, mapFilepath);
4743
result.sourceMap.file = destFilepath;
4844
fs.writeFileSync(destMap, JSON.stringify(result.sourceMap), fsOpts);
4945
});

tools/broccoli/typescript/index.js

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/broccoli/typescript/index.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
var fs = require('fs');
2+
var path = require('path');
3+
var ts = require('typescript');
4+
var walkSync = require('walk-sync');
5+
var Writer = require('broccoli-writer');
6+
var xtend = require('xtend');
7+
8+
class TSCompiler extends Writer {
9+
constructor(private inputTree, private options = {}) { super(inputTree, options); }
10+
11+
write(readTree, destDir) {
12+
var options: ts.CompilerOptions = xtend({outDir: destDir}, this.options);
13+
if (this.options.outDir) {
14+
options.outDir = path.resolve(destDir, options.outDir);
15+
}
16+
if (options.out) {
17+
options.out = path.resolve(destDir, options.out);
18+
}
19+
options.target = ts.ScriptTarget[options.target];
20+
return readTree(this.inputTree)
21+
.then(srcDir => {
22+
var files = walkSync(srcDir)
23+
.filter(filepath => path.extname(filepath).toLowerCase() === '.ts')
24+
.map(filepath => path.resolve(srcDir, filepath));
25+
26+
if (files.length > 0) {
27+
var program = ts.createProgram(files, options);
28+
var emitResult = program.emit();
29+
30+
var allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
31+
32+
var errMsg = '';
33+
allDiagnostics.forEach(diagnostic => {
34+
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
35+
if (!diagnostic.file) {
36+
errMsg += `\n${message}`;
37+
return;
38+
}
39+
var {line, character} =
40+
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
41+
errMsg += `\n${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`;
42+
});
43+
44+
if (emitResult.emitSkipped) {
45+
throw new Error(errMsg);
46+
}
47+
}
48+
});
49+
}
50+
}
51+
module.exports = TSCompiler;

0 commit comments

Comments
 (0)