Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit 556d2e3

Browse files
committed
refactor(bundler): use typescript rollup plugin
Use the typescript rollup plugin instead of spawning tsc. This cuts dev build times by 1 to 2 seconds per save. Additionally, remove the ngTemplate from the rollup config and have dev builds automatically receive the required plugins for template inlining and TS compiling.
1 parent 6313e99 commit 556d2e3

11 files changed

+439
-355
lines changed

config/rollup.config.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
var ngTemplate = require('../dist/plugins/ng-template').ngTemplate;
21
var nodeResolve = require('rollup-plugin-node-resolve');
32
var commonjs = require('rollup-plugin-commonjs');
43
var globals = require('rollup-plugin-node-globals');
54
var builtins = require('rollup-plugin-node-builtins');
65
var json = require('rollup-plugin-json');
76

7+
88
// https://github.com/rollup/rollup/wiki/JavaScript-API
99

1010
var rollupConfig = {
@@ -13,7 +13,7 @@ var rollupConfig = {
1313
* be included, along with the minimum necessary code
1414
* from its dependencies
1515
*/
16-
entry: './.tmp/app/main.dev.js',
16+
entry: 'src/app/main.dev.ts',
1717

1818
/**
1919
* sourceMap: If true, a separate sourcemap file will
@@ -36,7 +36,6 @@ var rollupConfig = {
3636
* See https://github.com/rollup/rollup/wiki/Plugins for more info.
3737
*/
3838
plugins: [
39-
ngTemplate(),
4039
builtins(),
4140
commonjs(),
4241
nodeResolve({
@@ -55,7 +54,7 @@ var rollupConfig = {
5554

5655
if (process.env.IONIC_ENV == 'prod') {
5756
// production mode
58-
rollupConfig.entry = '.tmp/app/main.prod.js';
57+
rollupConfig.entry = '{{TMP}}/app/main.prod.ts';
5958
rollupConfig.sourceMap = false;
6059
}
6160

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"rollup-pluginutils": "1.5.2",
4141
"tslint": "3.15.1",
4242
"tslint-eslint-rules": "1.5.0",
43+
"typescript": "^2.0.3",
4344
"uglify-js": "2.7.3"
4445
},
4546
"devDependencies": {
@@ -49,9 +50,9 @@
4950
"@types/node": "6.0.38",
5051
"@types/uglify-js": "2.0.27",
5152
"jasmine": "^2.5.2",
53+
"tippex": "^2.2.0",
5254
"tslint": "3.15.1",
53-
"tslint-ionic-rules": "0.0.5",
54-
"typescript": "^2.0.3"
55+
"tslint-ionic-rules": "0.0.5"
5556
},
5657
"repository": {
5758
"type": "git",

src/build.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { BuildContext, BuildOptions, generateContext, generateBuildOptions, Logger } from './util';
1+
import { BuildContext, BuildOptions } from './util/interfaces';
2+
import { generateContext, generateBuildOptions } from './util/config';
23
import { bundle, bundleUpdate } from './bundle';
34
import { clean } from './clean';
45
import { minify } from './minify';
56
import { copy } from './copy';
67
import { lint } from './lint';
8+
import { Logger } from './util/logger';
79
import { ngc } from './ngc';
810
import { sass, sassUpdate } from './sass';
9-
import { tsc } from './tsc';
1011

1112

1213
export function build(context: BuildContext, options: BuildOptions) {
@@ -74,10 +75,7 @@ function buildDev(context: BuildContext, options: BuildOptions) {
7475
const copyPromise = copy(context);
7576
const lintPromise = lint(context);
7677

77-
return tsc(context, options).then(() => {
78-
return bundle(context, options);
79-
80-
}).then(() => {
78+
return bundle(context, options).then(() => {
8179
return sass(context);
8280

8381
}).then(() => {

src/bundle.ts

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { BuildContext, BuildOptions, fillConfigDefaults, generateContext, generateBuildOptions, Logger, TaskInfo } from './util';
1+
import { BuildContext, BuildOptions, TaskInfo } from './util/interfaces';
2+
import { endsWith } from './util/helpers';
3+
import { fillConfigDefaults, generateContext, generateBuildOptions, replacePathVars } from './util/config';
4+
import ionCompiler from './plugins/ion-compiler';
25
import { join, isAbsolute } from 'path';
6+
import { Logger } from './util/logger';
37
import { outputJson, readJsonSync } from 'fs-extra';
48
import { tmpdir } from 'os';
59

@@ -14,7 +18,7 @@ export function bundle(context?: BuildContext, options?: BuildOptions, rollupCon
1418
return runBundle(context, options, rollupConfig, useCache).then(() => {
1519
return logger.finish();
1620
}).catch((err: Error) => {
17-
logger.fail(err, err.message);
21+
logger.fail(err);
1822
return Promise.reject(err);
1923
});
2024
}
@@ -29,7 +33,7 @@ export function bundleUpdate(event: string, path: string, context: BuildContext,
2933
return logger.finish();
3034

3135
}).catch((err: Error) => {
32-
logger.fail(err, err.message);
36+
logger.fail(err);
3337
return Promise.reject(err);
3438
});
3539
}
@@ -39,20 +43,37 @@ function runBundle(context: BuildContext, options: BuildOptions, rollupConfig: R
3943
rollupConfig = fillConfigDefaults(context, rollupConfig, ROLLUP_TASK_INFO);
4044

4145
if (!isAbsolute(rollupConfig.dest)) {
46+
// user can pass in absolute paths
47+
// otherwise save it in the build directory
4248
rollupConfig.dest = join(context.buildDir, rollupConfig.dest);
4349
}
4450

51+
// replace any path vars like {{TMP}} with the real path
52+
rollupConfig.entry = replacePathVars(context, rollupConfig.entry);
53+
rollupConfig.dest = replacePathVars(context, rollupConfig.dest);
54+
55+
if (!options.isProd) {
56+
// dev mode should auto add the ion-compiler plugin
57+
// this will do template inlining and transpile TS
58+
// ngc does full production builds itself and the bundler
59+
// will already receive transpiled and AoT templates
60+
rollupConfig.plugins.unshift(ionCompiler());
61+
}
62+
4563
if (useCache) {
4664
// tell rollup to use a previous bundle as its starting point
4765
rollupConfig.cache = bundleCache;
4866
}
4967

5068
if (!rollupConfig.onwarn) {
69+
// use our own logger if one wasn't already provided
5170
rollupConfig.onwarn = createOnWarnFn();
5271
}
5372

5473
Logger.debug(`entry: ${rollupConfig.entry}, dest: ${rollupConfig.dest}, cache: ${rollupConfig.cache}, format: ${rollupConfig.format}`);
5574

75+
checkDeprecations(options, rollupConfig);
76+
5677
// bundle the app then create create css
5778
const rollup = require('rollup').rollup;
5879
return rollup(rollupConfig).then((bundle: RollupBundle) => {
@@ -67,15 +88,36 @@ function runBundle(context: BuildContext, options: BuildOptions, rollupConfig: R
6788
// to always bundle to know which modules are used
6889
setModulePathsCache(context.moduleFiles);
6990

70-
// Cache our bundle for later use
91+
// cache our bundle for later use
7192
bundleCache = bundle;
7293

94+
// clean up any references
95+
rollupConfig.cache = rollupConfig.onwarn = rollupConfig.plugins = null;
96+
7397
// write the bundle
7498
return bundle.write(rollupConfig);
99+
100+
}).catch((err: any) => {
101+
// ensure references are cleared up when there's an error
102+
bundleCache = rollupConfig.cache = rollupConfig.onwarn = rollupConfig.plugins = null;
103+
return Promise.reject(err);
75104
});
76105
}
77106

78107

108+
function checkDeprecations(options: BuildOptions, rollupConfig: RollupConfig) {
109+
if (!options.isProd) {
110+
if (rollupConfig.entry.indexOf('.tmp') > -1 || endsWith(rollupConfig.entry, '.js')) {
111+
// warning added 2016-10-05, v0.0.29
112+
throw new Error('\nDev builds no longer use the ".tmp" directory. Please update your rollup config\'s\n' +
113+
'entry to use your "src" directory\'s "main.dev.ts" TypeScript file.\n' +
114+
'For example, the entry for dev builds should be: "src/app/main.dev.ts"');
115+
116+
}
117+
}
118+
}
119+
120+
79121
export function getModulePathsCache(): string[] {
80122
// sync get the cached array of module paths (if they exist)
81123
let modulePaths: string[] = null;
@@ -150,8 +192,7 @@ function createOnWarnFn() {
150192
}
151193

152194
const IGNORE_WARNS = [
153-
'keyword is equivalent to',
154-
'plugin (\'ng-template\') was used to transform files'
195+
'keyword is equivalent to'
155196
];
156197

157198

src/ngc.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { basename, join } from 'path';
2-
import { BuildContext, BuildOptions, TaskInfo, fillConfigDefaults, generateContext, generateBuildOptions, getNodeBinExecutable, isTsFilename, Logger } from './util';
2+
import { BuildContext, BuildOptions, TaskInfo } from './util/interfaces';
33
import { copy as fsCopy, emptyDirSync, outputJsonSync, statSync } from 'fs-extra';
4-
import { getSrcTsConfig } from './tsc';
4+
import { fillConfigDefaults, generateContext, generateBuildOptions, getNodeBinExecutable } from './util/config';
5+
import { endsWith } from './util/helpers';
6+
import { Logger } from './util/logger';
7+
import { getTsConfig } from './transpile';
58

69

710
export function ngc(context?: BuildContext, options?: BuildOptions, ngcConfig?: NgcConfig) {
@@ -20,6 +23,7 @@ export function ngc(context?: BuildContext, options?: BuildOptions, ngcConfig?:
2023

2124
}).then(() => {
2225
return logger.finish();
26+
2327
}).catch((err: Error) => {
2428
logger.fail(err);
2529
return Promise.reject(err);
@@ -43,7 +47,7 @@ function runNgc(context: BuildContext, options: BuildOptions, ngcConfig: NgcConf
4347

4448
const ngcCmd = getNodeBinExecutable(context, 'ngc');
4549
if (!ngcCmd) {
46-
reject(new Error(`Unable to find Angular Compiler "ngc" command: ${ngcCmd}`));
50+
reject(new Error(`Unable to find Angular Compiler "ngc" command: ${ngcCmd}. Please ensure @angular/compiler-cli has been installed with NPM.`));
4751
return;
4852
}
4953

@@ -64,7 +68,7 @@ function runNgc(context: BuildContext, options: BuildOptions, ngcConfig: NgcConf
6468
});
6569

6670
cp.stderr.on('data', (data: string) => {
67-
Logger.error(`ngc error: ${data}`);
71+
Logger.error(`ngc: ${data}`);
6872
hadAnError = true;
6973
});
7074

@@ -81,17 +85,12 @@ function runNgc(context: BuildContext, options: BuildOptions, ngcConfig: NgcConf
8185

8286
function createTmpTsConfig(context: BuildContext, ngcConfig: NgcConfig) {
8387
// create the tsconfig from the original src
84-
const tsConfig = getSrcTsConfig(context);
88+
const tsConfig = getTsConfig();
8589

8690
// delete outDir if it's set since we only want
8791
// to compile to the same directory we're in
8892
delete tsConfig.compilerOptions.outDir;
8993

90-
// downstream, we have a dependency on es5 code and
91-
// es2015 modules, so force them
92-
tsConfig.compilerOptions.module = 'es2015';
93-
tsConfig.compilerOptions.target = 'es5';
94-
9594
// force where to look for ts files
9695
tsConfig.include = ngcConfig.include;
9796

@@ -136,20 +135,14 @@ function filterCopyFiles(filePath: any, hoop: any) {
136135
shouldInclude = (EXCLUDE_DIRS.indexOf(basename(filePath)) < 0);
137136

138137
} else {
139-
if (isTsFilename(filePath)) {
140-
shouldInclude = true;
141-
}
142-
143-
if (filePath.substr(filePath.length - 5) === '.html') {
144-
shouldInclude = true;
145-
}
138+
shouldInclude = (endsWith(filePath, '.ts') || endsWith(filePath, '.html'));
146139
}
147-
148140
} catch (e) {}
149141

150142
return shouldInclude;
151143
}
152144

145+
153146
export function getTmpTsConfigPath(context: BuildContext) {
154147
return join(context.tmpDir, 'tsconfig.json');
155148
}

src/plugins/ion-compiler.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Ported from 'rollup-plugin-typescript':
2+
// https://github.com/rollup/rollup-plugin-typescript
3+
// MIT Licenced
4+
5+
import { helperFns, helpersId } from '../util/typescript-helpers';
6+
import { getCompilerOptions, resolveId, transpile, IonCompilerPluginOptions } from '../transpile';
7+
import { inlineTemplate } from '../template';
8+
9+
10+
export default function ionCompiler(options?: IonCompilerPluginOptions) {
11+
options = options || {};
12+
13+
const pluginutils = require('rollup-pluginutils');
14+
15+
const filter = pluginutils.createFilter(
16+
options.include || ['*.ts+(|x)', '**/*.ts+(|x)'],
17+
options.exclude || ['*.d.ts', '**/*.d.ts']);
18+
19+
const compilerOptions = getCompilerOptions();
20+
21+
return {
22+
resolveId(importee: string, importer: string) {
23+
return resolveId(importee, importer, compilerOptions);
24+
},
25+
26+
load(id: string) {
27+
if (id === helpersId) {
28+
return helperFns;
29+
}
30+
},
31+
32+
transform(sourceText: string, sourcePath: string): any {
33+
if (filter(sourcePath)) {
34+
// inline templates
35+
sourceText = inlineTemplate(sourceText, sourcePath);
36+
37+
// transpile typescirpt
38+
return transpile(sourceText, sourcePath, compilerOptions, true);
39+
}
40+
}
41+
};
42+
}
43+

src/plugins/ng-template.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)