Skip to content

Commit 1506b51

Browse files
Blackbaud-SteveBrushBlackbaud-MikitaYankouski
authored andcommittedMay 3, 2019
Libraries > Separated transpile and bundle actions (blackbaud#439)
1 parent 047eaaf commit 1506b51

5 files changed

+87
-20
lines changed
 

‎cli/build-public-library.js

+41-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/*jshint node: true*/
22
'use strict';
33

4+
const spawn = require('cross-spawn');
45
const fs = require('fs-extra');
56
const rimraf = require('rimraf');
67
const logger = require('@blackbaud/skyux-logger');
78

89
const stageTypeScriptFiles = require('./utils/stage-library-ts');
910
const preparePackage = require('./utils/prepare-library-package');
10-
const webpackConfig = require('../config/webpack/build-public-library.webpack.config.js');
1111
const skyPagesConfigUtil = require('../config/sky-pages/sky-pages.config');
1212
const runCompiler = require('./utils/run-compiler');
1313
const tsLinter = require('./utils/ts-linter');
@@ -81,9 +81,14 @@ function writeTSConfig() {
8181
fs.writeJSONSync(skyPagesConfigUtil.spaPathTemp('tsconfig.json'), config);
8282
}
8383

84+
/**
85+
* Create a "placeholder" module for Angular AoT compiler.
86+
* This is needed to avoid breaking changes; in the future,
87+
* we should require a module name be provided by the consumer.
88+
*/
8489
function writePlaceholderModule() {
8590
const content = `import { NgModule } from '@angular/core';
86-
import './index';
91+
export * from './index';
8792
@NgModule({})
8893
export class SkyLibPlaceholderModule {}
8994
`;
@@ -93,11 +98,42 @@ export class SkyLibPlaceholderModule {}
9398
});
9499
}
95100

