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

Commit e14f819

Browse files
committed
feature(webpack): add scope hoisting to webpack, update sass to read scss files from disk
1 parent be53fa3 commit e14f819

File tree

6 files changed

+55
-37
lines changed

6 files changed

+55
-37
lines changed

config/webpack.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ var path = require('path');
22
var webpack = require('webpack');
33
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);
44

5+
var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
6+
57
module.exports = {
68
entry: process.env.IONIC_APP_ENTRY_POINT,
79
output: {
@@ -36,6 +38,7 @@ module.exports = {
3638

3739
plugins: [
3840
ionicWebpackFactory.getIonicEnvironmentPlugin(),
41+
new ModuleConcatPlugin()
3942
],
4043

4144
// Some libraries import Node modules but don't use them in the browser.

src/optimization.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { basename, extname } from 'path';
1+
import { basename, dirname, extname, join } from 'path';
22

33
import * as MagicString from 'magic-string';
44

@@ -76,6 +76,7 @@ export function doOptimizations(context: BuildContext, dependencyMap: Map<string
7676
modifiedMap = checkIfProviderIsUsedInSrc(context, modifiedMap);
7777
const results = calculateUnusedComponents(modifiedMap);
7878
purgeUnusedImports(context, results.purgedModules);
79+
updateIonicComponentsUsed(context, dependencyMap, results.purgedModules);
7980
}
8081
}
8182

@@ -88,6 +89,16 @@ export function doOptimizations(context: BuildContext, dependencyMap: Map<string
8889
return modifiedMap;
8990
}
9091

92+
function updateIonicComponentsUsed(context: BuildContext, originalDependencyMap: Map<string, Set<string>>, purgedModules: Map<string, Set<string>>) {
93+
const includedModuleSet = new Set<string>();
94+
originalDependencyMap.forEach((set: Set<string>, modulePath: string) => {
95+
if (!purgedModules.has(modulePath)) {
96+
includedModuleSet.add(modulePath);
97+
}
98+
});
99+
context.moduleFiles = Array.from(includedModuleSet);
100+
}
101+
91102
function optimizationEnabled() {
92103
const purgeDecorators = getBooleanPropertyValue(Constants.ENV_PURGE_DECORATORS);
93104
const manualTreeshaking = getBooleanPropertyValue(Constants.ENV_MANUAL_TREESHAKING);
@@ -193,8 +204,8 @@ export function getConfig(context: BuildContext, configFile: string): WebpackCon
193204

194205
const taskInfo: TaskInfo = {
195206
fullArg: '--optimization',
196-
shortArg: '-dt',
197-
envVar: 'IONIC_DEPENDENCY_TREE',
198-
packageConfig: 'ionic_dependency_tree',
207+
shortArg: '-op',
208+
envVar: 'IONIC_OPTIMIZATION',
209+
packageConfig: 'ionic_optimization',
199210
defaultConfigFile: 'optimization.config'
200211
};

src/preprocess.spec.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { join } from 'path';
12
import * as preprocess from './preprocess';
23
import * as deeplink from './deep-linking';
34
import * as helpers from './util/helpers';
45
import * as optimization from './optimization';
5-
6+
import * as globUtil from './util/glob-util';
67

78
describe('Preprocess Task', () => {
89
describe('preprocess', () => {
@@ -12,10 +13,16 @@ describe('Preprocess Task', () => {
1213
optimizeJs: false
1314
};
1415

16+
const mockDirName = join('some', 'fake', 'dir');
17+
const mockGlobResults = [];
18+
mockGlobResults.push({ absolutePath: mockDirName});
19+
mockGlobResults.push({ absolutePath: mockDirName + '2'});
1520
spyOn(deeplink, deeplink.deepLinking.name).and.returnValue(Promise.resolve());
1621
spyOn(optimization, optimization.optimization.name).and.returnValue(Promise.resolve());
1722
spyOn(helpers, helpers.getBooleanPropertyValue.name).and.returnValue(false);
1823
spyOn(preprocess, preprocess.writeFilesToDisk.name).and.returnValue(null);
24+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(mockDirName);
25+
spyOn(globUtil, globUtil.globAll.name).and.returnValue(Promise.resolve(mockGlobResults));
1926

2027
// act
2128
return preprocess.preprocess(context).then(() => {
@@ -27,20 +34,30 @@ describe('Preprocess Task', () => {
2734

2835
it('should call optimization or write files to disk', () => {
2936
// arrange
30-
const context = {
37+
const context: any = {
3138
optimizeJs: true
3239
};
3340

41+
const mockDirName = join('some', 'fake', 'dir');
42+
const mockGlobResults = [];
43+
mockGlobResults.push({ absolutePath: mockDirName});
44+
mockGlobResults.push({ absolutePath: mockDirName + '2'});
3445
spyOn(deeplink, deeplink.deepLinking.name).and.returnValue(Promise.resolve());
3546
spyOn(optimization, optimization.optimization.name).and.returnValue(Promise.resolve());
3647
spyOn(helpers, helpers.getBooleanPropertyValue.name).and.returnValue(false);
3748
spyOn(preprocess, preprocess.writeFilesToDisk.name).and.returnValue(null);
49+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(mockDirName);
50+
spyOn(globUtil, globUtil.globAll.name).and.returnValue(Promise.resolve(mockGlobResults));
3851

3952
// act
4053
return preprocess.preprocess(context).then(() => {
4154
// assert
4255
expect(optimization.optimization).toHaveBeenCalled();
4356
expect(preprocess.writeFilesToDisk).not.toHaveBeenCalledWith();
57+
expect(context.moduleFiles).toBeTruthy();
58+
expect(context.moduleFiles.length).toEqual(2);
59+
expect(context.moduleFiles[0]).toEqual(mockDirName);
60+
expect(context.moduleFiles[1]).toEqual(mockDirName + '2');
4461
});
4562
});
4663
});

src/preprocess.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { basename, dirname, join, relative } from 'path';
44
import { Logger } from './logger/logger';
55
import * as Constants from './util/constants';
66
import { BuildError } from './util/errors';
7-
import { getBooleanPropertyValue } from './util/helpers';
7+
import { globAll, GlobResult } from './util/glob-util';
8+
import { getBooleanPropertyValue, getStringPropertyValue } from './util/helpers';
89
import { BuildContext, ChangedFile } from './util/interfaces';
910
import { optimization } from './optimization';
1011
import { deepLinking, deepLinkingUpdate } from './deep-linking';
@@ -26,8 +27,8 @@ export function preprocess(context: BuildContext) {
2627
function preprocessWorker(context: BuildContext) {
2728
const bundlePromise = bundleCoreComponents(context);
2829
const deepLinksPromise = getBooleanPropertyValue(Constants.ENV_PARSE_DEEPLINKS) ? deepLinking(context) : Promise.resolve();
29-
30-
return Promise.all([bundlePromise, deepLinksPromise])
30+
const componentSassPromise = lookUpDefaultIonicComponentPaths(context);
31+
return Promise.all([bundlePromise, deepLinksPromise, componentSassPromise])
3132
.then(() => {
3233
if (context.optimizeJs) {
3334
return optimization(context, null);
@@ -67,3 +68,15 @@ export function preprocessUpdate(changedFiles: ChangedFile[], context: BuildCont
6768

6869
return Promise.all(promises);
6970
}
71+
72+
export function lookUpDefaultIonicComponentPaths(context: BuildContext) {
73+
const componentsDirGlob = join(getStringPropertyValue(Constants.ENV_VAR_IONIC_ANGULAR_DIR), 'components', '**', '*.scss');
74+
const srcDirGlob = join(getStringPropertyValue(Constants.ENV_VAR_SRC_DIR), '**', '*.scss');
75+
return globAll([componentsDirGlob, srcDirGlob]).then((results: GlobResult[]) => {
76+
const componentPathSet = new Set<string>();
77+
results.forEach(result => {
78+
componentPathSet.add(result.absolutePath);
79+
});
80+
context.moduleFiles = Array.from(componentPathSet);
81+
});
82+
}

src/rollup.ts

+1-12
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,6 @@ export function rollupWorker(context: BuildContext, configFile: string): Promise
7373

7474
Logger.debug(`bundle.modules: ${bundle.modules.length}`);
7575

76-
// set the module files used in this bundle
77-
// this reference can be used elsewhere in the build (sass)
78-
context.moduleFiles = bundle.modules.map((m) => {
79-
// sometimes, Rollup appends weird prefixes to the path like commonjs:proxy
80-
const index = m.id.indexOf(sep);
81-
if (index >= 0) {
82-
return m.id.substring(index);
83-
}
84-
return m.id;
85-
});
86-
8776
// cache our bundle for later use
8877
if (context.isWatch) {
8978
cachedBundle = bundle;
@@ -225,4 +214,4 @@ export interface RollupLocationInfo {
225214
file: string;
226215
line: number;
227216
column: number;
228-
}
217+
}

src/webpack.ts

+1-16
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,6 @@ function webpackBuildComplete(stats: any, context: BuildContext, webpackConfig:
9393
Logger.debug('Webpack Dependency Map End');
9494
}
9595

96-
// set the module files used in this bundle
97-
// this reference can be used elsewhere in the build (sass)
98-
const files: string[] = stats.compilation.modules.map((webpackObj: any) => {
99-
if (webpackObj.resource) {
100-
return webpackObj.resource;
101-
} else {
102-
return webpackObj.context;
103-
}
104-
}).filter((path: string) => {
105-
// just make sure the path is not null
106-
return path && path.length > 0;
107-
});
108-
109-
context.moduleFiles = files;
110-
11196
return writeBundleFilesToDisk(context);
11297
}
11398

@@ -244,4 +229,4 @@ export interface WebpackOutputObject {
244229
export interface WebpackResolveObject {
245230
extensions: string[];
246231
modules: string[];
247-
}
232+
}

0 commit comments

Comments
 (0)