feat(@angular/cli): remove deduped licenses

This commit is contained in:
Sumit Arora 2017-02-14 11:13:17 -05:00 committed by Filipe Silva
parent d1cac3255b
commit e72693a948
10 changed files with 47 additions and 5 deletions

View File

@ -81,6 +81,8 @@ Flag | `--dev` | `--prod`
`--sourcemaps` | `true` | `false` `--sourcemaps` | `true` | `false`
`--extract-css` | `false` | `true` `--extract-css` | `false` | `true`
`--extract-licenses` Extract all licenses in a separate file, in the case of production builds only.
`--i18n-file` Localization file to use for i18n.
`--prod` also sets the following non-flaggable settings: `--prod` also sets the following non-flaggable settings:
- Adds service worker if configured in `.angular-cli.json`. - Adds service worker if configured in `.angular-cli.json`.
- Replaces `process.env.NODE_ENV` in modules with the `production` value (this is needed for some libraries, like react). - Replaces `process.env.NODE_ENV` in modules with the `production` value (this is needed for some libraries, like react).

View File

@ -66,6 +66,7 @@
"less": "^2.7.2", "less": "^2.7.2",
"less-loader": "^4.0.2", "less-loader": "^4.0.2",
"loader-utils": "^1.0.2", "loader-utils": "^1.0.2",
"license-webpack-plugin": "^0.4.3",
"lodash": "^4.11.1", "lodash": "^4.11.1",
"magic-string": "^0.19.0", "magic-string": "^0.19.0",
"memory-fs": "^0.4.1", "memory-fs": "^0.4.1",

View File

@ -96,7 +96,8 @@ export const baseBuildCommandOptions: any = [
}, },
{ {
name: 'watch', name: 'watch',
type: Boolean, default: false, type: Boolean,
default: false,
aliases: ['w'], aliases: ['w'],
description: 'Run build when files change.' description: 'Run build when files change.'
}, },
@ -131,6 +132,12 @@ export const baseBuildCommandOptions: any = [
type: Boolean, type: Boolean,
default: false, default: false,
description: 'Do not use the real path when resolving modules.' description: 'Do not use the real path when resolving modules.'
},
{
name: 'extract-licenses',
type: Boolean,
default: true,
description: 'Extract all licenses in a separate file, in the case of production builds only.'
} }
]; ];

View File

@ -19,4 +19,5 @@ export interface BuildOptions {
app?: string; app?: string;
deleteOutputPath?: boolean; deleteOutputPath?: boolean;
preserveSymlinks?: boolean; preserveSymlinks?: boolean;
extractLicenses?: boolean;
} }

View File

@ -7,6 +7,7 @@ import { StaticAssetPlugin } from '../../plugins/static-asset';
import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin'; import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin';
import { WebpackConfigOptions } from '../webpack-config'; import { WebpackConfigOptions } from '../webpack-config';
const licensePlugin = require('license-webpack-plugin');
export const getProdConfig = function (wco: WebpackConfigOptions) { export const getProdConfig = function (wco: WebpackConfigOptions) {
const { projectRoot, buildOptions, appConfig } = wco; const { projectRoot, buildOptions, appConfig } = wco;
@ -79,6 +80,13 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
entryPoints['sw-register'] = [registerPath]; entryPoints['sw-register'] = [registerPath];
} }
if (buildOptions.extractLicenses) {
extraPlugins.push(new licensePlugin({
pattern: /^(MIT|ISC|BSD.*)$/,
suppressErrors: true
}));
}
return { return {
entry: entryPoints, entry: entryPoints,
plugins: [ plugins: [
@ -89,7 +97,8 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
new webpack.optimize.UglifyJsPlugin(<any>{ new webpack.optimize.UglifyJsPlugin(<any>{
mangle: { screw_ie8: true }, mangle: { screw_ie8: true },
compress: { screw_ie8: true, warnings: buildOptions.verbose }, compress: { screw_ie8: true, warnings: buildOptions.verbose },
sourceMap: buildOptions.sourcemaps sourceMap: buildOptions.sourcemaps,
comments: false
}) })
].concat(extraPlugins) ].concat(extraPlugins)
}; };

