Skip to content

feat(@angular-devkit/build-angular): move browser-sync as optional dependency #26587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 6, 2023
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
5 changes: 4 additions & 1 deletion packages/angular_devkit/build_angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"babel-loader": "9.1.3",
"babel-plugin-istanbul": "6.1.1",
"browserslist": "^4.21.5",
"browser-sync": "2.29.3",
"chokidar": "3.5.3",
"copy-webpack-plugin": "11.0.0",
"critters": "0.0.20",
Expand Down Expand Up @@ -80,6 +79,7 @@
"@angular/localize": "^17.0.0 || ^17.1.0-next.0",
"@angular/platform-server": "^17.0.0 || ^17.1.0-next.0",
"@angular/service-worker": "^17.0.0 || ^17.1.0-next.0",
"browser-sync": "^2.29.3",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"karma": "^6.3.0",
Expand All @@ -98,6 +98,9 @@
"@angular/service-worker": {
"optional": true
},
"browser-sync": {
"optional": true
},
"jest": {
"optional": true
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,18 @@ export function execute(
verbose: options.verbose,
} as json.JsonObject);

const bsInstance = require('browser-sync').create();
let browserSync: typeof import('browser-sync');
try {
browserSync = require('browser-sync');
} catch {
return of({
success: false,
error:
'"browser-sync" is not installed, most likely you need to run `npm install browser-sync --save-dev` in your project.',
});
}

const bsInstance = browserSync.create();

context.logger.error(tags.stripIndents`
****************************************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"factory": "./update-17/update-workspace-config",
"description": "Replace deprecated options in 'angular.json'."
},
"add-browser-sync-dependency": {
"version": "17.1.0",
"factory": "./update-17/add-browser-sync-dependency",
"description": "Add 'browser-sync' as dev dependency when '@angular-devkit/build-angular:ssr-dev-server' is used, as it is no longer a direct dependency of '@angular-devkit/build-angular'."
},
"use-application-builder": {
"version": "18.0.0",
"factory": "./update-17/use-application-builder",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { Rule } from '@angular-devkit/schematics';
import { DependencyType, addDependency } from '../../utility';
import { getPackageJsonDependency } from '../../utility/dependencies';
import { latestVersions } from '../../utility/latest-versions';
import { getWorkspace } from '../../utility/workspace';
import { Builders, ProjectType } from '../../utility/workspace-models';

const BROWSER_SYNC_VERSION = latestVersions['browser-sync'];

export default function (): Rule {
return async (tree) => {
if (getPackageJsonDependency(tree, 'browser-sync')?.version === BROWSER_SYNC_VERSION) {
return;
}

const workspace = await getWorkspace(tree);
for (const project of workspace.projects.values()) {
if (project.extensions.projectType !== ProjectType.Application) {
continue;
}

for (const target of project.targets.values()) {
if (target.builder === Builders.SsrDevServer) {
return addDependency('browser-sync', BROWSER_SYNC_VERSION, {
type: DependencyType.Dev,
});
}
}
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { EmptyTree } from '@angular-devkit/schematics';
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { latestVersions } from '../../utility/latest-versions';
import { Builders, ProjectType } from '../../utility/workspace-models';

describe(`Migration to add 'browser-sync' as a dev dependency`, () => {
const schematicName = 'add-browser-sync-dependency';
const schematicRunner = new SchematicTestRunner(
'migrations',
require.resolve('../migration-collection.json'),
);

let tree: UnitTestTree;
beforeEach(() => {
tree = new UnitTestTree(new EmptyTree());
tree.create(
'/package.json',
JSON.stringify(
{
devDependencies: {},
},
undefined,
2,
),
);
});

it(`should add 'browser-sync' as devDependencies when '@angular-devkit/build-angular:ssr-dev-server' is used`, async () => {
tree.create(
'/angular.json',
JSON.stringify(
{
version: 1,
projects: {
app: {
root: '',
projectType: ProjectType.Application,
prefix: 'app',
architect: {
'serve-ssr': {
builder: Builders.SsrDevServer,
options: {},
},
},
},
},
},
undefined,
2,
),
);

const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
const { devDependencies } = JSON.parse(newTree.readContent('/package.json'));
expect(devDependencies['browser-sync']).toBe(latestVersions['browser-sync']);
});

it(`should not add 'browser-sync' as devDependencies when '@angular-devkit/build-angular:ssr-dev-server' is not used`, async () => {
tree.create(
'/angular.json',
JSON.stringify(
{
version: 1,
projects: {
app: {
root: '',
projectType: ProjectType.Application,
prefix: 'app',
architect: {
'serve-ssr': {
builder: Builders.Browser,
options: {},
},
},
},
},
},
undefined,
2,
),
);
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
const { devDependencies } = JSON.parse(newTree.readContent('/package.json'));
expect(devDependencies['browser-sync']).toBeUndefined();
});
});
18 changes: 14 additions & 4 deletions packages/schematics/angular/ssr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ function updateWebpackBuilderServerTsConfigRule(options: SSROptions): Rule {
};
}

function addDependencies(): Rule {
return chain([
function addDependencies(isUsingApplicationBuilder: boolean): Rule {
const rules: Rule[] = [
addDependency('@angular/ssr', latestVersions.AngularSSR, {
type: DependencyType.Default,
}),
Expand All @@ -223,7 +223,17 @@ function addDependencies(): Rule {
addDependency('@types/express', latestVersions['@types/express'], {
type: DependencyType.Dev,
}),
]);
];

if (!isUsingApplicationBuilder) {
rules.push(
addDependency('browser-sync', latestVersions['browser-sync'], {
type: DependencyType.Dev,
}),
);
}

return chain(rules);
}

function addServerFile(options: ServerOptions, isStandalone: boolean): Rule {
Expand Down Expand Up @@ -288,7 +298,7 @@ export default function (options: SSROptions): Rule {
]),
addServerFile(options, isStandalone),
addScriptsRule(options, isUsingApplicationBuilder),
addDependencies(),
addDependencies(isUsingApplicationBuilder),
]);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0",
"browser-sync": "^2.29.3",
"express": "^4.18.2",
"jasmine-core": "~5.1.0",
"jasmine-spec-reporter": "~7.0.0",
Expand Down