Skip to content

Commit ce8a938

Browse files
devversionjelbourn
authored andcommitted
build: switch to browser-sync (#14295)
Switches the gulp-connect dev-server to browser-sync
1 parent a8f1137 commit ce8a938

File tree

9 files changed

+430
-231
lines changed

9 files changed

+430
-231
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"@google-cloud/storage": "^1.1.1",
6161
"@octokit/rest": "^15.9.4",
6262
"@schematics/angular": "^7.0.6",
63+
"@types/browser-sync": "^0.0.42",
6364
"@types/chalk": "^0.4.31",
6465
"@types/fs-extra": "^4.0.3",
6566
"@types/glob": "^5.0.33",
@@ -76,6 +77,7 @@
7677
"@types/run-sequence": "^0.0.29",
7778
"autoprefixer": "^6.7.6",
7879
"axe-webdriverjs": "^1.1.1",
80+
"browser-sync": "^2.26.3",
7981
"chalk": "^1.1.3",
8082
"codelyzer": "^4.5.0",
8183
"conventional-changelog": "^3.0.5",
@@ -90,7 +92,6 @@
9092
"gulp-clean": "^0.3.2",
9193
"gulp-clean-css": "^3.3.1",
9294
"gulp-cli": "^2.0.1",
93-
"gulp-connect": "^5.0.0",
9495
"gulp-dom": "^0.9.17",
9596
"gulp-flatten": "^0.3.1",
9697
"gulp-highlight-files": "^0.0.5",

tools/gulp/tasks/development.ts

+13-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
copyFiles,
88
inlineResourcesForDirectory,
99
sequenceTask,
10-
watchFiles,
1110
} from 'material2-build-tools';
1211
import {
1312
cdkPackage,
@@ -17,6 +16,7 @@ import {
1716
momentAdapterPackage,
1817
examplesPackage,
1918
} from '../packages';
19+
import {watchFilesAndReload} from '../util/watch-files-reload';
2020

2121
// These imports don't have any typings provided.
2222
const firebaseTools = require('firebase-tools');
@@ -56,7 +56,7 @@ task(':build:devapp:assets', copyTask(assetsGlob, outDir));
5656
task(':build:devapp:scss', () => buildScssPipeline(appDir).pipe(dest(outDir)));
5757
task(':build:devapp:inline-resources', () => inlineResourcesForDirectory(outDir));
5858

59-
task(':serve:devapp', serverTask(outDir, true));
59+
task(':serve:devapp', serverTask(outDir));
6060

6161
task('build:devapp', sequenceTask(
6262
'cdk:build-no-bundles',
@@ -123,40 +123,41 @@ task('deploy:devapp', ['stage-deploy:devapp'], () => {
123123
*/
124124

125125
task(':watch:devapp', () => {
126-
watchFiles(join(appDir, '**/*.ts'), [':build:devapp:ts']);
127-
watchFiles(join(appDir, '**/*.scss'), [':watch:devapp:rebuild-scss']);
128-
watchFiles(join(appDir, '**/*.html'), [':watch:devapp:rebuild-html']);
126+
watchFilesAndReload(join(appDir, '**/*.ts'), [':build:devapp:ts']);
127+
watchFilesAndReload(join(appDir, '**/*.scss'), [':watch:devapp:rebuild-scss']);
128+
watchFilesAndReload(join(appDir, '**/*.html'), [':watch:devapp:rebuild-html']);
129129

130130
// Custom watchers for all packages that are used inside of the dev-app. This is necessary
131131
// because we only want to build the changed package (using the build-no-bundles task).
132132

133133
// CDK package watchers.
134-
watchFiles(join(cdkPackage.sourceDir, '**/*'), ['cdk:build-no-bundles']);
134+
watchFilesAndReload(join(cdkPackage.sourceDir, '**/*'), ['cdk:build-no-bundles']);
135135

136136
const materialCoreThemingGlob = join(materialPackage.sourceDir, '**/core/theming/**/*.scss');
137137

138138
// Material package watchers.
139-
watchFiles([
139+
watchFilesAndReload([
140140
join(materialPackage.sourceDir, '**/!(*-theme.scss)'), `!${materialCoreThemingGlob}`
141141
], ['material:build-no-bundles']);
142-
watchFiles([
142+
watchFilesAndReload([
143143
join(materialPackage.sourceDir, '**/*-theme.scss'), materialCoreThemingGlob
144144
], [':build:devapp:scss']);
145145

146146
// Moment adapter package watchers
147-
watchFiles(join(momentAdapterPackage.sourceDir, '**/*'),
147+
watchFilesAndReload(join(momentAdapterPackage.sourceDir, '**/*'),
148148
['material-moment-adapter:build-no-bundles']);
149149

150150
// Material experimental package watchers
151-
watchFiles(join(materialExperimentalPackage.sourceDir, '**/*'),
151+
watchFilesAndReload(join(materialExperimentalPackage.sourceDir, '**/*'),
152152
['material-experimental:build-no-bundles']);
153153

154154
// CDK experimental package watchers
155-
watchFiles(join(cdkExperimentalPackage.sourceDir, '**/*'),
155+
watchFilesAndReload(join(cdkExperimentalPackage.sourceDir, '**/*'),
156156
['cdk-experimental:build-no-bundles']);
157157

158158
// Example package watchers.
159-
watchFiles(join(examplesPackage.sourceDir, '**/*'), ['material-examples:build-no-bundles']);
159+
watchFilesAndReload(join(examplesPackage.sourceDir, '**/*'),
160+
['material-examples:build-no-bundles']);
160161
});
161162

162163
// Note that we need to rebuild the TS here, because the resource inlining

tools/gulp/tasks/e2e.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import {task} from 'gulp';
2-
import {buildConfig, sequenceTask, triggerLivereload, watchFiles} from 'material2-build-tools';
2+
import {buildConfig, sequenceTask, watchFiles} from 'material2-build-tools';
33
import {join} from 'path';
4-
import {copyTask, execNodeTask, ngcBuildTask, serverTask} from '../util/task_helpers';
5-
6-
// There are no type definitions available for these imports.
7-
const gulpConnect = require('gulp-connect');
4+
import {
5+
copyTask,
6+
execNodeTask,
7+
getActiveBrowserSyncInstance,
8+
ngcBuildTask,
9+
serverTask
10+
} from '../util/task_helpers';
811

912
const {outputDir, packagesDir, projectDir} = buildConfig;
1013

@@ -39,7 +42,7 @@ task('e2e:watch', sequenceTask(
3942
/** Watches the e2e app and tests for changes and triggers a test rerun on change. */
4043
task(':e2e:watch', () => {
4144
watchFiles([join(appDir, '**/*.+(html|ts|css)'), join(e2eTestDir, '**/*.+(html|ts)')],
42-
[':e2e:rerun'], false);
45+
[':e2e:rerun']);
4346
});
4447

4548
/** Updates the e2e app and runs the protractor tests. */
@@ -52,7 +55,7 @@ task(':e2e:rerun', sequenceTask(
5255

5356
/** Triggers a reload of the e2e app. */
5457
task(':e2e:reload', () => {
55-
return triggerLivereload();
58+
return getActiveBrowserSyncInstance().reload();
5659
});
5760

5861
/** Task that builds the e2e-app in AOT mode. */
@@ -76,8 +79,8 @@ task('e2e-app:copy-index-html', copyTask(join(appDir, 'index.html'), outDir));
7679
task('e2e-app:build-ts', ngcBuildTask(tsconfigPath));
7780

7881
task(':watch:e2eapp', () => {
79-
watchFiles(join(appDir, '**/*.ts'), ['e2e-app:build'], false);
80-
watchFiles(join(appDir, '**/*.html'), ['e2e-app:copy-assets'], false);
82+
watchFiles(join(appDir, '**/*.ts'), ['e2e-app:build']);
83+
watchFiles(join(appDir, '**/*.html'), ['e2e-app:copy-assets']);
8184
});
8285

8386
/** Ensures that protractor and webdriver are set up to run. */
@@ -90,7 +93,7 @@ task(':test:protractor:setup', execNodeTask(
9093
task(':test:protractor', execNodeTask('protractor', [PROTRACTOR_CONFIG_PATH]));
9194

9295
/** Starts up the e2e app server and rewrites the HTTP requests to properly work with AOT. */
93-
task(':serve:e2eapp', serverTask(outDir, false, [
96+
task(':serve:e2eapp', serverTask(outDir, [
9497
// Rewrite each request for .ngfactory files which are outside of the e2e-app to the **actual**
9598
// path. This is necessary because NGC cannot generate factory files for the node modules
9699
// and release output. If we work around it by adding multiple root directories, the directory
@@ -108,7 +111,7 @@ task(':serve:e2eapp', serverTask(outDir, false, [
108111
]));
109112

110113
/** Terminates the e2e app server */
111-
task(':serve:e2eapp:stop', gulpConnect.serverClose);
114+
task(':serve:e2eapp:stop', () => getActiveBrowserSyncInstance().exit());
112115

113116
/** Builds and serves the e2e app. */
114117
task('serve:e2eapp', sequenceTask('e2e-app:build', ':serve:e2eapp'));

tools/gulp/util/task_helpers.ts

+24-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1+
import {BrowserSyncInstance, create as createBrowserSyncInstance} from 'browser-sync';
12
import * as child_process from 'child_process';
23
import * as fs from 'fs';
34
import * as gulp from 'gulp';
4-
import * as path from 'path';
55
import {buildConfig} from 'material2-build-tools';
6+
import * as path from 'path';
67

7-
// Those imports lack typings.
8+
// This import lacks type definitions.
89
const gulpClean = require('gulp-clean');
9-
const gulpConnect = require('gulp-connect');
1010

1111
// There are no type definitions available for these imports.
1212
const resolveBin = require('resolve-bin');
1313
const httpRewrite = require('http-rewrite-middleware');
1414

1515
const {projectDir} = buildConfig;
1616

17+
/** Currently active browsersync instance. */
18+
let activeBrowserSyncInstance: BrowserSyncInstance;
19+
1720
/** If the string passed in is a glob, returns it, otherwise append '**\/*' to it. */
1821
function _globify(maybeGlob: string, suffix = '**/*') {
1922
if (maybeGlob.indexOf('*') > -1) {
@@ -125,9 +128,7 @@ export function cleanTask(glob: string) {
125128
* Create a task that serves a given directory in the project.
126129
* The server rewrites all node_module/ or dist/ requests to the correct directory.
127130
*/
128-
export function serverTask(packagePath: string, livereload = true,
129-
rewrites?: {from: string, to: string}[]) {
130-
131+
export function serverTask(packagePath: string, rewrites?: {from: string, to: string}[]) {
131132
// The http-rewrite-middleware only supports relative paths as rewrite destinations.
132133
const relativePath = path.relative(projectDir, packagePath);
133134
const defaultHttpRewrites = [
@@ -143,14 +144,24 @@ export function serverTask(packagePath: string, livereload = true,
143144
];
144145

145146
return () => {
146-
gulpConnect.server({
147-
root: projectDir,
148-
livereload: livereload,
147+
if (activeBrowserSyncInstance) {
148+
throw new Error('Cannot setup BrowserSync because there is already an instance running.');
149+
}
150+
151+
activeBrowserSyncInstance = createBrowserSyncInstance();
152+
activeBrowserSyncInstance.init({
153+
server: projectDir,
149154
port: 4200,
150-
host: '0.0.0.0',
151-
middleware: () => {
152-
return [httpRewrite.getMiddleware(rewrites || defaultHttpRewrites)];
153-
}
155+
middleware: httpRewrite.getMiddleware(rewrites || defaultHttpRewrites),
154156
});
155157
};
156158
}
159+
160+
/** Gets the currently active browsersync instance */
161+
export function getActiveBrowserSyncInstance(): BrowserSyncInstance {
162+
if (!activeBrowserSyncInstance) {
163+
throw new Error('Cannot return Browsersync instance because there is no instance running.');
164+
}
165+
166+
return activeBrowserSyncInstance;
167+
}

tools/gulp/util/watch-files-reload.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {watchFiles} from 'material2-build-tools';
2+
import {getActiveBrowserSyncInstance} from './task_helpers';
3+
4+
/**
5+
* Function that watches a set of file globs and runs the specified tasks if a file
6+
* changed. Additionally BrowserSync will reload all browsers on file change.
7+
*/
8+
export function watchFilesAndReload(fileGlob: string | string[], tasks: string[]) {
9+
watchFiles(fileGlob, [...tasks, () => getActiveBrowserSyncInstance().reload()]);
10+
}

tools/package-tools/gulp/trigger-livereload.ts

-11
This file was deleted.
+5-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
import {watch} from 'gulp';
2-
import {triggerLivereload} from './trigger-livereload';
1+
import {watch, WatchCallback} from 'gulp';
32

4-
/**
5-
* Function that watches a set of file globs and runs given Gulp tasks if a given file changes.
6-
* By default the livereload server will be also called on file change.
7-
*/
8-
export function watchFiles(fileGlob: string | string[], tasks: string[], livereload = true,
9-
debounceDelay = 700) {
10-
watch(fileGlob, {debounceDelay}, [...tasks, () => livereload && triggerLivereload()]);
3+
/** Function that watches a set of file globs and runs given Gulp tasks if a given file changes. */
4+
export function watchFiles(fileGlob: string | string[], tasks: (string|WatchCallback)[],
5+
debounceDelay = 700) {
6+
watch(fileGlob, {debounceDelay}, tasks);
117
}

tools/package-tools/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ export * from './inline-resources';
1010
export * from './gulp/build-tasks-gulp';
1111
export * from './gulp/build-scss-pipeline';
1212
export * from './gulp/sequence-task';
13-
export * from './gulp/trigger-livereload';
1413
export * from './gulp/watch-files';

0 commit comments

Comments
 (0)