View File

@ -52,6 +52,7 @@
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"less": "^2.7.2", "less": "^2.7.2",
"less-loader": "^4.0.2", "less-loader": "^4.0.2",
"license-webpack-plugin": "^0.4.2",
"lodash": "^4.11.1", "lodash": "^4.11.1",
"memory-fs": "^0.4.1", "memory-fs": "^0.4.1",
"minimatch": "^3.0.3", "minimatch": "^3.0.3",

View File

@ -21,6 +21,7 @@ const angularCliPlugins = require('../plugins/webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const SilentError = require('silent-error'); const SilentError = require('silent-error');
const licensePlugin = require('license-webpack-plugin');
const Task = require('../ember-cli/lib/models/task'); const Task = require('../ember-cli/lib/models/task');
const ProgressPlugin = require('webpack/lib/ProgressPlugin'); const ProgressPlugin = require('webpack/lib/ProgressPlugin');
@ -134,6 +135,12 @@ class JsonWebpackSerializer {
return plugin.defaultValues; return plugin.defaultValues;
} }
private _licenseWebpackPlugin(plugin: any) {
return {
'pattern': plugin.pattern
};
}
private _pluginsReplacer(plugins: any[]) { private _pluginsReplacer(plugins: any[]) {
return plugins.map(plugin => { return plugins.map(plugin => {
let args = plugin.options || undefined; let args = plugin.options || undefined;
@ -180,13 +187,14 @@ class JsonWebpackSerializer {
args = this._environmentPlugin(plugin); args = this._environmentPlugin(plugin);
this._addImport('webpack', 'EnvironmentPlugin'); this._addImport('webpack', 'EnvironmentPlugin');
break; break;
case licensePlugin:
args = this._licenseWebpackPlugin(plugin);
this.variableImports['license-webpack-plugin'] = 'licensePlugin';
default: default:
if (plugin.constructor.name == 'AngularServiceWorkerPlugin') { if (plugin.constructor.name == 'AngularServiceWorkerPlugin') {
this._addImport('@angular/service-worker/build/webpack', plugin.constructor.name); this._addImport('@angular/service-worker/build/webpack', plugin.constructor.name);
} }
break; break;
} }
const argsSerialized = JSON.stringify(args, (k, v) => this._replacer(k, v), 2) || ''; const argsSerialized = JSON.stringify(args, (k, v) => this._replacer(k, v), 2) || '';

View File

@ -1,7 +1,8 @@
import {ng} from '../../utils/process'; import {ng} from '../../utils/process';
import {expectFileToMatch} from '../../utils/fs'; import {expectFileToMatch, expectFileToExist} from '../../utils/fs';
import {expectGitToBeClean} from '../../utils/git'; import {expectGitToBeClean} from '../../utils/git';
import {getGlobalVariable} from '../../utils/env'; import {getGlobalVariable} from '../../utils/env';
import {expectToFail} from '../../utils/utils';
export default function() { export default function() {
@ -9,6 +10,7 @@ export default function() {
return ng('build', '--env=dev') return ng('build', '--env=dev')
.then(() => expectFileToMatch('dist/index.html', 'main.bundle.js')) .then(() => expectFileToMatch('dist/index.html', 'main.bundle.js'))
.then(() => expectToFail(() => expectFileToExist('dist/3rdpartylicenses.txt')))
// If this is an ejected test, the eject will create files so git will not be clean. // If this is an ejected test, the eject will create files so git will not be clean.
.then(() => !ejected && expectGitToBeClean()); .then(() => !ejected && expectGitToBeClean());
} }

View File

@ -0,0 +1,10 @@
import {join} from 'path';
import {expectFileToExist} from '../../utils/fs';
import {expectToFail} from '../../utils/utils';
import {ng} from '../../utils/process';
export default function() {
return ng('build', '--prod', '--extract-licenses=false')
.then(() => expectFileToExist(join(process.cwd(), 'dist')))
.then(() => expectToFail(() => expectFileToExist('dist/3rdpartylicenses.txt')));
}

View File

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