Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Libraries > Separated transpile and bundle actions #439

Merged
merged 5 commits into from
Jul 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 41 additions & 4 deletions cli/build-public-library.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/*jshint node: true*/
'use strict';

const spawn = require('cross-spawn');
const fs = require('fs-extra');
const rimraf = require('rimraf');
const logger = require('@blackbaud/skyux-logger');

const stageTypeScriptFiles = require('./utils/stage-library-ts');
const preparePackage = require('./utils/prepare-library-package');
const webpackConfig = require('../config/webpack/build-public-library.webpack.config.js');
const skyPagesConfigUtil = require('../config/sky-pages/sky-pages.config');
const runCompiler = require('./utils/run-compiler');
const tsLinter = require('./utils/ts-linter');
Expand Down Expand Up @@ -81,9 +81,14 @@ function writeTSConfig() {
fs.writeJSONSync(skyPagesConfigUtil.spaPathTemp('tsconfig.json'), config);
}

/**
* Create a "placeholder" module for Angular AoT compiler.
* This is needed to avoid breaking changes; in the future,
* we should require a module name be provided by the consumer.
*/
function writePlaceholderModule() {
const content = `import { NgModule } from '@angular/core';
import './index';
export * from './index';
@NgModule({})
export class SkyLibPlaceholderModule {}
`;
Expand All @@ -93,11 +98,42 @@ export class SkyLibPlaceholderModule {}
});
}

