Skip to content

Commit e72693a

Browse files
sumitarorafilipesilva
authored andcommitted
feat(@angular/cli): remove deduped licenses
1 parent d1cac32 commit e72693a

File tree

10 files changed

+47
-5
lines changed

10 files changed

+47
-5
lines changed

docs/documentation/build.md

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Flag | `--dev` | `--prod`
8181
`--sourcemaps` | `true` | `false`
8282
`--extract-css` | `false` | `true`
8383

84+
`--extract-licenses` Extract all licenses in a separate file, in the case of production builds only.
85+
`--i18n-file` Localization file to use for i18n.
8486
`--prod` also sets the following non-flaggable settings:
8587
- Adds service worker if configured in `.angular-cli.json`.
8688
- Replaces `process.env.NODE_ENV` in modules with the `production` value (this is needed for some libraries, like react).

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"less": "^2.7.2",
6767
"less-loader": "^4.0.2",
6868
"loader-utils": "^1.0.2",
69+
"license-webpack-plugin": "^0.4.3",
6970
"lodash": "^4.11.1",
7071
"magic-string": "^0.19.0",
7172
"memory-fs": "^0.4.1",

packages/@angular/cli/commands/build.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ export const baseBuildCommandOptions: any = [
9696
},
9797
{
9898
name: 'watch',
99-
type: Boolean, default: false,
99+
type: Boolean,
100+
default: false,
100101
aliases: ['w'],
101102
description: 'Run build when files change.'
102103
},
@@ -131,6 +132,12 @@ export const baseBuildCommandOptions: any = [
131132
type: Boolean,
132133
default: false,
133134
description: 'Do not use the real path when resolving modules.'
135+
},
136+
{
137+
name: 'extract-licenses',
138+
type: Boolean,
139+
default: true,
140+
description: 'Extract all licenses in a separate file, in the case of production builds only.'
134141
}
135142
];
136143

packages/@angular/cli/models/build-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export interface BuildOptions {
1919
app?: string;
2020
deleteOutputPath?: boolean;
2121
preserveSymlinks?: boolean;
22+
extractLicenses?: boolean;
2223
}

packages/@angular/cli/models/webpack-configs/production.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { StaticAssetPlugin } from '../../plugins/static-asset';
77
import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin';
88
import { WebpackConfigOptions } from '../webpack-config';
99

10+
const licensePlugin = require('license-webpack-plugin');
1011

1112
export const getProdConfig = function (wco: WebpackConfigOptions) {
1213
const { projectRoot, buildOptions, appConfig } = wco;
@@ -79,6 +80,13 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
7980
entryPoints['sw-register'] = [registerPath];
8081
}
8182

83+
if (buildOptions.extractLicenses) {
84+
extraPlugins.push(new licensePlugin({
85+
pattern: /^(MIT|ISC|BSD.*)$/,
86+
suppressErrors: true
87+
}));
88+
}
89+
8290
return {
8391
entry: entryPoints,
8492
plugins: [
@@ -89,7 +97,8 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
8997
new webpack.optimize.UglifyJsPlugin(<any>{
9098
mangle: { screw_ie8: true },
9199
compress: { screw_ie8: true, warnings: buildOptions.verbose },
92-
sourceMap: buildOptions.sourcemaps
100+
sourceMap: buildOptions.sourcemaps,
101+
comments: false
93102
})
94103
].concat(extraPlugins)
95104
};

packages/@angular/cli/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"json-loader": "^0.5.4",
5353
"less": "^2.7.2",
5454
"less-loader": "^4.0.2",
55+
"license-webpack-plugin": "^0.4.2",
5556
"lodash": "^4.11.1",
5657
"memory-fs": "^0.4.1",
5758
"minimatch": "^3.0.3",

packages/@angular/cli/tasks/eject.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const angularCliPlugins = require('../plugins/webpack');
2121
const ExtractTextPlugin = require('extract-text-webpack-plugin');
2222
const HtmlWebpackPlugin = require('html-webpack-plugin');
2323
const SilentError = require('silent-error');
24+
const licensePlugin = require('license-webpack-plugin');
2425
const Task = require('../ember-cli/lib/models/task');
2526

2627
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
@@ -134,6 +135,12 @@ class JsonWebpackSerializer {
134135
return plugin.defaultValues;
135136
}
136137

138+
private _licenseWebpackPlugin(plugin: any) {
139+
return {
140+
'pattern': plugin.pattern
141+
};
142+
}
143+
137144
private _pluginsReplacer(plugins: any[]) {
138145
return plugins.map(plugin => {
139146
let args = plugin.options || undefined;
@@ -180,13 +187,14 @@ class JsonWebpackSerializer {
180187
args = this._environmentPlugin(plugin);
181188
this._addImport('webpack', 'EnvironmentPlugin');
182189
break;
183-
190+
case licensePlugin:
191+
args = this._licenseWebpackPlugin(plugin);
192+
this.variableImports['license-webpack-plugin'] = 'licensePlugin';
184193
default:
185194
if (plugin.constructor.name == 'AngularServiceWorkerPlugin') {
186195
this._addImport('@angular/service-worker/build/webpack', plugin.constructor.name);
187196
}
188197
break;
189-
190198
}
191199

192200
const argsSerialized = JSON.stringify(args, (k, v) => this._replacer(k, v), 2) || '';

tests/e2e/tests/build/dev-build.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import {ng} from '../../utils/process';
2-
import {expectFileToMatch} from '../../utils/fs';
2+
import {expectFileToMatch, expectFileToExist} from '../../utils/fs';
33
import {expectGitToBeClean} from '../../utils/git';
44
import {getGlobalVariable} from '../../utils/env';
5+
import {expectToFail} from '../../utils/utils';
56

67

78
export default function() {
89
const ejected = getGlobalVariable('argv').eject;
910

1011
return ng('build', '--env=dev')
1112
.then(() => expectFileToMatch('dist/index.html', 'main.bundle.js'))
13+
.then(() => expectToFail(() => expectFileToExist('dist/3rdpartylicenses.txt')))
1214
// If this is an ejected test, the eject will create files so git will not be clean.
1315
.then(() => !ejected && expectGitToBeClean());
1416
}
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {join} from 'path';
2+
import {expectFileToExist} from '../../utils/fs';
3+
import {expectToFail} from '../../utils/utils';
4+
import {ng} from '../../utils/process';
5+
6+
export default function() {
7+
return ng('build', '--prod', '--extract-licenses=false')
8+
.then(() => expectFileToExist(join(process.cwd(), 'dist')))
9+
.then(() => expectToFail(() => expectFileToExist('dist/3rdpartylicenses.txt')));
10+
}

tests/e2e/tests/build/prod-build.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default function() {
1717
// Check for cache busting hash script src
1818
.then(() => expectFileToMatch('dist/index.html', /main\.[0-9a-f]{20}\.bundle\.js/))
1919
.then(() => expectFileToMatch('dist/index.html', /styles\.[0-9a-f]{20}\.bundle\.css/))
20+
.then(() => expectFileToExist('dist/3rdpartylicenses.txt'))
2021
// Defaults to AoT
2122
.then(() => {
2223
const main = readdirSync('./dist').find(name => !!name.match(/main.[a-z0-9]+\.bundle\.js/));

0 commit comments

Comments
 (0)