Skip to content

Commit 6530aa1

Browse files
committedMar 25, 2024·
feat(@schematics/angular): replace assets with public directory
The `assets` directory is confusing for the users and commonly users place "assets" which are not meant to be copied but instead processed by the build system. This causes some files both bundled and copied. With this change we rename the `assets` directory to `public` and also move the `favicon.ico` inside this newly created directory.
1 parent 9d3aa46 commit 6530aa1

File tree

32 files changed

+102
-129
lines changed

32 files changed

+102
-129
lines changed
 

‎goldens/public-api/angular_devkit/build_angular/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export interface AssetPatternObject {
7979
glob: string;
8080
ignore?: string[];
8181
input: string;
82-
output: string;
82+
output?: string;
8383
}
8484

8585
// @public

‎packages/angular/pwa/pwa/index.ts

+23-19
Original file line numberDiff line numberDiff line change
@@ -104,23 +104,6 @@ export default function (options: PwaOptions): Rule {
104104
}
105105
}
106106

107-
// Add manifest to asset configuration
108-
const assetEntry = posix.join(
109-
project.sourceRoot ?? posix.join(project.root, 'src'),
110-
'manifest.webmanifest',
111-
);
112-
for (const target of [...buildTargets, ...testTargets]) {
113-
if (target.options) {
114-
if (Array.isArray(target.options.assets)) {
115-
target.options.assets.push(assetEntry);
116-
} else {
117-
target.options.assets = [assetEntry];
118-
}
119-
} else {
120-
target.options = { assets: [assetEntry] };
121-
}
122-
}
123-
124107
// Find all index.html files in build targets
125108
const indexFiles = new Set<string>();
126109
for (const target of buildTargets) {
@@ -146,11 +129,32 @@ export default function (options: PwaOptions): Rule {
146129
const { title, ...swOptions } = options;
147130

148131
await writeWorkspace(host, workspace);
132+
let assetsDir = posix.join(sourcePath, 'assets');
133+
134+
if (host.exists(assetsDir)) {
135+
// Add manifest to asset configuration
136+
const assetEntry = posix.join(
137+
project.sourceRoot ?? posix.join(project.root, 'src'),
138+
'manifest.webmanifest',
139+
);
140+
for (const target of [...buildTargets, ...testTargets]) {
141+
if (target.options) {
142+
if (Array.isArray(target.options.assets)) {
143+
target.options.assets.push(assetEntry);
144+
} else {
145+
target.options.assets = [assetEntry];
146+
}
147+
} else {
148+
target.options = { assets: [assetEntry] };
149+
}
150+
}
151+
} else {
152+
assetsDir = posix.join(project.root, 'public');
153+
}
149154

150155
return chain([
151156
externalSchematic('@schematics/angular', 'service-worker', swOptions),
152-
mergeWith(apply(url('./files/root'), [template({ ...options }), move(sourcePath)])),
153-
mergeWith(apply(url('./files/assets'), [move(posix.join(sourcePath, 'assets'))])),
157+
mergeWith(apply(url('./files/assets'), [template({ ...options }), move(assetsDir)])),
154158
...[...indexFiles].map((path) => updateIndexFile(path)),
155159
]);
156160
};

‎packages/angular/pwa/pwa/index_spec.ts

+4-15
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe('PWA Schematic', () => {
5454

5555
it('should create icon files', async () => {
5656
const dimensions = [72, 96, 128, 144, 152, 192, 384, 512];
57-
const iconPath = '/projects/bar/src/assets/icons/icon-';
57+
const iconPath = '/projects/bar/public/icons/icon-';
5858
const tree = await schematicRunner.runSchematic('ng-add', defaultOptions, appTree);
5959

6060
dimensions.forEach((d) => {
@@ -74,13 +74,13 @@ describe('PWA Schematic', () => {
7474

7575
it('should create a manifest file', async () => {
7676
const tree = await schematicRunner.runSchematic('ng-add', defaultOptions, appTree);
77-
expect(tree.exists('/projects/bar/src/manifest.webmanifest')).toBeTrue();
77+
expect(tree.exists('/projects/bar/public/manifest.webmanifest')).toBeTrue();
7878
});
7979

8080
it('should set the name & short_name in the manifest file', async () => {
8181
const tree = await schematicRunner.runSchematic('ng-add', defaultOptions, appTree);
8282

83-
const manifestText = tree.readContent('/projects/bar/src/manifest.webmanifest');
83+
const manifestText = tree.readContent('/projects/bar/public/manifest.webmanifest');
8484
const manifest = JSON.parse(manifestText);
8585

8686
expect(manifest.name).toEqual(defaultOptions.title);
@@ -91,7 +91,7 @@ describe('PWA Schematic', () => {
9191
const options = { ...defaultOptions, title: undefined };
9292
const tree = await schematicRunner.runSchematic('ng-add', options, appTree);
9393

94-
const manifestText = tree.readContent('/projects/bar/src/manifest.webmanifest');
94+
const manifestText = tree.readContent('/projects/bar/public/manifest.webmanifest');
9595
const manifest = JSON.parse(manifestText);
9696

9797
expect(manifest.name).toEqual(defaultOptions.project);
@@ -125,17 +125,6 @@ describe('PWA Schematic', () => {
125125
expect(content).toMatch(/<noscript>NO JAVASCRIPT<\/noscript>/);
126126
});
127127

128-
it('should update the build and test assets configuration', async () => {
129-
const tree = await schematicRunner.runSchematic('ng-add', defaultOptions, appTree);
130-
const configText = tree.readContent('/angular.json');
131-
const config = JSON.parse(configText);
132-
const targets = config.projects.bar.architect;
133-
134-
['build', 'test'].forEach((target) => {
135-
expect(targets[target].options.assets).toContain('projects/bar/src/manifest.webmanifest');
136-
});
137-
});
138-
139128
describe('Legacy browser builder', () => {
140129
function convertBuilderToLegacyBrowser(): void {
141130
const config = JSON.parse(appTree.readContent('/angular.json'));

‎packages/angular_devkit/build_angular/src/builders/application/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -560,11 +560,12 @@
560560
},
561561
"output": {
562562
"type": "string",
563+
"default": "",
563564
"description": "Absolute path within the output."
564565
}
565566
},
566567
"additionalProperties": false,
567-
"required": ["glob", "input", "output"]
568+
"required": ["glob", "input"]
568569
},
569570
{
570571
"type": "string"

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,12 @@
466466
},
467467
"output": {
468468
"type": "string",
469+
"default": "",
469470
"description": "Absolute path within the output."
470471
}
471472
},
472473
"additionalProperties": false,
473-
"required": ["glob", "input", "output"]
474+
"required": ["glob", "input"]
474475
},
475476
{
476477
"type": "string"

‎packages/angular_devkit/build_angular/src/builders/browser/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,12 @@
454454
},
455455
"output": {
456456
"type": "string",
457+
"default": "",
457458
"description": "Absolute path within the output."
458459
}
459460
},
460461
"additionalProperties": false,
461-
"required": ["glob", "input", "output"]
462+
"required": ["glob", "input"]
462463
},
463464
{
464465
"type": "string"

‎packages/angular_devkit/build_angular/src/builders/karma/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
},
291291
"output": {
292292
"type": "string",
293+
"default": "",
293294
"description": "Absolute path within the output."
294295
},
295296
"ignore": {
@@ -301,7 +302,7 @@
301302
}
302303
},
303304
"additionalProperties": false,
304-
"required": ["glob", "input", "output"]
305+
"required": ["glob", "input"]
305306
},
306307
{
307308
"type": "string"

‎packages/angular_devkit/build_angular/src/builders/server/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,12 @@
251251
},
252252
"output": {
253253
"type": "string",
254+
"default": "",
254255
"description": "Absolute path within the output."
255256
}
256257
},
257258
"additionalProperties": false,
258-
"required": ["glob", "input", "output"]
259+
"required": ["glob", "input"]
259260
},
260261
{
261262
"type": "string"

‎packages/angular_devkit/build_angular/src/builders/web-test-runner/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
},
270270
"output": {
271271
"type": "string",
272+
"default": "",
272273
"description": "Absolute path within the output."
273274
},
274275
"ignore": {
@@ -280,7 +281,7 @@
280281
}
281282
},
282283
"additionalProperties": false,
283-
"required": ["glob", "input", "output"]
284+
"required": ["glob", "input"]
284285
},
285286
{
286287
"type": "string"

‎packages/angular_devkit/build_angular/src/tools/webpack/utils/helpers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export function assetPatterns(root: string, assets: AssetPatternClass[]) {
231231
return assets.map((asset: AssetPatternClass, index: number): ObjectPattern => {
232232
// Resolve input paths relative to workspace root and add slash at the end.
233233
// eslint-disable-next-line prefer-const
234-
let { input, output, ignore = [], glob } = asset;
234+
let { input, output = '', ignore = [], glob } = asset;
235235
input = path.resolve(root, input).replace(/\\/g, '/');
236236
input = input.endsWith('/') ? input : input + '/';
237237
output = output.endsWith('/') ? output : output + '/';

‎packages/angular_devkit/build_angular/src/utils/normalize-asset-patterns.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import { statSync } from 'fs';
10+
import assert from 'node:assert';
1011
import * as path from 'path';
1112
import { AssetPattern, AssetPatternClass } from '../builders/browser/schema';
1213

@@ -21,7 +22,7 @@ export function normalizeAssetPatterns(
2122
workspaceRoot: string,
2223
projectRoot: string,
2324
projectSourceRoot: string | undefined,
24-
): AssetPatternClass[] {
25+
): (AssetPatternClass & { output: string })[] {
2526
if (assetPatterns.length === 0) {
2627
return [];
2728
}
@@ -67,13 +68,15 @@ export function normalizeAssetPatterns(
6768

6869
assetPattern = { glob, input, output };
6970
} else {
70-
assetPattern.output = path.join('.', assetPattern.output);
71+
assetPattern.output = path.join('.', assetPattern.output ?? '');
7172
}
7273

74+
assert(assetPattern.output !== undefined);
75+
7376
if (assetPattern.output.startsWith('..')) {
7477
throw new Error('An asset cannot be written to a location outside of the output path.');
7578
}
7679

77-
return assetPattern;
80+
return assetPattern as AssetPatternClass & { output: string };
7881
});
7982
}

‎packages/schematics/angular/application/files/common-files/src/assets/.gitkeep.template

Whitespace-only changes.

‎packages/schematics/angular/application/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ function addAppToWorkspaceFile(
242242
polyfills: ['zone.js'],
243243
tsConfig: `${projectRoot}tsconfig.app.json`,
244244
inlineStyleLanguage,
245-
assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
245+
assets: [{ 'glob': '**/*', 'input': 'public' }],
246246
styles: [`${sourceRoot}/styles.${options.style}`],
247247
scripts: [],
248248
},
@@ -285,7 +285,7 @@ function addAppToWorkspaceFile(
285285
polyfills: ['zone.js', 'zone.js/testing'],
286286
tsConfig: `${projectRoot}tsconfig.spec.json`,
287287
inlineStyleLanguage,
288-
assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
288+
assets: [{ 'glob': '**/*', 'input': 'public' }],
289289
styles: [`${sourceRoot}/styles.${options.style}`],
290290
scripts: [],
291291
},

‎packages/schematics/angular/application/index_spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('Application Schematic', () => {
5050
jasmine.arrayContaining([
5151
'/projects/foo/tsconfig.app.json',
5252
'/projects/foo/tsconfig.spec.json',
53-
'/projects/foo/src/favicon.ico',
53+
'/projects/foo/public/favicon.ico',
5454
'/projects/foo/src/index.html',
5555
'/projects/foo/src/main.ts',
5656
'/projects/foo/src/styles.css',
@@ -263,7 +263,7 @@ describe('Application Schematic', () => {
263263
jasmine.arrayContaining([
264264
'/tsconfig.app.json',
265265
'/tsconfig.spec.json',
266-
'/src/favicon.ico',
266+
'/public/favicon.ico',
267267
'/src/index.html',
268268
'/src/main.ts',
269269
'/src/styles.css',
@@ -448,7 +448,7 @@ describe('Application Schematic', () => {
448448
expect(files).toEqual(
449449
jasmine.arrayContaining([
450450
'/projects/foo/tsconfig.app.json',
451-
'/projects/foo/src/favicon.ico',
451+
'/projects/foo/public/favicon.ico',
452452
'/projects/foo/src/index.html',
453453
'/projects/foo/src/main.ts',
454454
'/projects/foo/src/styles.css',
@@ -473,7 +473,7 @@ describe('Application Schematic', () => {
473473
expect(files).toEqual(
474474
jasmine.arrayContaining([
475475
'/projects/foo/tsconfig.app.json',
476-
'/projects/foo/src/favicon.ico',
476+
'/projects/foo/public/favicon.ico',
477477
'/projects/foo/src/index.html',
478478
'/projects/foo/src/main.ts',
479479
'/projects/foo/src/styles.css',
@@ -499,7 +499,7 @@ describe('Application Schematic', () => {
499499
expect(files).toEqual(
500500
jasmine.arrayContaining([
501501
'/projects/foo/tsconfig.app.json',
502-
'/projects/foo/src/favicon.ico',
502+
'/projects/foo/public/favicon.ico',
503503
'/projects/foo/src/index.html',
504504
'/projects/foo/src/main.ts',
505505
'/projects/foo/src/styles.css',
@@ -519,7 +519,7 @@ describe('Application Schematic', () => {
519519
jasmine.arrayContaining([
520520
'/projects/foo/tsconfig.app.json',
521521
'/projects/foo/tsconfig.spec.json',
522-
'/projects/foo/src/favicon.ico',
522+
'/projects/foo/public/favicon.ico',
523523
'/projects/foo/src/index.html',
524524
'/projects/foo/src/main.ts',
525525
'/projects/foo/src/styles.css',

‎packages/schematics/angular/service-worker/files/ngsw-config.json.template

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"updateMode": "prefetch",
2222
"resources": {
2323
"files": [
24-
"/assets/**",
25-
"<%= resourcesOutputPath %>/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
24+
"/**/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
2625
]
2726
}
2827
}

‎packages/schematics/angular/service-worker/index.ts

-6
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,10 @@ export default function (options: ServiceWorkerOptions): Rule {
120120

121121
const buildOptions = buildTarget.options as Record<string, string | boolean>;
122122
let browserEntryPoint: string | undefined;
123-
let resourcesOutputPath = '';
124123
const ngswConfigPath = join(normalize(project.root), 'ngsw-config.json');
125124

126125
if (buildTarget.builder === Builders.Application) {
127126
browserEntryPoint = buildOptions.browser as string;
128-
resourcesOutputPath = '/media';
129127
const productionConf = buildTarget.configurations?.production;
130128
if (productionConf) {
131129
productionConf.serviceWorker = ngswConfigPath;
@@ -134,9 +132,6 @@ export default function (options: ServiceWorkerOptions): Rule {
134132
browserEntryPoint = buildOptions.main as string;
135133
buildOptions.serviceWorker = true;
136134
buildOptions.ngswConfigPath = ngswConfigPath;
137-
if (buildOptions.resourcesOutputPath) {
138-
resourcesOutputPath = normalize(`/${buildOptions.resourcesOutputPath}`);
139-
}
140135
}
141136

142137
await writeWorkspace(host, workspace);
@@ -147,7 +142,6 @@ export default function (options: ServiceWorkerOptions): Rule {
147142
apply(url('./files'), [
148143
applyTemplates({
149144
...options,
150-
resourcesOutputPath,
151145
relativePathToWorkspaceRoot: relativePathToWorkspaceRoot(project.root),
152146
}),
153147
move(project.root),

‎packages/schematics/angular/service-worker/index_spec.ts

-21
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,6 @@ describe('Service Worker Schematic', () => {
107107
expect(configNotInRoot.$schema).toBe(`../../${pathToNgswConfigSchema}`);
108108
});
109109

110-
it('should add root assets RegExp', async () => {
111-
const tree = await schematicRunner.runSchematic('service-worker', defaultOptions, appTree);
112-
const pkgText = tree.readContent('/projects/bar/ngsw-config.json');
113-
const config = JSON.parse(pkgText);
114-
expect(config.assetGroups[1].resources.files).toContain(
115-
'/media/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)',
116-
);
117-
});
118-
119110
it('should generate ngsw-config.json in root when the application is at root level', async () => {
120111
const name = 'foo';
121112
const rootAppOptions: ApplicationOptions = {
@@ -228,18 +219,6 @@ describe('Service Worker Schematic', () => {
228219
convertBuilderToLegacyBrowser();
229220
});
230221

231-
it('should add resourcesOutputPath to root assets when specified', async () => {
232-
const config = JSON.parse(appTree.readContent('/angular.json'));
233-
config.projects.bar.architect.build.options.resourcesOutputPath = 'outDir';
234-
appTree.overwrite('/angular.json', JSON.stringify(config));
235-
const tree = await schematicRunner.runSchematic('service-worker', defaultOptions, appTree);
236-
const pkgText = tree.readContent('/projects/bar/ngsw-config.json');
237-
const ngswConfig = JSON.parse(pkgText);
238-
expect(ngswConfig.assetGroups[1].resources.files).toContain(
239-
'/outDir/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)',
240-
);
241-
});
242-
243222
it('should add `serviceWorker` option to build target', async () => {
244223
const tree = await schematicRunner.runSchematic('service-worker', defaultOptions, appTree);
245224
const configText = tree.readContent('/angular.json');

‎tests/legacy-cli/e2e/tests/build/assets.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ import { updateJsonFile } from '../../utils/project';
55
import { expectToFail } from '../../utils/utils';
66

77
export default async function () {
8-
await writeFile('src/assets/.file', '');
9-
await writeFile('src/assets/test.abc', 'hello world');
8+
await writeFile('public/.file', '');
9+
await writeFile('public/test.abc', 'hello world');
1010

1111
await ng('build', '--configuration=development');
1212

1313
await expectFileToExist('dist/test-project/browser/favicon.ico');
14-
await expectFileToExist('dist/test-project/browser/assets/.file');
15-
await expectFileToMatch('dist/test-project/browser/assets/test.abc', 'hello world');
16-
await expectToFail(() => expectFileToExist('dist/test-project/browser/assets/.gitkeep'));
14+
await expectFileToExist('dist/test-project/browser/.file');
15+
await expectFileToMatch('dist/test-project/browser/test.abc', 'hello world');
16+
await expectToFail(() => expectFileToExist('dist/test-project/browser/.gitkeep'));
1717

1818
// Ensure `followSymlinks` option follows symlinks
1919
await updateJsonFile('angular.json', (workspaceJson) => {
2020
const appArchitect = workspaceJson.projects['test-project'].architect;
2121
appArchitect['build'].options.assets = [
22-
{ glob: '**/*', input: 'src/assets', output: 'assets', followSymlinks: true },
22+
{ glob: '**/*', input: 'public', followSymlinks: true },
2323
];
2424
});
2525
fs.mkdirSync('dirToSymlink/subdir1', { recursive: true });
@@ -28,12 +28,12 @@ export default async function () {
2828
fs.writeFileSync('dirToSymlink/subdir1/b.txt', '');
2929
fs.writeFileSync('dirToSymlink/subdir2/c.txt', '');
3030
fs.writeFileSync('dirToSymlink/subdir2/subsubdir1/d.txt', '');
31-
fs.symlinkSync(process.cwd() + '/dirToSymlink', 'src/assets/symlinkDir');
31+
fs.symlinkSync(process.cwd() + '/dirToSymlink', 'public/symlinkDir');
3232

3333
await ng('build', '--configuration=development');
3434

35-
await expectFileToExist('dist/test-project/browser/assets/symlinkDir/a.txt');
36-
await expectFileToExist('dist/test-project/browser/assets/symlinkDir/subdir1/b.txt');
37-
await expectFileToExist('dist/test-project/browser/assets/symlinkDir/subdir2/c.txt');
38-
await expectFileToExist('dist/test-project/browser/assets/symlinkDir/subdir2/subsubdir1/d.txt');
35+
await expectFileToExist('dist/test-project/browser/symlinkDir/a.txt');
36+
await expectFileToExist('dist/test-project/browser/symlinkDir/subdir1/b.txt');
37+
await expectFileToExist('dist/test-project/browser/symlinkDir/subdir2/c.txt');
38+
await expectFileToExist('dist/test-project/browser/symlinkDir/subdir2/subsubdir1/d.txt');
3939
}

‎tests/legacy-cli/e2e/tests/build/css-urls.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
import { copyProjectAsset } from '../../utils/assets';
99
import { expectToFail } from '../../utils/utils';
1010
import { getGlobalVariable } from '../../utils/env';
11+
import { mkdir } from 'node:fs/promises';
1112

1213
const imgSvg = `
1314
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
@@ -22,6 +23,8 @@ export default async function () {
2223
? './dist/test-project/browser'
2324
: './dist/test-project/browser/media';
2425

26+
await mkdir('public/assets/', { recursive: true });
27+
2528
await Promise.resolve()
2629
// Verify absolute/relative paths in global/component css.
2730
.then(() =>
@@ -34,8 +37,8 @@ export default async function () {
3437
h3 { background: url('/assets/component-img-absolute.svg'); }
3538
h4 { background: url('../assets/component-img-relative.png'); }
3639
`,
37-
'src/assets/global-img-absolute.svg': imgSvg,
38-
'src/assets/component-img-absolute.svg': imgSvg,
40+
'public/assets/global-img-absolute.svg': imgSvg,
41+
'public/assets/component-img-absolute.svg': imgSvg,
3942
}),
4043
)
4144
.then(() => copyProjectAsset('images/spectrum.png', './src/assets/global-img-relative.png'))

‎tests/legacy-cli/e2e/tests/build/multiple-configs.ts

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export default async function () {
2424
sourceMap: true,
2525
outputHashing: 'none',
2626
vendorChunk: true,
27-
assets: ['src/favicon.ico', 'src/assets'],
2827
styles: ['src/styles.css'],
2928
scripts: [],
3029
budgets: [],

‎tests/legacy-cli/e2e/tests/build/prerender/http-requests-assets.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default async function () {
3939
};
4040
`,
4141
// Add asset
42-
'src/assets/media.json': JSON.stringify({ dataFromAssets: true }),
42+
'public/media.json': JSON.stringify({ dataFromAssets: true }),
4343
// Update component to do an HTTP call to asset.
4444
'src/app/app.component.ts': `
4545
import { Component, inject } from '@angular/core';
@@ -60,7 +60,7 @@ export default async function () {
6060
data: any;
6161
constructor() {
6262
const http = inject(HttpClient);
63-
http.get('/assets/media.json').subscribe((d) => {
63+
http.get('/media.json').subscribe((d) => {
6464
this.data = d;
6565
});
6666
}

‎tests/legacy-cli/e2e/tests/commands/add/add-pwa.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { join } from 'path';
21
import { getGlobalVariable } from '../../../utils/env';
32
import { expectFileToExist, readFile, rimraf } from '../../../utils/fs';
43
import { installWorkspacePackages } from '../../../utils/packages';
@@ -11,12 +10,10 @@ export default async function () {
1110
// forcibly remove in case another test doesn't clean itself up
1211
await rimraf('node_modules/@angular/pwa');
1312
await ng('add', '@angular/pwa', '--skip-confirmation');
14-
await expectFileToExist(join(process.cwd(), 'src/manifest.webmanifest'));
13+
await expectFileToExist('public/manifest.webmanifest');
1514

1615
// Angular PWA doesn't install as a dependency
17-
const { dependencies, devDependencies } = JSON.parse(
18-
await readFile(join(process.cwd(), 'package.json')),
19-
);
16+
const { dependencies, devDependencies } = JSON.parse(await readFile('package.json'));
2017
const hasPWADep = Object.keys({ ...dependencies, ...devDependencies }).some(
2118
(d) => d === '@angular/pwa',
2219
);

‎tests/legacy-cli/e2e/tests/commands/add/npm-env-vars.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ export default async function () {
1313
const command = ['add', '@angular/pwa', '--skip-confirmation'];
1414

1515
// Environment variables only
16-
await expectFileNotToExist('src/manifest.webmanifest');
16+
await expectFileNotToExist('public/manifest.webmanifest');
1717
setNpmEnvVarsForAuthentication();
1818
await ng(...command);
19-
await expectFileToExist('src/manifest.webmanifest');
19+
await expectFileToExist('public/manifest.webmanifest');
2020
await git('clean', '-dxf');
2121

2222
// Mix of config file and env vars works
23-
await expectFileNotToExist('src/manifest.webmanifest');
23+
await expectFileNotToExist('public/manifest.webmanifest');
2424
await createNpmConfigForAuthentication(false, true);
2525
await ng(...command);
26-
await expectFileToExist('src/manifest.webmanifest');
26+
await expectFileToExist('public/manifest.webmanifest');
2727

2828
await git('clean', '-dxf');
2929
await installWorkspacePackages();

‎tests/legacy-cli/e2e/tests/commands/add/registry-option.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ export default async function () {
1212
await expectToFail(() => ng('add', '@angular/pwa', '--skip-confirmation'));
1313

1414
await ng('add', `--registry=${testRegistry}`, '@angular/pwa', '--skip-confirmation');
15-
await expectFileToExist('src/manifest.webmanifest');
15+
await expectFileToExist('public/manifest.webmanifest');
1616
}

‎tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ export default async function () {
99
delete process.env['NPM_CONFIG_REGISTRY'];
1010

1111
const command = ['add', '@angular/pwa', '--skip-confirmation'];
12-
await expectFileNotToExist('src/manifest.webmanifest');
12+
await expectFileNotToExist('public/manifest.webmanifest');
1313

1414
// Works with unscoped registry authentication details
1515
await createNpmConfigForAuthentication(false);
1616
await ng(...command);
17-
await expectFileToExist('src/manifest.webmanifest');
17+
await expectFileToExist('public/manifest.webmanifest');
1818
await git('clean', '-dxf');
1919

2020
// Works with scoped registry authentication details
21-
await expectFileNotToExist('src/manifest.webmanifest');
21+
await expectFileNotToExist('public/manifest.webmanifest');
2222

2323
await createNpmConfigForAuthentication(true);
2424
await ng(...command);
25-
await expectFileToExist('src/manifest.webmanifest');
25+
await expectFileToExist('public/manifest.webmanifest');
2626

2727
// Invalid authentication token
2828
await createNpmConfigForAuthentication(false, true);

‎tests/legacy-cli/e2e/tests/commands/add/yarn-env-vars.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ export default async function () {
1515
const command = ['add', '@angular/pwa', '--skip-confirmation'];
1616

1717
// Environment variables only
18-
await expectFileNotToExist('src/manifest.webmanifest');
18+
await expectFileNotToExist('public/manifest.webmanifest');
1919
setNpmEnvVarsForAuthentication(false, true);
2020
await ng(...command);
21-
await expectFileToExist('src/manifest.webmanifest');
21+
await expectFileToExist('public/manifest.webmanifest');
2222
await git('clean', '-dxf');
2323

2424
// Mix of config file and env vars works
25-
await expectFileNotToExist('src/manifest.webmanifest');
25+
await expectFileNotToExist('public/manifest.webmanifest');
2626
await createNpmConfigForAuthentication(false, true);
2727
await ng(...command);
28-
await expectFileToExist('src/manifest.webmanifest');
28+
await expectFileToExist('public/manifest.webmanifest');
2929
}

‎tests/legacy-cli/e2e/tests/commands/config/config-get.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ export default async function () {
2323
'config',
2424
`projects.test-project.architect.build.options.assets[0]`,
2525
);
26-
if (!stdout2.includes('src/favicon.ico')) {
27-
throw new Error(`Expected "src/favicon.ico", received "${JSON.stringify(stdout)}".`);
26+
if (!stdout2.includes('"input": "public"')) {
27+
throw new Error(`Expected "input": "public", received "${JSON.stringify(stdout)}".`);
2828
}
2929

3030
const { stdout: stdout3 } = await ng(
3131
'config',
3232
`projects["test-project"].architect.build.options.assets[0]`,
3333
);
3434

35-
if (!stdout3.includes('src/favicon.ico')) {
36-
throw new Error(`Expected "src/favicon.ico", received "${JSON.stringify(stdout)}".`);
35+
if (!stdout3.includes('"input": "public"')) {
36+
throw new Error(`Expected "input": "public", received "${JSON.stringify(stdout)}".`);
3737
}
3838

3939
// should print all config when no positional args are provided.

‎tests/legacy-cli/e2e/tests/commands/serve/assets.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ export default async function () {
88
const outsideDirectoryName = `../outside-${randomUUID()}`;
99

1010
await updateJsonFile('angular.json', (json) => {
11-
json.projects['test-project'].architect.build.options.assets = [
12-
'src/favicon.ico',
13-
'src/assets',
14-
// Ensure assets located outside the workspace root work with the dev server
15-
{ 'input': outsideDirectoryName, 'glob': '**/*', 'output': './outside' },
16-
];
11+
// Ensure assets located outside the workspace root work with the dev server
12+
json.projects['test-project'].architect.build.options.assets.push({
13+
'input': outsideDirectoryName,
14+
'glob': '**/*',
15+
'output': './outside',
16+
});
1717
});
1818

1919
await mkdir(outsideDirectoryName);

‎tests/legacy-cli/e2e/tests/commands/serve/ssr-http-requests-assets.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default async function () {
3434
};
3535
`,
3636
// Add asset
37-
'src/assets/media.json': JSON.stringify({ dataFromAssets: true }),
37+
'public/media.json': JSON.stringify({ dataFromAssets: true }),
3838
// Update component to do an HTTP call to asset.
3939
'src/app/app.component.ts': `
4040
import { Component, inject } from '@angular/core';
@@ -55,7 +55,7 @@ export default async function () {
5555
data: any;
5656
constructor() {
5757
const http = inject(HttpClient);
58-
http.get('/assets/media.json').toPromise().then((d) => {
58+
http.get('/media.json').toPromise().then((d) => {
5959
this.data = d;
6060
});
6161
}

‎tests/legacy-cli/e2e/utils/fs.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PathLike, promises as fs, constants } from 'fs';
1+
import { promises as fs, constants } from 'fs';
22
import { dirname, join } from 'path';
33

44
export function readFile(fileName: string): Promise<string> {

1 commit comments

Comments
 (1)

VBobCat commented on May 30, 2024

@VBobCat

Please update docs about ditching /assets;

Please sign in to comment.