Skip to content
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
903 changes: 107 additions & 796 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"chalk": "^2.0.1",
"circular-dependency-plugin": "^3.0.0",
"common-tags": "^1.3.1",
"copy-webpack-plugin": "^4.0.1",
"core-object": "^3.1.0",
"css-loader": "^0.28.1",
"cssnano": "^3.10.0",
Expand Down Expand Up @@ -105,6 +106,7 @@
"@angular/core": "^4.0.0",
"@types/chalk": "^0.4.28",
"@types/common-tags": "^1.2.4",
"@types/copy-webpack-plugin": "^4.0.0",
"@types/denodeify": "^1.2.30",
"@types/express": "^4.0.32",
"@types/fs-extra": "^4.0.0",
Expand Down
47 changes: 41 additions & 6 deletions packages/@angular/cli/models/webpack-configs/common.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as webpack from 'webpack';
import * as path from 'path';
import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin';
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
import { NamedLazyChunksWebpackPlugin } from '../../plugins/named-lazy-chunks-webpack-plugin';
import { InsertConcatAssetsWebpackPlugin } from '../../plugins/insert-concat-assets-webpack-plugin';
import { extraEntryParser, getOutputHashFormat } from './utils';
import { extraEntryParser, getOutputHashFormat, AssetPattern } from './utils';
import { isDirectory } from '../../utilities/is-directory';
import { WebpackConfigOptions } from '../webpack-config';