96-
function transpile(skyPagesConfig, webpack) {
101+
/**
102+
* Creates a UMD JavaScript bundle.
103+
* @param {*} skyPagesConfig
104+
* @param {*} webpack
105+
*/
106+
function createBundle(skyPagesConfig, webpack) {
107+
const webpackConfig = require('../config/webpack/build-public-library.webpack.config');
97108
const config = webpackConfig.getWebpackConfig(skyPagesConfig);
98109
return runCompiler(webpack, config);
99110
}
100111

112+
/**
113+
* Transpiles TypeScript files into JavaScript files
114+
* to be included with the NPM package.
115+
*/
116+
function transpile() {
117+
return new Promise((resolve, reject) => {
118+
const result = spawn.sync(
119+
'node',
120+
[
121+
skyPagesConfigUtil.spaPath('node_modules', '.bin', 'ngc'),
122+
'--project',
123+
skyPagesConfigUtil.spaPathTemp('tsconfig.json')
124+
],
125+
{ stdio: 'inherit' }
126+
);
127+
128+
if (result.err) {
129+
reject(result.err);
130+
return;
131+
}
132+
133+
resolve();
134+
});
135+
}
136+
101137
module.exports = (skyPagesConfig, webpack) => {
102138
runLinter();
103139
cleanAll();
@@ -106,7 +142,8 @@ module.exports = (skyPagesConfig, webpack) => {
106142
writePlaceholderModule();
107143
copyRuntime();
108144

109-
return transpile(skyPagesConfig, webpack)
145+
return createBundle(skyPagesConfig, webpack)
146+
.then(() => transpile())
110147
.then(() => {
111148
cleanRuntime();
112149
preparePackage();

‎config/webpack/build-public-library.webpack.config.js

+18-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
const ngtools = require('@ngtools/webpack');
55
const fs = require('fs-extra');
66
const webpack = require('webpack');
7-
const ngcWebpack = require('ngc-webpack');
87
const skyPagesConfigUtil = require('../sky-pages/sky-pages.config');
98

109
function parseRegExp(name) {
@@ -26,19 +25,27 @@ function getWebpackConfig(skyPagesConfig) {
2625
skyPagesConfigUtil.spaPath('package.json')
2726
);
2827

29-
let builderDependencies = [];
28+
let dependencies = [];
3029
if (builderPackageJson.dependencies) {
31-
builderDependencies = Object.keys(builderPackageJson.dependencies)
32-
.map(key => parseRegExp(key));
30+
dependencies = Object.keys(builderPackageJson.dependencies);
31+
}
32+
33+
if (builderPackageJson.peerDependencies) {
34+
dependencies = dependencies.concat(Object.keys(builderPackageJson.peerDependencies));
3335
}
3436

35-
let spaDependencies = [];
3637
if (spaPackageJson.dependencies) {
37-
spaDependencies = Object.keys(spaPackageJson.dependencies)
38-
.map(key => parseRegExp(key));
38+
dependencies = dependencies.concat(Object.keys(spaPackageJson.dependencies));
39+
}
40+
41+
if (spaPackageJson.peerDependencies) {
42+
dependencies = dependencies.concat(Object.keys(spaPackageJson.peerDependencies));
3943
}
4044

41-
const externals = builderDependencies.concat(spaDependencies);
45+
// Remove duplicates from array.
46+
// https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates
47+
const externals = [...new Set(dependencies)]
48+
.map(key => parseRegExp(key));
4249

4350
return {
4451
entry: skyPagesConfigUtil.spaPathTemp('index.ts'),
@@ -74,12 +81,9 @@ function getWebpackConfig(skyPagesConfig) {
7481
]
7582
},
7683
plugins: [
77-
// Generate transpiled source files.
78-
new ngcWebpack.NgcWebpackPlugin({
79-
tsConfig: skyPagesConfigUtil.spaPathTemp('tsconfig.json')
80-
}),
81-
82-
// Generates an aot JavaScript bundle.
84+
// Generates an AoT JavaScript bundle.
85+
// TODO: Remove this in favor of Angular's native library bundler,
86+
// once we've upgraded to Angular version 6.
8387
new ngtools.AotPlugin({
8488
tsConfigPath: skyPagesConfigUtil.spaPathTemp('tsconfig.json'),
8589
entryModule: skyPagesConfigUtil.spaPathTemp('main.ts') + '#SkyLibPlaceholderModule',

‎package.json

-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
"karma-webpack": "2.0.3",
8080
"loader-utils": "1.1.0",
8181
"lodash.mergewith": "4.6.0",
82-
"ngc-webpack": "3.0.0",
8382
"node-sass": "4.5.3",
8483
"node-sass-tilde-importer": "1.0.2",
8584
"open": "0.0.5",

‎test/cli-build-public-library.spec.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe('cli build-public-library', () => {
1111
let webpackConfig;
1212
let mockWebpack;
1313
let mockFs;
14+
let mockSpawn;
1415

1516
beforeEach(() => {
1617
mockFs = {
@@ -19,6 +20,12 @@ describe('cli build-public-library', () => {
1920
copySync() {}
2021
};
2122

23+
mockSpawn = {
24+
sync() {
25+
return {};
26+
}
27+
};
28+
2229
mockWebpack = () => {
2330
return {
2431
run: (cb) => {
@@ -50,6 +57,7 @@ describe('cli build-public-library', () => {
5057
});
5158

5259
mock('fs-extra', mockFs);
60+
mock('cross-spawn', mockSpawn);
5361

5462
spyOn(process, 'exit').and.callFake(() => {});
5563
spyOn(skyPagesConfigUtil, 'spaPath').and.returnValue('');
@@ -108,7 +116,7 @@ describe('cli build-public-library', () => {
108116
const args = spy.calls.argsFor(0);
109117
expect(args[0]).toEqual('main.ts');
110118
expect(args[1]).toEqual(`import { NgModule } from '@angular/core';
111-
import './index';
119+
export * from './index';
112120
@NgModule({})
113121
export class SkyLibPlaceholderModule {}
114122
`);
@@ -155,4 +163,16 @@ export class SkyLibPlaceholderModule {}
155163
done();
156164
});
157165
});
166+
167+
it('should handle transpilation errors', (done) => {
168+
const cliCommand = mock.reRequire(requirePath);
169+
const spy = spyOn(logger, 'error').and.callThrough();
170+
spyOn(mockSpawn, 'sync').and.returnValue({
171+
err: 'something bad happened'
172+
});
173+
cliCommand({}, mockWebpack).then(() => {
174+
expect(spy).toHaveBeenCalledWith('something bad happened');
175+
done();
176+
});
177+
});
158178
});

‎test/config-webpack-build-public-library.spec.js

+7
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ describe('config webpack build public library', () => {
8282
'@angular/common': '4.3.6',
8383
'@pact-foundation/pact-web': '5.3.0',
8484
'zone.js': '0.8.10'
85+
},
86+
peerDependencies: {
87+
'@angular/core': '4.3.6'
8588
}
8689
};
8790
}
@@ -90,6 +93,9 @@ describe('config webpack build public library', () => {
9093
dependencies: {
9194
'@blackbaud/skyux': '2.13.0',
9295
'@blackbaud-internal/skyux-lib-testing': 'latest'
96+
},
97+
peerDependencies: {
98+
'@angular/core': '4.3.6'
9399
}
94100
};
95101
});
@@ -99,6 +105,7 @@ describe('config webpack build public library', () => {
99105
/^@angular\/common/,
100106
/^@pact\-foundation\/pact\-web/,
101107
/^zone\.js/,
108+
/^@angular\/core/,
102109
/^@blackbaud\/skyux/,
103110
/^@blackbaud\-internal\/skyux\-lib\-testing/
104111
]);

0 commit comments

Comments
 (0)
Please sign in to comment.