Skip to content

Commit 1655e51

Browse files
authored
feat(@angular/cli): hash loaded media by default (#4878)
Currently dev builds use `--output-hashing=none` by default. This can cause image resources to be overwritten in dev if they have the same same. This wasn't much of a problem before when only images in global CSS would be treated as resources, but now component css also does that. Production builds are unaffected since they already use `--output-hashing=all`. BREAKING CHANGE: dev builds will hash relative resources from CSS (images, etc).
1 parent e4fc294 commit 1655e51

File tree

5 files changed

+31
-23
lines changed

5 files changed

+31
-23
lines changed

packages/@angular/cli/models/webpack-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class NgCliWebpackConfig {
7878
const targetDefaults: any = {
7979
development: {
8080
environment: 'dev',
81-
outputHashing: 'none',
81+
outputHashing: 'media',
8282
sourcemap: true,
8383
extractCss: false
8484
},

tests/e2e/tests/build/css-urls.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import * as fs from 'fs';
12
import { ng } from '../../utils/process';
23
import {
34
expectFileToMatch,
45
expectFileToExist,
6+
expectFileMatchToExist,
57
writeMultipleFiles
68
} from '../../utils/fs';
79
import { expectToFail } from '../../utils/utils';
@@ -33,24 +35,27 @@ export default function () {
3335
.then(() => ng('build', '--extract-css', '--aot'))
3436
// Check paths are correctly generated.
3537
.then(() => expectFileToMatch('dist/styles.bundle.css',
36-
`url\('\/assets\/global-img-absolute\.svg'\)`))
37-
.then(() => expectFileToMatch('dist/styles.bundle.css', 'url\(global-img-relative.svg\)'))
38+
/url\('\/assets\/global-img-absolute\.svg'\)/))
39+
.then(() => expectFileToMatch('dist/styles.bundle.css',
40+
/url\(global-img-relative\.[0-9a-f]{20}\.svg\)/))
41+
.then(() => expectFileToMatch('dist/main.bundle.js',
42+
/url\(\\'\/assets\/component-img-absolute\.svg\\'\)/))
3843
.then(() => expectFileToMatch('dist/main.bundle.js',
39-
`url\(\\'\/assets\/component-img-absolute\.svg\\'\)`))
40-
.then(() => expectFileToMatch('dist/main.bundle.js', 'url\(component-img-relative\.svg\)'))
44+
/url\(component-img-relative\.[0-9a-f]{20}\.svg\)/))
4145
// Check files are correctly created.
4246
.then(() => expectToFail(() => expectFileToExist('dist/global-img-absolute.svg')))
43-
.then(() => expectFileToExist('dist/global-img-relative.svg'))
4447
.then(() => expectToFail(() => expectFileToExist('dist/component-img-absolute.svg')))
45-
.then(() => expectFileToExist('dist/component-img-relative.svg'))
48+
.then(() => expectFileMatchToExist('./dist', /global-img-relative\.[0-9a-f]{20}\.svg/))
49+
.then(() => expectFileMatchToExist('./dist', /component-img-relative\.[0-9a-f]{20}\.svg/))
4650
// Also check with base-href and deploy-url flags.
4751
.then(() => ng('build', '--base-href=/base/', '--deploy-url=deploy/',
4852
'--extract-css', '--aot'))
4953
.then(() => expectFileToMatch('dist/styles.bundle.css',
50-
`url\('\/base\/deploy\/assets\/global-img-absolute\.svg'\)`))
51-
.then(() => expectFileToMatch('dist/styles.bundle.css', 'url\(global-img-relative.svg\)'))
54+
/url\('\/base\/deploy\/assets\/global-img-absolute\.svg'\)/))
55+
.then(() => expectFileToMatch('dist/styles.bundle.css',
56+
/url\(global-img-relative\.[0-9a-f]{20}\.svg\)/))
5257
.then(() => expectFileToMatch('dist/main.bundle.js',
53-
`url\(\\'\/base\/deploy\/assets\/component-img-absolute\.svg\\'\)`))
58+
/url\(\\'\/base\/deploy\/assets\/component-img-absolute\.svg\\'\)/))
5459
.then(() => expectFileToMatch('dist/main.bundle.js',
55-
'url\(deploy/component-img-relative\.svg\)'));
60+
/url\(deploy\/component-img-relative\.[0-9a-f]{20}\.svg\)/));
5661
}

tests/e2e/tests/build/deploy-url.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default function () {
1616
.then(() => ng('build', '--deploy-url=deployUrl/', '--extract-css'))
1717
.then(() => expectFileToMatch('dist/index.html', 'deployUrl/main.bundle.js'))
1818
// verify --deploy-url isn't applied to extracted css urls
19-
.then(() => expectFileToMatch('dist/styles.bundle.css', 'url\(more.svg\)'))
19+
.then(() => expectFileToMatch('dist/styles.bundle.css', /url\(more\.[0-9a-f]{20}\.svg\)/))
2020
// verify option also works in config
2121
.then(() => updateJsonFile('.angular-cli.json', configJson => {
2222
const app = configJson['apps'][0];
@@ -27,5 +27,5 @@ export default function () {
2727
// verify --deploy-url is applied to non-extracted css urls
2828
.then(() => ng('build', '--deploy-url=deployUrl/', '--extract-css=false'))
2929
.then(() => expectFileToMatch('dist/styles.bundle.js',
30-
'__webpack_require__.p \+ \"more.svg\"'));
30+
/__webpack_require__.p \+ \"more\.[0-9a-f]{20}\.svg\"/));
3131
}

tests/e2e/tests/build/output-hashing.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
import {stripIndents} from 'common-tags';
2-
import * as fs from 'fs';
32
import {ng} from '../../utils/process';
4-
import { writeMultipleFiles, expectFileToMatch } from '../../utils/fs';
3+
import { writeMultipleFiles, expectFileToMatch, expectFileMatchToExist } from '../../utils/fs';
54

65
function verifyMedia(css: RegExp, content: RegExp) {
7-
return new Promise((resolve, reject) => {
8-
const [fileName] = fs.readdirSync('./dist').filter(name => name.match(css));
9-
if (!fileName) {
10-
reject(new Error(`File ${fileName} was expected to exist but not found...`));
11-
}
12-
resolve(fileName);
13-
})
14-
.then(fileName => expectFileToMatch(`dist/${fileName}`, content));
6+
return expectFileMatchToExist('./dist', css)
7+
.then(fileName => expectFileToMatch(`dist/${fileName}`, content));
158
}
169

1710
export default function() {

tests/e2e/utils/fs.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ export function prependToFile(filePath: string, text: string, options?: any) {
120120
}
121121

122122

123+
export function expectFileMatchToExist(dir: string, regex: RegExp) {
124+
return new Promise((resolve, reject) => {
125+
const [fileName] = fs.readdirSync(dir).filter(name => name.match(regex));
126+
if (!fileName) {
127+
reject(new Error(`File ${regex} was expected to exist but not found...`));
128+
}
129+
resolve(fileName);
130+
});
131+
}
132+
123133
export function expectFileToExist(fileName: string) {
124134
return new Promise((resolve, reject) => {
125135
fs.exists(fileName, (exist) => {

0 commit comments

Comments
 (0)