const ConcatPlugin = require('webpack-concat-plugin');
Expand Down Expand Up @@ -84,10 +85,44 @@ export function getCommonConfig(wco: WebpackConfigOptions) {

// process asset entries
if (appConfig.assets) {
extraPlugins.push(new GlobCopyWebpackPlugin({
patterns: appConfig.assets,
globOptions: { cwd: appRoot, dot: true, ignore: '**/.gitkeep' }
}));
const copyWebpackPluginPatterns = appConfig.assets.map((asset: string | AssetPattern) => {
// Convert all string assets to object notation.
asset = typeof asset === 'string' ? { glob: asset } : asset;
// Add defaults.
// Input is always resolved relative to the appRoot.
asset.input = path.resolve(appRoot, asset.input || '');
asset.output = asset.output || '';
asset.glob = asset.glob || '';

// Ensure trailing slash.
if (isDirectory(path.resolve(asset.input))) {
asset.input += '/';
}

// Convert dir patterns to globs.
if (isDirectory(path.resolve(asset.input, asset.glob))) {
asset.glob = asset.glob + '/**/*';
}

return {
context: asset.input,
to: asset.output,
from: {
glob: asset.glob,
dot: true
}
};
});
const copyWebpackPluginOptions = { ignore: ['.gitkeep'] };

const copyWebpackPluginInstance = new CopyWebpackPlugin(copyWebpackPluginPatterns,
copyWebpackPluginOptions);

// Save options so we can use them in eject.
(copyWebpackPluginInstance as any)['copyWebpackPluginPatterns'] = copyWebpackPluginPatterns;
(copyWebpackPluginInstance as any)['copyWebpackPluginOptions'] = copyWebpackPluginOptions;

extraPlugins.push(copyWebpackPluginInstance);
}

if (buildOptions.progress) {
Expand Down
5 changes: 5 additions & 0 deletions packages/@angular/cli/models/webpack-configs/production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
`);
}

// CopyWebpackPlugin replaces GlobCopyWebpackPlugin, but AngularServiceWorkerPlugin depends
// on specific behaviour from latter.
// AngularServiceWorkerPlugin expects the ngsw-manifest.json to be present in the 'emit' phase
// but with CopyWebpackPlugin it's only there on 'after-emit'.
// So for now we keep it here, but if AngularServiceWorkerPlugin changes we remove it.
extraPlugins.push(new GlobCopyWebpackPlugin({
patterns: [
'ngsw-manifest.json',
Expand Down
6 changes: 6 additions & 0 deletions packages/@angular/cli/models/webpack-configs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ export function getOutputHashFormat(option: string, length = 20): HashFormat {
/* tslint:enable:max-line-length */
return hashFormats[option] || hashFormats['none'];
}

export interface AssetPattern {
glob: string;
input?: string;
output?: string;
}
1 change: 1 addition & 0 deletions packages/@angular/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"chalk": "^2.0.1",
"circular-dependency-plugin": "^3.0.0",
"common-tags": "^1.3.1",
"copy-webpack-plugin": "^4.0.1",
"core-object": "^3.1.0",
"css-loader": "^0.28.1",
"cssnano": "^3.10.0",
Expand Down
20 changes: 4 additions & 16 deletions packages/@angular/cli/plugins/glob-copy-webpack-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,21 @@ import * as fs from 'fs';
import * as path from 'path';
import * as glob from 'glob';
import * as denodeify from 'denodeify';
import { AssetPattern } from '../models/webpack-configs/utils';
import { isDirectory } from '../utilities/is-directory';

const flattenDeep = require('lodash/flattenDeep');
const globPromise = <any>denodeify(glob);
const statPromise = <any>denodeify(fs.stat);

function isDirectory(path: string) {
try {
return fs.statSync(path).isDirectory();
} catch (_) {
return false;
}
}

interface Asset {
originPath: string;
destinationPath: string;
relativePath: string;
}

export interface Pattern {
glob: string;
input?: string;
output?: string;
}

export interface GlobCopyWebpackPluginOptions {
patterns: (string | Pattern)[];
patterns: (string | AssetPattern)[];
globOptions: any;
}

Expand Down Expand Up @@ -79,7 +67,7 @@ export class GlobCopyWebpackPlugin {

compiler.plugin('emit', (compilation: any, cb: any) => {
// Create an array of promises for each pattern glob
const globs = patterns.map((pattern: Pattern) => new Promise((resolve, reject) =>
const globs = patterns.map((pattern: AssetPattern) => new Promise((resolve, reject) =>
// Individual patterns can override cwd
globPromise(pattern.glob, Object.assign({}, globOptions, { cwd: pattern.input }))
// Map the results onto an Asset
Expand Down
13 changes: 3 additions & 10 deletions packages/@angular/cli/plugins/karma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import * as glob from 'glob';
import * as webpack from 'webpack';
const webpackDevMiddleware = require('webpack-dev-middleware');

import { Pattern } from './glob-copy-webpack-plugin';
import { AssetPattern } from '../models/webpack-configs/utils';
import { isDirectory } from '../utilities/is-directory';
import { WebpackTestConfig, WebpackTestOptions } from '../models/webpack-test-config';
import { KarmaWebpackThrowError } from './karma-webpack-throw-error';

Expand All @@ -22,14 +23,6 @@ const getAppFromConfig = require('../utilities/app-utils').getAppFromConfig;
let blocked: any[] = [];
let isBlocked = false;

function isDirectory(path: string) {
try {
return fs.statSync(path).isDirectory();
} catch (_) {
return false;
}
}

// Add files to the Karma files array.
function addKarmaFiles(files: any[], newFiles: any[], prepend = false) {
const defaults = {
Expand Down Expand Up @@ -82,7 +75,7 @@ const init: any = (config: any, emitter: any, customFileHandlers: any) => {
// Add assets. This logic is mimics the one present in GlobCopyWebpackPlugin.
if (appConfig.assets) {
config.proxies = config.proxies || {};
appConfig.assets.forEach((pattern: Pattern) => {
appConfig.assets.forEach((pattern: AssetPattern) => {
// Convert all string patterns to Pattern type.
pattern = typeof pattern === 'string' ? { glob: pattern } : pattern;
// Add defaults.
Expand Down
10 changes: 9 additions & 1 deletion packages/@angular/cli/tasks/eject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class JsonWebpackSerializer {
private _pluginsReplacer(plugins: any[]) {
return plugins.map(plugin => {
let args = plugin.options || undefined;
const serializer = (args: any) => JSON.stringify(args, (k, v) => this._replacer(k, v), 2);

switch (plugin.constructor) {
case ProgressPlugin:
Expand Down Expand Up @@ -231,11 +232,17 @@ class JsonWebpackSerializer {
default:
if (plugin.constructor.name == 'AngularServiceWorkerPlugin') {
this._addImport('@angular/service-worker/build/webpack', plugin.constructor.name);
} else if (plugin['copyWebpackPluginPatterns']) {
// CopyWebpackPlugin doesn't have a constructor nor save args.
this.variableImports['copy-webpack-plugin'] = 'CopyWebpackPlugin';
const patternsSerialized = serializer(plugin['copyWebpackPluginPatterns']);
const optionsSerialized = serializer(plugin['copyWebpackPluginOptions']) || 'undefined';
return `\uFF02CopyWebpackPlugin(${patternsSerialized}, ${optionsSerialized})\uFF02`;
}
break;
}

const argsSerialized = JSON.stringify(args, (k, v) => this._replacer(k, v), 2) || '';
const argsSerialized = serializer(args) || '';
return `\uFF02${plugin.constructor.name}(${argsSerialized})\uFF02`;
});
}
Expand Down Expand Up @@ -538,6 +545,7 @@ export default Task.extend({
'url-loader',
'circular-dependency-plugin',
'webpack-concat-plugin',
'copy-webpack-plugin',
].forEach((packageName: string) => {
packageJson['devDependencies'][packageName] = ourPackageJson['dependencies'][packageName];
});
Expand Down
9 changes: 9 additions & 0 deletions packages/@angular/cli/utilities/is-directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as fs from 'fs';

export function isDirectory(path: string) {
try {
return fs.statSync(path).isDirectory();
} catch (_) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If TS is upgraded to 2.5.2 for CLI build purposes, the empty catch variable can be removed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do that project wide when updating.

return false;
}
}