Skip to content

Commit 580f293

Browse files
committed
feat(client): Add initial TypeScript support
1 parent 5bc5656 commit 580f293

12 files changed

+198
-61
lines changed

Diff for: app/generator.js

+19-6
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,18 @@ export default class Generator extends Base {
9696

9797
this.log('# Client\n');
9898

99-
this.prompt([/*{
99+
this.prompt([{
100100
type: 'list',
101101
name: 'script',
102102
message: 'What would you like to write scripts with?',
103103
choices: ['Babel', 'TypeScript'],
104-
filter: function(val) { return val.toLowerCase(); }
105-
}, */{
104+
filter: val => {
105+
return {
106+
'Babel': 'babel',
107+
'TypeScript': 'ts'
108+
}[val];
109+
}
110+
}, {
106111
type: 'list',
107112
name: 'markup',
108113
message: 'What would you like to write markup with?',
@@ -136,14 +141,14 @@ export default class Generator extends Base {
136141
}], function (answers) {
137142

138143
this.filters.js = true;
139-
this.filters.babel = true;
144+
this.filters[answers.script] = true;
140145
this.filters[answers.markup] = true;
141146
this.filters[answers.stylesheet] = true;
142147
this.filters[answers.router] = true;
143148
this.filters.bootstrap = !!answers.bootstrap;
144149
this.filters.uibootstrap = !!answers.uibootstrap;
145150

146-
this.scriptExt = answers.script === 'coffee' ? 'coffee' : 'js';
151+
this.scriptExt = answers.script === 'ts' ? 'ts' : 'js';
147152
this.templateExt = answers.markup;
148153
this.styleExt = answers.stylesheet === 'sass' ? 'scss' : answers.stylesheet;
149154

@@ -359,6 +364,7 @@ export default class Generator extends Base {
359364
if(this.filters.ngroute) filters.push('ngroute');
360365
if(this.filters.uirouter) filters.push('uirouter');
361366
if(this.filters.babel) extensions.push('babel');
367+
if(this.filters.ts) extensions.push('ts');
362368
if(this.filters.js) extensions.push('js');
363369
if(this.filters.html) extensions.push('html');
364370
if(this.filters.jade) extensions.push('jade');
@@ -412,8 +418,15 @@ export default class Generator extends Base {
412418
return {
413419

414420
generateProject: function() {
421+
let self = this;
415422
this.sourceRoot(path.join(__dirname, './templates'));
416-
this.processDirectory('.', '.');
423+
this.processDirectory('.', '.', function(dest) {
424+
if(self.filters.ts && dest.indexOf('client') > -1 && dest.indexOf('.json') === -1) {
425+
dest = dest.replace('.js', '.ts');
426+
}
427+
428+
return dest;
429+
});
417430
},
418431

419432
generateEndpoint: function() {

Diff for: app/templates/Gruntfile(grunt).js

+26-11
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,18 @@ module.exports = function (grunt) {
6060
babel: {
6161
files: ['<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js'],
6262
tasks: ['newer:babel:client']
63+
},<% } %><% if(filters.ts) { %>
64+
ts: {
65+
files: ['<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).ts'],
66+
tasks: ['ts:client']
6367
},<% } %>
6468
ngconstant: {
6569
files: ['<%%= yeoman.server %>/config/environment/shared.js'],
6670
tasks: ['ngconstant']
6771
},
6872
injectJS: {
6973
files: [
70-
'<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js',
74+
'<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).<%= scriptExt %>',
7175
'!<%%= yeoman.client %>/app/app.js'
7276
],
7377
tasks: ['injector:scripts']
@@ -77,11 +81,11 @@ module.exports = function (grunt) {
7781
tasks: ['injector:css']
7882
},
7983
mochaTest: {
80-
files: ['<%%= yeoman.server %>/**/*.{spec,integration}.js'],
84+
files: ['<%%= yeoman.server %>/**/*.{spec,integration}.<%= scriptExt %>'],
8185
tasks: ['env:test', 'mochaTest']
8286
},
8387
jsTest: {
84-
files: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js'],
88+
files: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.<%= scriptExt %>'],
8589
tasks: ['newer:jshint:all', 'wiredep:test', 'karma']
8690
},<% if (filters.stylus) { %>
8791
injectStylus: {
@@ -118,7 +122,7 @@ module.exports = function (grunt) {
118122
livereload: {
119123
files: [
120124
'{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.{css,html}',
121-
'{.tmp,<%%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).js',
125+
'{.tmp,<%%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).<%= scriptExt %>',
122126
'<%%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
123127
],
124128
options: {
@@ -454,14 +458,16 @@ module.exports = function (grunt) {
454458
'ngconstant'
455459
],
456460
server: [<% if(filters.babel) { %>
457-
'newer:babel:client',<% } if(filters.jade) { %>
461+
'newer:babel:client',<% } if(filters.ts) { %>
462+
'ts:client',<% } if(filters.jade) { %>
458463
'jade',<% } if(filters.stylus) { %>
459464
'stylus',<% } if(filters.sass) { %>
460465
'sass',<% } if(filters.less) { %>
461466
'less',<% } %>
462467
],
463468
test: [<% if(filters.babel) { %>
464-
'newer:babel:client',<% } if(filters.jade) { %>
469+
'newer:babel:client',<% } if(filters.ts) { %>
470+
'ts:client',<% } if(filters.jade) { %>
465471
'jade',<% } if(filters.stylus) { %>
466472
'stylus',<% } if(filters.sass) { %>
467473
'sass',<% } if(filters.less) { %>
@@ -477,7 +483,8 @@ module.exports = function (grunt) {
477483
}
478484
},
479485
dist: [<% if(filters.babel) { %>
480-
'newer:babel:client',<% } if(filters.jade) { %>
486+
'newer:babel:client',<% } if(filters.ts) { %>
487+
'ts:client',<% } if(filters.jade) { %>
481488
'jade',<% } if(filters.stylus) { %>
482489
'stylus',<% } if(filters.sass) { %>
483490
'sass',<% } if(filters.less) { %>
@@ -613,7 +620,16 @@ module.exports = function (grunt) {
613620
dest: '<%%= yeoman.dist %>/<%%= yeoman.server %>'
614621
}]
615622
}
616-
},<% if(filters.stylus) { %>
623+
},<% if(filters.ts) { %>
624+
625+
ts: {
626+
options: {
627+
sourceMap: true
628+
},
629+
client: {
630+
tsconfig: './tsconfig.client.json'
631+
}
632+
},<% } %><% if(filters.stylus) { %>
617633

618634
// Compiles Stylus to CSS
619635
stylus: {
@@ -673,9 +689,8 @@ module.exports = function (grunt) {
673689
},
674690
files: {
675691
'<%%= yeoman.client %>/index.html': [
676-
[<% if(filters.babel) { %>
677-
'.tmp/{app,components}/**/!(*.spec|*.mock).js',<% } else { %>
678-
'{.tmp,<%%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).js',<% } %>
692+
[
693+
'.tmp/{app,components}/**/!(*.spec|*.mock).<%= scriptExt %>',
679694
'!{.tmp,<%%= yeoman.client %>}/app/app.js'
680695
]
681696
]

Diff for: app/templates/_package.json

+8-5
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@
4242
"gulp": "^3.9.0",
4343
"gulp-add-src": "^0.2.0",
4444
"gulp-angular-templatecache": "^1.7.0",
45-
"gulp-autoprefixer": "2.3.1",<% if(filters.babel) { %>
46-
"gulp-babel": "^5.1.0",<% } %>
47-
"gulp-babel-istanbul": "^0.11.0",
45+
"gulp-autoprefixer": "2.3.1",
46+
"gulp-babel": "^5.1.0",
47+
"gulp-babel-istanbul": "^0.11.0",<% if(filters.ts) { %>
48+
"gulp-typescript": "~2.10.0",<% } %>
4849
"gulp-cache": "^0.2.10",
4950
"gulp-concat": "^2.6.0",
5051
"gulp-env": "^0.2.0",
@@ -97,7 +98,8 @@
9798
"grunt-contrib-watch": "~0.6.1",<% if (filters.jade) { %>
9899
"grunt-contrib-jade": "^0.15.0",<% } %><% if (filters.less) { %>
99100
"grunt-contrib-less": "^1.0.0",<% } %><% if(filters.babel) { %>
100-
"grunt-babel": "~5.0.0",<% } %>
101+
"grunt-babel": "~5.0.0",<% } %><% if(filters.ts) { %>
102+
"grunt-ts": "~5.2.0",<% } %>
101103
"grunt-google-cdn": "~0.4.0",
102104
"grunt-jscs": "^2.1.0",
103105
"grunt-newer": "^1.1.1",
@@ -149,7 +151,8 @@
149151
"jasmine-core": "^2.3.4",
150152
"karma-jasmine": "~0.3.0",
151153
"jasmine-spec-reporter": "^2.4.0",<% } if(filters.babel) { %>
152-
"karma-babel-preprocessor": "^5.2.1",<% } %>
154+
"karma-babel-preprocessor": "^5.2.1",<% } %><% if(filters.ts) { %>
155+
"karma-typescript-preprocessor": "0.0.21",<% } %>
153156
"requirejs": "~2.1.11",
154157
"phantomjs": "^1.9.18",
155158
"proxyquire": "^1.0.1",
File renamed without changes.

Diff for: app/templates/client/app/account(auth)/login/login.controller.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
'use strict';
22

33
class LoginController {
4-
//start-non-standard
5-
user = {};
6-
errors = {};
7-
submitted = false;
8-
//end-non-standard
9-
104
constructor(Auth<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %>) {
5+
this.user = {};
6+
this.errors = {};
7+
this.submitted = false;
8+
119
this.Auth = Auth;<% if (filters.ngroute) { %>
1210
this.$location = $location;<% } if (filters.uirouter) { %>
1311
this.$state = $state;<% } %>

Diff for: app/templates/client/app/account(auth)/settings/settings.controller.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
'use strict';
22

33
class SettingsController {
4-
//start-non-standard
5-
errors = {};
6-
submitted = false;
7-
//end-non-standard
8-
94
constructor(Auth) {
5+
this.errors = {};
6+
this.submitted = false;
7+
108
this.Auth = Auth;
119
}
1210

Diff for: app/templates/gulpfile.babel(gulp).js

+33-19
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ const paths = {
2727
images: `${clientPath}/assets/images/**/*`,
2828
scripts: [
2929
`${clientPath}/**/!(*.spec|*.mock).<%= scriptExt %>`,
30-
`!${clientPath}/bower_components/**/*.js`
30+
`!${clientPath}/bower_components/**/*.js`<% if(filters.ts) { %>,
31+
`!${clientPath}/typings/**/*`<% } %>
3132
],
3233
styles: [`${clientPath}/{app,components}/**/*.<%= styleExt %>`],
3334
mainStyle: `${clientPath}/app/app.<%= styleExt %>`,
@@ -38,7 +39,7 @@ const paths = {
3839
bower: `${clientPath}/bower_components/`
3940
},
4041
server: {
41-
scripts: [`${serverPath}/**/!(*.spec|*.integration).<%= scriptExt %>`],
42+
scripts: [`${serverPath}/**/!(*.spec|*.integration).js`],
4243
json: [`${serverPath}/**/*.json`],
4344
test: {
4445
integration: `${serverPath}/**/*.integration.js`,
@@ -86,7 +87,7 @@ function whenServerReady(cb) {
8687
}
8788

8889
function sortModulesFirst(a, b) {
89-
var module = /\.module\.js$/;
90+
var module = /\.module\.<%= scriptExt %>$/;
9091
var aMod = module.test(a.path);
9192
var bMod = module.test(b.path);
9293
// inject *.module.js first
@@ -130,19 +131,20 @@ let styles = lazypipe()
130131
.pipe(plugins.less)<% } %>
131132
.pipe(plugins.autoprefixer, {browsers: ['last 1 version']})
132133
.pipe(plugins.sourcemaps.write, '.');
134+
<% if(filters.ts) { %>
135+
let tsProject = plugins.typescript.createProject('./tsconfig.client.json');<% } else { %>
136+
let transpileClient = lazypipe()
137+
.pipe(plugins.sourcemaps.init)
138+
.pipe(plugins.babel, {
139+
optional: ['es7.classProperties']
140+
})
141+
.pipe(plugins.sourcemaps.write, '.');<% } %>
133142

134143
let transpileServer = lazypipe()
135-
.pipe(plugins.sourcemaps.init)<% if(filters.babel) { %>
144+
.pipe(plugins.sourcemaps.init)
136145
.pipe(plugins.babel, {
137146
optional: ['runtime']
138-
})<% } %>
139-
.pipe(plugins.sourcemaps.write, '.');
140-
141-
let transpileClient = lazypipe()
142-
.pipe(plugins.sourcemaps.init)<% if(filters.babel) { %>
143-
.pipe(plugins.babel, {
144-
optional: ['es7.classProperties']
145-
})<% } %>
147+
})
146148
.pipe(plugins.sourcemaps.write, '.');
147149

148150
let mocha = lazypipe()
@@ -204,12 +206,12 @@ gulp.task('inject', cb => {
204206
gulp.task('inject:js', () => {
205207
return gulp.src(paths.client.mainView)
206208
.pipe(plugins.inject(
207-
gulp.src(_.union(paths.client.scripts, [`!${clientPath}/**/*.{spec,mock}.js`, `!${clientPath}/app/app.js`]), {read: false})
209+
gulp.src(_.union(paths.client.scripts, [<% if(filters.ts) { %>'client/app/app.constant.js', <% } %>`!${clientPath}/**/*.{spec,mock}.js`, `!${clientPath}/app/app.js`]), {read: false})
208210
.pipe(plugins.sort(sortModulesFirst)),
209211
{
210212
starttag: '<!-- injector:js -->',
211213
endtag: '<!-- endinjector -->',
212-
transform: (filepath) => '<script src="' + filepath.replace(`/${clientPath}/`, '') + '"></script>'
214+
transform: (filepath) => '<script src="' + filepath.replace(`/${clientPath}/`, '')<% if(filters.ts) { %>.replace('.ts', '.js')<% } %> + '"></script>'
213215
}))
214216
.pipe(gulp.dest(clientPath));
215217
});
@@ -245,6 +247,14 @@ gulp.task('inject:<%= styleExt %>', () => {
245247
}
246248
}))
247249
.pipe(gulp.dest(`${clientPath}/app`));
250+
});<% } %><% if(filters.ts) { %>
251+
252+
// Install DefinitelyTyped TypeScript definition files
253+
gulp.task('tsd', cb => {
254+
plugins.tsd({
255+
command: 'reinstall',
256+
config: './tsd.json'
257+
}, cb);
248258
});<% } %>
249259

250260
gulp.task('styles', () => {
@@ -254,8 +264,11 @@ gulp.task('styles', () => {
254264
});
255265

256266
gulp.task('transpile:client', () => {
257-
return gulp.src(paths.client.scripts)
258-
.pipe(transpileClient())
267+
return gulp.src(paths.client.scripts)<% if(filters.ts) { %>
268+
.pipe(plugins.sourcemaps.init())
269+
.pipe(plugins.typescript(tsProject)).js
270+
.pipe(plugins.sourcemaps.write('.'))<% } else { %>
271+
.pipe(transpileClient())<% } %>
259272
.pipe(gulp.dest('.tmp'));
260273
});
261274

@@ -348,7 +361,7 @@ gulp.task('watch', () => {
348361
});
349362

350363
gulp.task('serve', cb => {
351-
runSequence(['clean:tmp', 'constant'],
364+
runSequence(['clean:tmp', 'constant'<% if(filters.ts) { %>, 'tsd'<% } %>],
352365
['lint:scripts', 'inject'<% if(filters.jade) { %>, 'jade'<% } %>],
353366
['wiredep:client'],
354367
['transpile:client', 'styles'],
@@ -440,7 +453,8 @@ gulp.task('build', cb => {
440453
'clean:dist',
441454
'clean:tmp',
442455
'inject',
443-
'wiredep:client',
456+
'wiredep:client',<% if(filters.ts) { %>
457+
'tsd',<% } %>
444458
[
445459
'build:images',
446460
'copy:extras',
@@ -454,7 +468,7 @@ gulp.task('build', cb => {
454468

455469
gulp.task('clean:dist', () => del([`${paths.dist}/!(.git*|.openshift|Procfile)**`], {dot: true}));
456470

457-
gulp.task('build:client', ['transpile:client', 'styles', 'html'], () => {
471+
gulp.task('build:client', ['transpile:client', 'styles', 'html', 'constant'], () => {
458472
var manifest = gulp.src(`${paths.dist}/${clientPath}/assets/rev-manifest.json`);
459473

460474
var appFilter = plugins.filter('**/app.js');

0 commit comments

Comments
 (0)