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

Commit 23ad195

Browse files
committed
perf(webpack): speed up webpack build by not using file-system and watches
speed up webpack build by not using file-system and watches Uses eval for sourcemaps
1 parent 5ab3623 commit 23ad195

16 files changed

+323
-169
lines changed

config/webpack.config.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
var path = require('path');
22
var webpack = require('webpack');
33

4+
var ionicWebpackFactoryPath = path.join(process.env.IONIC_APP_SCRIPTS_DIR, 'dist', 'webpack', 'ionic-webpack-factory.js');
5+
var ionicWebpackFactory = require(ionicWebpackFactoryPath);
6+
47
function getEntryPoint() {
58
if (process.env.IONIC_ENV === 'prod') {
69
return '{{TMP}}/app/main.prod.js';
710
}
8-
return '{{TMP}}/app/main.dev.js';
11+
return '{{SRC}}/app/main.dev.ts';
912
}
1013

1114
function getPlugins() {
@@ -19,7 +22,11 @@ function getPlugins() {
1922
//new DedupePlugin()
2023
];
2124
}
22-
return [];
25+
26+
// for dev builds, use our custom environment
27+
return [
28+
ionicWebpackFactory.getIonicEnvironmentPlugin()
29+
];
2330
}
2431

2532
function getSourcemapLoader() {
@@ -30,8 +37,8 @@ function getSourcemapLoader() {
3037

3138
return [
3239
{
33-
test: /\.js$/,
34-
loader: path.join(process.env.IONIC_APP_SCRIPTS_DIR, 'dist', 'loaders', 'typescript-sourcemap-loader-memory.js')
40+
test: /\.ts$/,
41+
loader: path.join(process.env.IONIC_APP_SCRIPTS_DIR, 'dist', 'webpack', 'typescript-sourcemap-loader-memory.js')
3542
}
3643
];
3744
}
@@ -42,10 +49,10 @@ module.exports = {
4249
path: '{{BUILD}}',
4350
filename: 'main.js'
4451
},
45-
devtool: 'source-map',
52+
devtool: 'eval',
4653

4754
resolve: {
48-
extensions: ['.js', '.json']
55+
extensions: ['.js', '.ts', '.json']
4956
},
5057

5158
module: {

src/loaders/typescript-sourcemap-loader-memory.ts

-35
This file was deleted.

src/spec/ion-compiler.spec.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { BuildContext, File } from '../util/interfaces';
1+
import { FileCache } from '../util/file-cache';
2+
import { BuildContext } from '../util/interfaces';
23
import { dirname, join, resolve } from 'path';
34
import { resolveId } from '../plugins/ion-compiler';
45

@@ -33,8 +34,8 @@ describe('ion-compiler', () => {
3334
it('should return null when importer is not found in list of files', () => {
3435
// arrange
3536
let context: BuildContext = {};
36-
context.fileCache = new Map<string, File>();
37-
context.fileCache.set(importer, null);
37+
context.fileCache = new FileCache();
38+
context.fileCache.put(importer, null);
3839

3940
// act
4041
const result = resolveId('importee', importer, context);
@@ -46,8 +47,8 @@ describe('ion-compiler', () => {
4647
it('should return null when importer content lacks output property', () => {
4748
// arrange
4849
let context: BuildContext = {};
49-
context.fileCache = new Map<string, File>();
50-
context.fileCache.set(importer, null);
50+
context.fileCache = new FileCache();
51+
context.fileCache.put(importer, null);
5152

5253
// act
5354
const result = resolveId('importee', importer, context);
@@ -59,8 +60,8 @@ describe('ion-compiler', () => {
5960
it('should return path to file when file is found with ref to forward dir', () => {
6061
// arrange
6162
let context: BuildContext = {};
62-
context.fileCache = new Map<string, File>();
63-
context.fileCache.set(importer, {
63+
context.fileCache = new FileCache();
64+
context.fileCache.put(importer, {
6465
path: importer,
6566
content: 'fake irrelevant data'
6667
});
@@ -69,7 +70,7 @@ describe('ion-compiler', () => {
6970
const importerBasename = dirname(importer);
7071
const importeeFullPath = resolve(join(importerBasename, importee)) + '.ts';
7172

72-
context.fileCache.set(importeeFullPath, {
73+
context.fileCache.put(importeeFullPath, {
7374
path: importeeFullPath,
7475
content: 'someContent'
7576
});
@@ -85,8 +86,8 @@ describe('ion-compiler', () => {
8586

8687
// arrange
8788
let context: BuildContext = {};
88-
context.fileCache = new Map<string, File>();
89-
context.fileCache.set(importer, {
89+
context.fileCache = new FileCache();
90+
context.fileCache.put(importer, {
9091
path: importer,
9192
content: 'fake irrelevant data'
9293
});
@@ -95,7 +96,7 @@ describe('ion-compiler', () => {
9596
const importerBasename = dirname(importer);
9697
const importeeFullPath = resolve(join(importerBasename, importee)) + '.ts';
9798

98-
context.fileCache.set(importeeFullPath, { path: importeeFullPath, content: null});
99+
context.fileCache.put(importeeFullPath, { path: importeeFullPath, content: null});
99100

100101
// act
101102
const result = resolveId(importee, importer, context);
@@ -108,8 +109,8 @@ describe('ion-compiler', () => {
108109

109110
// arrange
110111
let context: BuildContext = {};
111-
context.fileCache = new Map<string, File>();
112-
context.fileCache.set(importer, {
112+
context.fileCache = new FileCache();
113+
context.fileCache.put(importer, {
113114
path: importer,
114115
content: 'fake irrelevant data'
115116
});
@@ -118,7 +119,7 @@ describe('ion-compiler', () => {
118119
const importerBasename = dirname(importer);
119120
const importeeFullPath = join(resolve(join(importerBasename, importee)), 'index.ts');
120121

121-
context.fileCache.set(importeeFullPath, { path: importeeFullPath, content: null });
122+
context.fileCache.put(importeeFullPath, { path: importeeFullPath, content: null });
122123

123124
// act
124125
const result = resolveId(importee, importer, context);
@@ -131,8 +132,8 @@ describe('ion-compiler', () => {
131132

132133
// arrange
133134
let context: BuildContext = {};
134-
context.fileCache = new Map<string, File>();
135-
context.fileCache.set(importer, {
135+
context.fileCache = new FileCache();
136+
context.fileCache.put(importer, {
136137
path: importer,
137138
content: 'fake irrelevant data'
138139
});
@@ -141,7 +142,7 @@ describe('ion-compiler', () => {
141142
const importerBasename = dirname(importer);
142143
const importeeFullPath = join(resolve(join(importerBasename, importee)), 'index.ts');
143144

144-
context.fileCache.set(importeeFullPath, { path: importeeFullPath, content: null});
145+
context.fileCache.put(importeeFullPath, { path: importeeFullPath, content: null});
145146

146147
// act
147148
const result = resolveId(importee, importer, context);
@@ -153,8 +154,8 @@ describe('ion-compiler', () => {
153154
it('should return null when importee isn\'t found in memory', () => {
154155
// arrange
155156
let context: BuildContext = {};
156-
context.fileCache = new Map<string, File>();
157-
context.fileCache.set(importer, {
157+
context.fileCache = new FileCache();
158+
context.fileCache.put(importer, {
158159
path: importer,
159160
content: 'fake irrelevant data'
160161
});

src/transpile.ts

+14-31
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { FileCache } from './util/file-cache';
12
import { BuildContext, File } from './util/interfaces';
23
import { BuildError, Logger } from './util/logger';
34
import { buildJsSourceMaps } from './bundle';
@@ -36,11 +37,8 @@ export function transpile(context?: BuildContext) {
3637

3738

3839
export function transpileUpdate(event: string, filePath: string, context: BuildContext) {
39-
if (!filePath.endsWith('.ts') && cachedTsFiles) {
40-
// however this ran, the changed file wasn't a .ts file
41-
// so if we already have tsFiles then make sure the context
42-
// has them and carry on
43-
context.fileCache = cachedTsFiles;
40+
if (!filePath.endsWith('.ts') ) {
41+
// however this ran, the changed file wasn't a .ts file so carry on
4442
return Promise.resolve();
4543
}
4644

@@ -68,10 +66,6 @@ export function transpileUpdate(event: string, filePath: string, context: BuildC
6866
* The full TS build for all app files.
6967
*/
7068
export function transpileWorker(context: BuildContext, workerConfig: TranspileWorkerConfig) {
71-
// forget any tsFiles we've already cached
72-
if (workerConfig.writeInMemory) {
73-
context.fileCache = null;
74-
}
7569

7670
// let's do this
7771
return new Promise((resolve, reject) => {
@@ -99,13 +93,11 @@ export function transpileWorker(context: BuildContext, workerConfig: TranspileWo
9993
// let's start a new tsFiles object to cache all the transpiled files in
10094
const host = ts.createCompilerHost(tsConfig.options);
10195

102-
const cache = new Map<string, File>();
103-
10496
const program = ts.createProgram(tsFileNames, tsConfig.options, host, cachedProgram);
10597
program.emit(undefined, (path: string, data: string, writeByteOrderMark: boolean, onError: Function, sourceFiles: ts.SourceFile[]) => {
10698
if (workerConfig.writeInMemory) {
107-
writeSourceFiles(cache, sourceFiles);
108-
writeTranspiledFilesCallback(cache, path, data, workerConfig.inlineTemplate);
99+
writeSourceFiles(context.fileCache, sourceFiles);
100+
writeTranspiledFilesCallback(context.fileCache, path, data, workerConfig.inlineTemplate);
109101
}
110102
});
111103

@@ -117,7 +109,7 @@ export function transpileWorker(context: BuildContext, workerConfig: TranspileWo
117109

118110
if (diagnostics.length) {
119111
// transpile failed :(
120-
cachedProgram = cachedTsFiles = null;
112+
cachedProgram = null;
121113

122114
const buildError = new BuildError();
123115
buildError.updatedDiagnostics = true;
@@ -128,14 +120,6 @@ export function transpileWorker(context: BuildContext, workerConfig: TranspileWo
128120
// cache the typescript program for later use
129121
cachedProgram = program;
130122

131-
if (workerConfig.writeInMemory) {
132-
context.fileCache = cache;
133-
}
134-
135-
if (workerConfig.cache) {
136-
cachedTsFiles = cache;
137-
}
138-
139123
resolve();
140124
}
141125
});
@@ -209,9 +193,9 @@ function transpileUpdateWorker(event: string, filePath: string, context: BuildCo
209193
const jsFile = { path: newPath, content: jsContent };
210194
const tsFile = { path: filePath, content: sourceText};
211195

212-
context.fileCache.set(sourceMapFile.path, sourceMapFile);
213-
context.fileCache.set(jsFile.path, jsFile);
214-
context.fileCache.set(tsFile.path, tsFile);
196+
context.fileCache.put(sourceMapFile.path, sourceMapFile);
197+
context.fileCache.put(jsFile.path, jsFile);
198+
context.fileCache.put(tsFile.path, tsFile);
215199

216200
// cool, the lil transpiling went through, but
217201
// let's still do the big transpiling (on another processor core)
@@ -251,13 +235,13 @@ function cleanFileNames(context: BuildContext, fileNames: string[]) {
251235
return fileNames.filter(f => (f.indexOf(removeFileName) === -1));
252236
}
253237

254-
function writeSourceFiles(fileCache: Map<String, File>, sourceFiles: ts.SourceFile[]) {
238+
function writeSourceFiles(fileCache: FileCache, sourceFiles: ts.SourceFile[]) {
255239
for (const sourceFile of sourceFiles) {
256-
fileCache.set(sourceFile.fileName, { path: sourceFile.fileName, content: sourceFile.text });
240+
fileCache.put(sourceFile.fileName, { path: sourceFile.fileName, content: sourceFile.text });
257241
}
258242
}
259243

260-
function writeTranspiledFilesCallback(fileCache: Map<String, File>, sourcePath: string, data: string, shouldInlineTemplate: boolean) {
244+
function writeTranspiledFilesCallback(fileCache: FileCache, sourcePath: string, data: string, shouldInlineTemplate: boolean) {
261245
sourcePath = normalize(sourcePath);
262246

263247
if (endsWith(sourcePath, '.js')) {
@@ -274,7 +258,7 @@ function writeTranspiledFilesCallback(fileCache: Map<String, File>, sourcePath:
274258
file.content = data;
275259
}
276260

277-
fileCache.set(sourcePath, file);
261+
fileCache.put(sourcePath, file);
278262

279263
} else if (endsWith(sourcePath, '.js.map')) {
280264

@@ -285,7 +269,7 @@ function writeTranspiledFilesCallback(fileCache: Map<String, File>, sourcePath:
285269
}
286270
file.content = data;
287271

288-
fileCache.set(sourcePath, file);
272+
fileCache.put(sourcePath, file);
289273
}
290274
}
291275

@@ -332,7 +316,6 @@ export function getTsConfig(context: BuildContext, tsConfigPath?: string): TsCon
332316

333317

334318
let cachedProgram: ts.Program = null;
335-
let cachedTsFiles: Map<string, File> = null;
336319

337320
export function getTsConfigPath(context: BuildContext) {
338321
return join(context.rootDir, 'tsconfig.json');

src/util/config.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { accessSync, readJSONSync, statSync } from 'fs-extra';
22
import { BuildContext, TaskInfo } from './interfaces';
33
import { join, resolve } from 'path';
44
import { objectAssign } from './helpers';
5+
import { FileCache } from './file-cache';
56

67

78
/**
@@ -21,6 +22,7 @@ import { objectAssign } from './helpers';
2122
export function generateContext(context?: BuildContext): BuildContext {
2223
if (!context) {
2324
context = {};
25+
context.fileCache = new FileCache();
2426
}
2527

2628
context.rootDir = resolve(context.rootDir || getConfigValue(context, '--rootDir', null, ENV_VAR_ROOT_DIR, ENV_VAR_ROOT_DIR.toLowerCase(), processCwd));

src/util/events.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@ export const EventType = {
2626
DirectoryAdd: 'DirectoryAdd',
2727
DirectoryDelete: 'DirectoryDelete',
2828
TaskEvent: 'TaskEvent',
29-
UpdatedDiagnostics: 'UpdatedDiagnostics'
29+
UpdatedDiagnostics: 'UpdatedDiagnostics',
30+
31+
WebpackFilesChanged: 'DanFileChanged',
32+
DanFileDeleted: 'DanFileDeleted'
3033
};

0 commit comments

Comments
 (0)