Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.
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
2 changes: 2 additions & 0 deletions modules/builders/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ ts_library(
"@npm//@angular-devkit/architect",
"@npm//@angular-devkit/core",
"@npm//@types/browser-sync",
"@npm//@types/http-proxy-middleware",
"@npm//browser-sync",
"@npm//http-proxy-middleware",
"@npm//rxjs",
"@npm//tree-kill",
],
Expand Down
1 change: 1 addition & 0 deletions modules/builders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@angular-devkit/architect": "DEVKIT_ARCHITECT_VERSION",
"@angular-devkit/core": "DEVKIT_CORE_VERSION",
"browser-sync": "^2.26.7",
"http-proxy-middleware": "^0.20.0",
"rxjs": "RXJS_VERSION",
"tree-kill": "^1.2.1"
},
Expand Down
92 changes: 69 additions & 23 deletions modules/builders/src/ssr-dev-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import {
} from 'rxjs/operators';
import * as browserSync from 'browser-sync';
import { join } from 'path';
import * as url from 'url';
import * as proxy from 'http-proxy-middleware';

import { getAvailablePort, spawnAsObservable, waitUntilServerIsListening } from './utils';

Expand Down Expand Up @@ -198,31 +200,75 @@ async function initBrowserSync(
return browserSyncInstance;
}

const { port, open, host } = options;
const bsPort = port || await getAvailablePort();
const { port: browserSyncPort, open, host, publicHost } = options;
const bsPort = browserSyncPort || await getAvailablePort();
const bsOptions: browserSync.Options = {
proxy: {
target: `localhost:${nodeServerPort}`,
proxyRes: [
proxyRes => {
if ('headers' in proxyRes) {
proxyRes.headers['cache-control'] = undefined;
}
},
]
},
host,
port: bsPort,
ui: false,
server: false,
notify: false,
ghostMode: false,
logLevel: 'silent',
open,
// Remove leading slash
scriptPath: path => path.substring(1),
};

const publicHostNormalized = publicHost && publicHost.endsWith('/')
? publicHost.substring(0, publicHost.length - 1)
: publicHost;

if (publicHostNormalized) {
const { protocol, hostname, port, pathname } = url.parse(publicHostNormalized);
const defaultSocketIoPath = '/browser-sync/socket.io';
const defaultNamespace = '/browser-sync';
const hasPathname = !!(pathname && pathname !== '/');
const namespace = hasPathname ? pathname + defaultNamespace : defaultNamespace;
const path = hasPathname ? pathname + defaultSocketIoPath : defaultSocketIoPath;

bsOptions.socket = {
namespace,
path,
domain: url.format({
protocol,
hostname,
port,
}),
};

// When having a pathname we also need to create a reverse proxy because socket.io
// will be listening on: 'http://localhost:4200/ssr/browser-sync/socket.io'
// However users will typically have a reverse proxy that will redirect all matching requests
// ex: http://testinghost.com/ssr -> http://localhost:4200 which will result in a 404.
if (hasPathname) {
bsOptions.middleware = [
proxy(defaultSocketIoPath, {
target: url.format({
protocol: 'http',
hostname: host,
port: bsPort,
pathname: path,
}),
ws: true,
logLevel: 'silent',
}),
];
}
}