function transpile(skyPagesConfig, webpack) {
/**
* Creates a UMD JavaScript bundle.
* @param {*} skyPagesConfig
* @param {*} webpack
*/
function createBundle(skyPagesConfig, webpack) {
const webpackConfig = require('../config/webpack/build-public-library.webpack.config');
const config = webpackConfig.getWebpackConfig(skyPagesConfig);
return runCompiler(webpack, config);
}

/**
* Transpiles TypeScript files into JavaScript files
* to be included with the NPM package.
*/
function transpile() {
return new Promise((resolve, reject) => {
const result = spawn.sync(
'node',
[
skyPagesConfigUtil.spaPath('node_modules', '.bin', 'ngc'),
'--project',
skyPagesConfigUtil.spaPathTemp('tsconfig.json')
],
{ stdio: 'inherit' }
);

if (result.err) {
reject(result.err);
return;
}

resolve();
});
}

module.exports = (skyPagesConfig, webpack) => {
runLinter();
cleanAll();
Expand All @@ -106,7 +142,8 @@ module.exports = (skyPagesConfig, webpack) => {
writePlaceholderModule();
copyRuntime();

return transpile(skyPagesConfig, webpack)
return createBundle(skyPagesConfig, webpack)
.then(() => transpile())
.then(() => {
cleanRuntime();
preparePackage();
Expand Down
32 changes: 18 additions & 14 deletions config/webpack/build-public-library.webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
const ngtools = require('@ngtools/webpack');
const fs = require('fs-extra');
const webpack = require('webpack');
const ngcWebpack = require('ngc-webpack');
const skyPagesConfigUtil = require('../sky-pages/sky-pages.config');

function parseRegExp(name) {
Expand All @@ -26,19 +25,27 @@ function getWebpackConfig(skyPagesConfig) {
skyPagesConfigUtil.spaPath('package.json')
);

let builderDependencies = [];
let dependencies = [];
if (builderPackageJson.dependencies) {
builderDependencies = Object.keys(builderPackageJson.dependencies)
.map(key => parseRegExp(key));
dependencies = Object.keys(builderPackageJson.dependencies);
}

if (builderPackageJson.peerDependencies) {
dependencies = dependencies.concat(Object.keys(builderPackageJson.peerDependencies));
}

let spaDependencies = [];
if (spaPackageJson.dependencies) {
spaDependencies = Object.keys(spaPackageJson.dependencies)
.map(key => parseRegExp(key));
dependencies = dependencies.concat(Object.keys(spaPackageJson.dependencies));
}

if (spaPackageJson.peerDependencies) {
dependencies = dependencies.concat(Object.keys(spaPackageJson.peerDependencies));
}

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

return {
entry: skyPagesConfigUtil.spaPathTemp('index.ts'),
Expand Down Expand Up @@ -74,12 +81,9 @@ function getWebpackConfig(skyPagesConfig) {
]
},
plugins: [
// Generate transpiled source files.
new ngcWebpack.NgcWebpackPlugin({
tsConfig: skyPagesConfigUtil.spaPathTemp('tsconfig.json')
}),

// Generates an aot JavaScript bundle.
// Generates an AoT JavaScript bundle.
// TODO: Remove this in favor of Angular's native library bundler,
// once we've upgraded to Angular version 6.
new ngtools.AotPlugin({
tsConfigPath: skyPagesConfigUtil.spaPathTemp('tsconfig.json'),
entryModule: skyPagesConfigUtil.spaPathTemp('main.ts') + '#SkyLibPlaceholderModule',
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
"karma-webpack": "2.0.3",
"loader-utils": "1.1.0",
"lodash.mergewith": "4.6.0",
"ngc-webpack": "3.0.0",
"node-sass": "4.5.3",
"node-sass-tilde-importer": "1.0.2",
"open": "0.0.5",
Expand Down
22 changes: 21 additions & 1 deletion test/cli-build-public-library.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('cli build-public-library', () => {
let webpackConfig;
let mockWebpack;
let mockFs;
let mockSpawn;

beforeEach(() => {
mockFs = {
Expand All @@ -19,6 +20,12 @@ describe('cli build-public-library', () => {
copySync() {}
};

mockSpawn = {
sync() {
return {};
}
};

mockWebpack = () => {
return {
run: (cb) => {
Expand Down Expand Up @@ -50,6 +57,7 @@ describe('cli build-public-library', () => {
});

mock('fs-extra', mockFs);
mock('cross-spawn', mockSpawn);

spyOn(process, 'exit').and.callFake(() => {});
spyOn(skyPagesConfigUtil, 'spaPath').and.returnValue('');
Expand Down Expand Up @@ -108,7 +116,7 @@ describe('cli build-public-library', () => {
const args = spy.calls.argsFor(0);
expect(args[0]).toEqual('main.ts');
expect(args[1]).toEqual(`import { NgModule } from '@angular/core';
import './index';
export * from './index';
@NgModule({})
export class SkyLibPlaceholderModule {}
`);
Expand Down Expand Up @@ -155,4 +163,16 @@ export class SkyLibPlaceholderModule {}
done();
});
});

it('should handle transpilation errors', (done) => {
const cliCommand = mock.reRequire(requirePath);
const spy = spyOn(logger, 'error').and.callThrough();
spyOn(mockSpawn, 'sync').and.returnValue({
err: 'something bad happened'
});
cliCommand({}, mockWebpack).then(() => {
expect(spy).toHaveBeenCalledWith('something bad happened');
done();
});
});
});
7 changes: 7 additions & 0 deletions test/config-webpack-build-public-library.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ describe('config webpack build public library', () => {
'@angular/common': '4.3.6',
'@pact-foundation/pact-web': '5.3.0',
'zone.js': '0.8.10'
},
peerDependencies: {
'@angular/core': '4.3.6'
}
};
}
Expand All @@ -90,6 +93,9 @@ describe('config webpack build public library', () => {
dependencies: {
'@blackbaud/skyux': '2.13.0',
'@blackbaud-internal/skyux-lib-testing': 'latest'
},
peerDependencies: {
'@angular/core': '4.3.6'
}
};
});
Expand All @@ -99,6 +105,7 @@ describe('config webpack build public library', () => {
/^@angular\/common/,
/^@pact\-foundation\/pact\-web/,
/^zone\.js/,
/^@angular\/core/,
/^@blackbaud\/skyux/,
/^@blackbaud\-internal\/skyux\-lib\-testing/
]);
Expand Down