From da18bbaa665c6b53d49ae4a98cd03b6cfbb1517e Mon Sep 17 00:00:00 2001 From: Dan Freeman Date: Wed, 24 Jan 2018 14:11:58 -0500 Subject: [PATCH 1/4] Fix cleanup --- lib/serve-ts.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/serve-ts.js b/lib/serve-ts.js index a46e1251d..3a0b5a195 100644 --- a/lib/serve-ts.js +++ b/lib/serve-ts.js @@ -92,13 +92,15 @@ module.exports = (project) => { }, onInterrupt() { - if (this.tsc) { - this.tsc.kill(); - } + return Serve.prototype.onInterrupt.apply(this, arguments).then(() => { + if (this.tsc) { + this.tsc.kill(); + } - if (fs.existsSync(OUT_DIR)) { - rimraf.sync(OUT_DIR); - } + if (fs.existsSync(OUT_DIR)) { + rimraf.sync(OUT_DIR); + } + }); }, }); }; From 54edcdc23fc71b3ee308770092a7d47d4225fea2 Mon Sep 17 00:00:00 2001 From: Dan Freeman Date: Wed, 24 Jan 2018 14:57:24 -0500 Subject: [PATCH 2/4] Move incremental output to OS temp --- blueprints/ember-cli-typescript/index.js | 16 ---------------- index.js | 19 +++++++++++++++---- lib/serve-ts.js | 9 ++++----- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/blueprints/ember-cli-typescript/index.js b/blueprints/ember-cli-typescript/index.js index 698df8b0c..18f659f38 100644 --- a/blueprints/ember-cli-typescript/index.js +++ b/blueprints/ember-cli-typescript/index.js @@ -38,22 +38,6 @@ module.exports = { }, afterInstall() { - if (existsSync('.gitignore')) { - this.insertIntoFile('.gitignore', '\n# Ember CLI TypeScript\n.e-c-ts'); - } - - if (existsSync('.vscode/settings.json')) { - // NOTE: this may or may not actually work -- it assumes that - // `"tmp:": true` is in fact set. - this.insertIntoFile('.vscode/settings.json', '",\n.e-c-ts": true', { - after: '"tmp": true', - }); - } - - // TODO: same for Atom - // TODO: same for Sublime - // TODO: same for IntelliJ - return this.addPackagesToProject([ { name: 'typescript', target: 'latest' }, { name: '@types/ember', target: 'latest' }, diff --git a/index.js b/index.js index 9e64045df..2a7c510a9 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ /* eslint-env node */ const fs = require('fs'); +const os = require('os'); const path = require('path'); const SilentError = require('silent-error'); const TsPreprocessor = require('./lib/typescript-preprocessor'); @@ -17,6 +18,16 @@ module.exports = { return this.project._isRunningServeTS; }, + _tempDir() { + if (!this.project._tsTempDir) { + const tempDir = path.join(os.tmpdir(), `e-c-ts-${process.pid}`); + this.project._tsTempDir = tempDir; + mkdirp.sync(tempDir); + } + + return this.project._tsTempDir; + }, + _inRepoAddons() { const pkg = this.project.pkg; if (!pkg || !pkg['ember-addon'] || !pkg['ember-addon'].paths) { @@ -28,7 +39,7 @@ module.exports = { includedCommands() { return { - 'serve-ts': buildServeCommand(this.project), + 'serve-ts': buildServeCommand(this.project, this._tempDir()), }; }, @@ -75,10 +86,10 @@ module.exports = { // funnel will fail if the directory doesn't exist roots.forEach(root => { - mkdirp.sync(path.join('.e-c-ts', root)); + mkdirp.sync(path.join(this._tempDir(), root)); }); - const ts = funnel('.e-c-ts', { + const ts = funnel(this._tempDir(), { exclude: ['tests'], getDestinationPath(relativePath) { const prefix = roots.find(root => relativePath.startsWith(root)); @@ -99,7 +110,7 @@ module.exports = { return tree; } - const tests = path.join('.e-c-ts', 'tests'); + const tests = path.join(this._tempDir(), 'tests'); // funnel will fail if the directory doesn't exist mkdirp.sync(tests); diff --git a/lib/serve-ts.js b/lib/serve-ts.js index 3a0b5a195..76608eba5 100644 --- a/lib/serve-ts.js +++ b/lib/serve-ts.js @@ -5,9 +5,8 @@ const child_process = require('child_process'); const fs = require('fs'); const rimraf = require('rimraf'); -const OUT_DIR = '.e-c-ts'; -module.exports = (project) => { +module.exports = (project, outDir) => { const Serve = project.require('ember-cli/lib/commands/serve'); const Builder = project.require('ember-cli/lib/models/builder'); const Watcher = project.require('ember-cli/lib/models/watcher'); @@ -71,7 +70,7 @@ module.exports = (project) => { 'node_modules/typescript/bin/tsc', [ '--watch', - '--outDir', OUT_DIR, + '--outDir', outDir, '--allowJs', 'false', '--noEmit', 'false', '--sourceMap', 'false', // TODO: enable if sourcemaps=true @@ -97,8 +96,8 @@ module.exports = (project) => { this.tsc.kill(); } - if (fs.existsSync(OUT_DIR)) { - rimraf.sync(OUT_DIR); + if (fs.existsSync(outDir)) { + rimraf.sync(outDir); } }); }, From 8fad31cca89efde1532ab7cc56d750936fc85568 Mon Sep 17 00:00:00 2001 From: Dan Freeman Date: Wed, 24 Jan 2018 15:13:54 -0500 Subject: [PATCH 3/4] Minimize rebuild thrashing --- .../ember-cli-typescript/files/tsconfig.json | 9 +- lib/serve-ts.js | 102 ++++++++++-------- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/blueprints/ember-cli-typescript/files/tsconfig.json b/blueprints/ember-cli-typescript/files/tsconfig.json index 44868b77e..03f735377 100644 --- a/blueprints/ember-cli-typescript/files/tsconfig.json +++ b/blueprints/ember-cli-typescript/files/tsconfig.json @@ -20,11 +20,8 @@ inRepoAddons.forEach(function(path) { %>, ] } }, - "exclude": [ - "tmp", - "dist", - "node_modules", - "bower_components", - "blueprints" + "include": [ + "app", + "tests" ] } diff --git a/lib/serve-ts.js b/lib/serve-ts.js index 76608eba5..4dd784c6a 100644 --- a/lib/serve-ts.js +++ b/lib/serve-ts.js @@ -42,52 +42,68 @@ module.exports = (project, outDir) => { run(options) { this.project._isRunningServeTS = true; - const builder = new Builder({ - ui: this.ui, - outputPath: options.outputPath, - project: this.project, - environment: options.environment, - }); + return new Promise(resolve => { + let started = false; - // We're ignoring this because TS doesn't have types for `Watcher`; this is - // fine, though. - // @ts-ignore - const watcher = new WatcherNonTS({ - ui: this.ui, - builder, - analytics: this.analytics, - options, - serving: true, - }); + this.ui.startProgress('Starting TypeScript compilation...'); - options._builder = builder; - options._watcher = watcher; - - // TODO: typescript might be installed globally? - // argument sequence here is meaningful; don't apply prettier. - // prettier-ignore - this.tsc = child_process.fork( - 'node_modules/typescript/bin/tsc', - [ - '--watch', - '--outDir', outDir, - '--allowJs', 'false', - '--noEmit', 'false', - '--sourceMap', 'false', // TODO: enable if sourcemaps=true - ], - { - silent: true, - execArgv: [], - } - ); - this.tsc.stdout.on('data', data => { - this.ui.write(data); - }); - this.tsc.stderr.on('data', data => { - this.ui.writeError(data); - }); + // TODO: typescript might be installed globally? + // argument sequence here is meaningful; don't apply prettier. + // prettier-ignore + this.tsc = child_process.fork( + 'node_modules/typescript/bin/tsc', + [ + '--watch', + '--outDir', outDir, + '--allowJs', 'false', + '--noEmit', 'false', + '--sourceMap', 'false', // TODO: enable if sourcemaps=true + ], + { + silent: true, + execArgv: [], + } + ); + + this.tsc.stderr.on('data', data => { + this.ui.writeError(data); + }); - return Serve.prototype.run.call(this, options); + this.tsc.stdout.on('data', data => { + this.ui.write(data); + + // Wait for the initial compilation to complete before continuing to + // minimize thrashing during startup. + if (data.indexOf('Compilation complete') !== -1 && !started) { + started = true; + this.ui.stopProgress(); + resolve(); + } + }); + }).then(() => { + const builder = new Builder({ + ui: this.ui, + outputPath: options.outputPath, + project: this.project, + environment: options.environment, + }); + + // We're ignoring this because TS doesn't have types for `Watcher`; this is + // fine, though. + // @ts-ignore + const watcher = new WatcherNonTS({ + ui: this.ui, + builder, + analytics: this.analytics, + options, + serving: true, + }); + + options._builder = builder; + options._watcher = watcher; + + return Serve.prototype.run.call(this, options); + }); }, onInterrupt() { From 0e4b8b58400fa4c96a829f740a51a8964c4d353b Mon Sep 17 00:00:00 2001 From: Dan Freeman Date: Wed, 24 Jan 2018 15:14:07 -0500 Subject: [PATCH 4/4] Fix app URL in serve output --- lib/serve-ts.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/serve-ts.js b/lib/serve-ts.js index 4dd784c6a..2cec5076b 100644 --- a/lib/serve-ts.js +++ b/lib/serve-ts.js @@ -40,6 +40,8 @@ module.exports = (project, outDir) => { 'Serve the app/addon with the TypeScript compiler in incremental mode. (Much faster!)', run(options) { + const config = this.project.config(options.environment); + this.project._isRunningServeTS = true; return new Promise(resolve => { @@ -88,6 +90,9 @@ module.exports = (project, outDir) => { environment: options.environment, }); + // This will be populated later by the superclass, but is needed by the Watcher now + options.rootURL = config.rootURL || '/'; + // We're ignoring this because TS doesn't have types for `Watcher`; this is // fine, though. // @ts-ignore