return new Promise((resolve, reject) => {
browserSyncInstance
.init({
proxy: {
target: `localhost:${nodeServerPort}`,
proxyRes: [
proxyRes => {
if ('headers' in proxyRes) {
proxyRes.headers['cache-control'] = undefined;
}
},
]
},
host,
port: bsPort,
ui: false,
server: false,
notify: false,
ghostMode: false,
logLevel: 'silent',
open,
}, (error, bs) => {
browserSyncInstance.init(bsOptions, (error, bs) => {
if (error) {
reject(error);
} else {
Expand Down
4 changes: 4 additions & 0 deletions modules/builders/src/ssr-dev-server/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
"default": 4200,
"description": "Port to start the development server at. Default is 4200. Pass 0 to get a dynamically assigned port."
},
"publicHost": {
"type": "string",
"description": "The URL that the browser client should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
},
"open": {
"type": "boolean",
"description": "Opens the url in default browser.",
Expand Down
6 changes: 6 additions & 0 deletions modules/builders/src/ssr-dev-server/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,10 @@ export interface Schema {

/** Opens the url in default browser. */
open?: boolean;

/**
* The URL that the browser client should use to connect to the development server.
* Use for a complex dev server setup, such as one with reverse proxies.
*/
publicHost?: string;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@
},
"devDependencies": {
"@angular-devkit/architect": "^0.900.0-rc.6",
"@angular/cli": "^9.0.0-rc.6",
"@angular-devkit/build-angular": "^0.900.0-rc.6",
"@angular-devkit/core": "^9.0.0-rc.6",
"@angular-devkit/schematics": "^9.0.0-rc.6",
"@angular/animations": "^9.0.0-rc.6",
"@angular/bazel": "^9.0.0-rc.6",
"@angular/cli": "^9.0.0-rc.6",
"@angular/common": "^9.0.0-rc.6",
"@angular/compiler": "^9.0.0-rc.6",
"@angular/compiler-cli": "^9.0.0-rc.6",
Expand All @@ -65,12 +65,14 @@
"@types/fs-extra": "^8.0.0",
"@types/hapi__hapi": "^18.2.5",
"@types/hapi__inert": "^5.2.0",
"@types/http-proxy-middleware": "^0.19.3",
"@types/jasmine": "^3.4.4",
"@types/node": "^12.11.1",
"@types/shelljs": "^0.8.6",
"browser-sync": "^2.26.7",
"domino": "^2.1.2",
"express": "^4.15.2",
"http-proxy-middleware": "^0.20.0",
"jasmine-core": "^3.0.0",
"karma": "^4.1.0",
"karma-chrome-launcher": "^3.0.0",
Expand Down
38 changes: 36 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,22 @@
dependencies:
"@types/node" "*"

"@types/http-proxy-middleware@^0.19.3":
version "0.19.3"
resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03"
integrity sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA==
dependencies:
"@types/connect" "*"
"@types/http-proxy" "*"
"@types/node" "*"

"@types/http-proxy@*":
version "1.17.2"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.2.tgz#3b7fb5365a00d47129967b0b2da51c2123692314"
integrity sha512-Qfb7batJJBlI8wcrd48vHpgsOOYzQQa+OZcaIz33jkJPe8A7KktAJFmRAiR42s5BfnErdlFnOyQucq2BKy/98g==
dependencies:
"@types/node" "*"

"@types/jasmine@^3.4.4":
version "3.5.0"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.0.tgz#2ad2006c8a937d20df20a8fee86071d0f730ef99"
Expand Down Expand Up @@ -2415,7 +2431,7 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"

braces@^3.0.2, braces@~3.0.2:
braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
Expand Down Expand Up @@ -4732,6 +4748,16 @@ http-proxy-middleware@0.19.1:
lodash "^4.17.11"
micromatch "^3.1.10"

http-proxy-middleware@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.20.0.tgz#5b128f7207985c4ea91b53fab8ad897a48c690d6"
integrity sha512-dNJAk71nEJhPiAczQH9hGvE/MT9kEs+zn2Dh+Hi94PGZe1GluQirC7mw5rdREUtWx6qGS1Gu0bZd4qEAg+REgw==
dependencies:
http-proxy "^1.17.0"
is-glob "^4.0.1"
lodash "^4.17.14"
micromatch "^4.0.2"

http-proxy@1.15.2:
version "1.15.2"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31"
Expand Down Expand Up @@ -6097,6 +6123,14 @@ micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"

micromatch@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
dependencies:
braces "^3.0.1"
picomatch "^2.0.5"

miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
Expand Down Expand Up @@ -7020,7 +7054,7 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=

picomatch@^2.0.4, picomatch@^2.0.7:
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7:
version "2.1.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5"
integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==
Expand Down