Skip to content
This repository was archived by the owner on Jul 21, 2022. It is now read-only.

Commit a48bab9

Browse files
filipesilvaBrocco
authored andcommitted
feat(build): add support for assets array (angular#2570)
1 parent 0492db0 commit a48bab9

File tree

10 files changed

+87
-22
lines changed

10 files changed

+87
-22
lines changed

Diff for: package.json

-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
"chalk": "^1.1.3",
5757
"common-tags": "^1.3.1",
5858
"compression-webpack-plugin": "github:webpack/compression-webpack-plugin#7e55907cd54a2e91b96d25a660acc6a2a6453f54",
59-
"copy-webpack-plugin": "^3.0.1",
6059
"core-js": "^2.4.0",
6160
"css-loader": "^0.23.1",
6261
"denodeify": "^1.2.1",

Diff for: packages/angular-cli/blueprints/ng2/files/__path__/assets/.gitignore

Whitespace-only changes.

Diff for: packages/angular-cli/blueprints/ng2/files/angular-cli.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
{
88
"root": "<%= sourceDir %>",
99
"outDir": "dist",
10-
"assets": "assets",
10+
"assets": [
11+
"assets",
12+
"favicon.ico"
13+
],
1114
"index": "index.html",
1215
"main": "main.ts",
1316
"test": "test.ts",

Diff for: packages/angular-cli/lib/config/schema.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@
3232
"default": "dist/"
3333
},
3434
"assets": {
35-
"type": "string"
35+
"fixme": true,
36+
"type": "array",
37+
"items": {
38+
"type": "string"
39+
},
40+
"default": []
3641
},
3742
"index": {
3843
"type": "string",

Diff for: packages/angular-cli/models/json-schema/schema-tree.ts

+6
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ export abstract class NonLeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
128128
// Helper function to create a child based on its schema.
129129
protected _createChildProperty<T>(name: string, value: T, forward: SchemaTreeNode<T>,
130130
schema: Schema, define = true): SchemaTreeNode<T> {
131+
132+
// TODO: fix this
133+
if (schema['fixme'] && typeof value === 'string') {
134+
value = <T>(<any>[ value ]);
135+
}
136+
131137
const type = schema['type'];
132138
let Klass: any = null;
133139

Diff for: packages/angular-cli/models/webpack-build-common.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as webpack from 'webpack';
22
import * as path from 'path';
3+
import {GlobCopyWebpackPlugin} from '../plugins/glob-copy-webpack-plugin';
34
import {BaseHrefWebpackPlugin} from '@angular-cli/base-href-webpack';
45

5-
const CopyWebpackPlugin = require('copy-webpack-plugin');
66
const HtmlWebpackPlugin = require('html-webpack-plugin');
77

88

@@ -127,12 +127,10 @@ export function getWebpackCommonConfig(
127127
filename: 'inline.js',
128128
sourceMapFilename: 'inline.map'
129129
}),
130-
new CopyWebpackPlugin([{
131-
context: path.resolve(appRoot, appConfig.assets),
132-
from: { glob: '**/*', dot: true },
133-
ignore: [ '.gitkeep' ],
134-
to: path.resolve(projectRoot, appConfig.outDir, appConfig.assets)
135-
}])
130+
new GlobCopyWebpackPlugin({
131+
patterns: appConfig.assets,
132+
globOptions: {cwd: appRoot, dot: true, ignore: '**/.gitkeep'}
133+
})
136134
],
137135
node: {
138136
fs: 'empty',

Diff for: packages/angular-cli/models/webpack-build-mobile.ts

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
import * as path from 'path';
22
const OfflinePlugin = require('offline-plugin');
3-
const CopyWebpackPlugin = require('copy-webpack-plugin');
3+
import { GlobCopyWebpackPlugin } from '../plugins/glob-copy-webpack-plugin';
44
import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin';
55

66
export const getWebpackMobileConfigPartial = function (projectRoot: string, appConfig: any) {
77
// Hardcoded files and paths here should be part of appConfig when
88
// reworking the mobile app functionality
99
return {
1010
plugins: [
11-
new CopyWebpackPlugin([
12-
{
13-
from: path.resolve(projectRoot, appConfig.root, 'icons'),
14-
to: path.resolve(projectRoot, appConfig.outDir, 'icons')
15-
}, {
16-
from: path.resolve(projectRoot, appConfig.root, 'manifest.webapp'),
17-
to: path.resolve(projectRoot, appConfig.outDir)
18-
}
19-
]),
11+
new GlobCopyWebpackPlugin({
12+
patterns: [ 'icons', 'manifest.webapp'],
13+
globOptions: {cwd: appConfig.root, dot: true, ignore: '**/.gitkeep'}
14+
}),
2015
new PrerenderWebpackPlugin({
2116
templatePath: 'index.html',
2217
configPath: path.resolve(projectRoot, appConfig.root, 'main-app-shell.ts'),

Diff for: packages/angular-cli/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"chalk": "^1.1.3",
4040
"common-tags": "^1.3.1",
4141
"compression-webpack-plugin": "github:webpack/compression-webpack-plugin#7e55907cd54a2e91b96d25a660acc6a2a6453f54",
42-
"copy-webpack-plugin": "^3.0.1",
4342
"core-js": "^2.4.0",
4443
"css-loader": "^0.23.1",
4544
"denodeify": "^1.2.1",
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as fs from 'fs';
2+
import * as path from 'path';
3+
import * as glob from 'glob';
4+
import * as denodeify from 'denodeify';
5+
6+
const globPromise = <any>denodeify(glob);
7+
const statPromise = <any>denodeify(fs.stat);
8+
9+
export interface GlobCopyWebpackPluginOptions {
10+
patterns: string[];
11+
globOptions: any;
12+
}
13+
14+
export class GlobCopyWebpackPlugin {
15+
constructor(private options: GlobCopyWebpackPluginOptions) { }
16+
17+
apply(compiler: any): void {
18+
let { patterns, globOptions } = this.options;
19+
let context = globOptions.cwd || compiler.options.context;
20+
21+
// convert dir patterns to globs
22+
patterns = patterns.map(pattern => fs.statSync(path.resolve(context, pattern)).isDirectory()
23+
? pattern += '/**/*'
24+
: pattern
25+
);
26+
27+
// force nodir option, since we can't add dirs to assets
28+
globOptions.nodir = true;
29+
30+
compiler.plugin('emit', (compilation: any, cb: any) => {
31+
let globs = patterns.map(pattern => globPromise(pattern, globOptions));
32+
33+
let addAsset = (relPath: string) => compilation.assets[relPath]
34+
// don't re-add to assets
35+
? Promise.resolve()
36+
: statPromise(path.resolve(context, relPath))
37+
.then((stat: any) => compilation.assets[relPath] = {
38+
size: () => stat.size,
39+
source: () => fs.readFileSync(path.resolve(context, relPath))
40+
});
41+
42+
Promise.all(globs)
43+
// flatten results
44+
.then(globResults => [].concat.apply([], globResults))
45+
// add each file to compilation assets
46+
.then(relPaths => relPaths.forEach((relPath: string) => addAsset(relPath)))
47+
.catch((err) => compilation.errors.push(err))
48+
.then(cb);
49+
});
50+
}
51+
}

Diff for: tests/e2e/tests/misc/assets.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
import {writeFile, expectFileToExist, expectFileToMatch} from '../../utils/fs';
22
import {ng} from '../../utils/process';
3+
import {updateJsonFile} from '../../utils/project';
34
import {expectToFail} from '../../utils/utils';
45

56

67
export default function() {
78
return writeFile('src/assets/.file', '')
89
.then(() => writeFile('src/assets/test.abc', 'hello world'))
910
.then(() => ng('build'))
11+
.then(() => expectFileToExist('dist/favicon.ico'))
1012
.then(() => expectFileToExist('dist/assets/.file'))
1113
.then(() => expectFileToMatch('dist/assets/test.abc', 'hello world'))
12-
.then(() => expectToFail(() => expectFileToExist('dist/assets/.gitkeep')));
14+
.then(() => expectToFail(() => expectFileToExist('dist/assets/.gitkeep')))
15+
// doesn't break beta.16 projects
16+
.then(() => updateJsonFile('angular-cli.json', configJson => {
17+
const app = configJson['apps'][0];
18+
app['assets'] = 'assets';
19+
}))
20+
.then(() => expectFileToExist('dist/assets/.file'))
21+
.then(() => expectFileToMatch('dist/assets/test.abc', 'hello world'));
1322
}

0 commit comments

Comments
 (0)