Skip to content
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

Add BrowserSync #1024

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

### Development

Run `npm start` to see your app at `localhost:3000`
Run `npm start` to see your app at `localhost:3000` and on your local network via BrowserSync, with hot reloading.

### Building & Deploying

Expand Down Expand Up @@ -119,7 +119,7 @@ get a performance check right in your terminal!

#### Browser testing

`npm run start:tunnel` makes your locally-running app globally available on the web
`npm run start:tunnel` makes your app available as with `npm start`, as well as on the web
via a temporary URL: great for testing on different devices, client demos, etc!

#### Unit testing
Expand Down
16 changes: 10 additions & 6 deletions docs/general/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ history irreversibly by accident.
npm run start
```

Starts the development server running on `http://localhost:3000`
Starts the development server and makes your application accessible with
[BrowserSync](https://www.browsersync.io/) at `localhost:3001` and on a local IP address (check your startup logs).

This means that your changes will keep in sync on all your local devices,
even when you update the code or you scroll the page on one of them!

Make sure to check the BrowserSync dashboard at `localhost:3002`.

## Cleaning

Expand Down Expand Up @@ -53,9 +59,7 @@ generate container`)
npm start
```

Starts the development server and makes your application accessible at
`localhost:3000`. Tunnels that server with `ngrok`, which means the website
accessible anywhere! Changes in the application code will be hot-reloaded.
Starts the development server and makes your hot-reloadable application accessible everywhere with BrowserSync.

### Production

Expand Down Expand Up @@ -141,8 +145,8 @@ Watches changes to your application and reruns tests whenever a file changes.
```Shell
npm run start:tunnel
```
Starts the development server and tunnels it with `ngrok`, making the website
available on the entire world. Useful for testing on different devices in different locations!
Starts the development server as usual for development, with an extra tunnels to make the website
available to the entire world. Useful for testing on different devices in different locations!

### Performance testing

Expand Down
9 changes: 4 additions & 5 deletions docs/testing/remote-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
npm run start:tunnel
```

This command will start a server and tunnel it with `ngrok`. You'll get a URL
that looks a bit like this: `http://abcdef.ngrok.com`
Starts the development server similarly to `npm start`, with an extra address XXX.localtunnel.me where XXX is
your app name configured in `package.json`.

This URL will show the version of your application that's in the `build` folder,
and it's accessible from the entire world! This is great for testing on different
devices and from different locations!
This means your app is accessible from the entire world!
This is great for testing on different devices and from different locations.
2 changes: 1 addition & 1 deletion internals/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const ReactBoilerplate = {
* by listing them here.
*/
exclude: [
'browser-sync',
'chalk',
'compression',
'cross-env',
'express',
'ip',
'minimist',
'sanitize.css',
],
Expand Down
35 changes: 35 additions & 0 deletions internals/scripts/browserSync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const browserSync = require('browser-sync');
const path = require('path');
const pkg = require(path.resolve(process.cwd(), 'package.json'));

const logger = require('../../server/logger');

module.exports = function startBrowserSync(port, middleware, cb) {
const bsConfig = {
proxy: {
target: `localhost:${port}`,
middleware,
},
port: parseInt(port, 10) + 1,
ui: {
port: parseInt(port, 10) + 2,
},
// no need to watch '*.js' here, webpack will take care of it for us,
// including full page reloads if HMR won't work
files: [
'build/*.css',
],
};
if (process.env.ENABLE_TUNNEL) {
bsConfig.tunnel = pkg.name.replace(/\W/g,'');
}
const bs = browserSync.create();

bs.init(bsConfig, (err, bs) => {
if (err) return cb(err);
logger.browserSyncStarted();

// return the BrowserSync URLs, in case someone cares
cb(null, bs.getOption("urls"));
});
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@
"dllPlugin": {
"path": "node_modules/react-boilerplate-dlls",
"exclude": [
"browser-sync",
"chalk",
"compression",
"cross-env",
"express",
"ip",
"minimist",
"sanitize.css"
],
Expand All @@ -210,6 +210,7 @@
},
"dependencies": {
"babel-polyfill": "6.16.0",
"browser-sync": "2.16.0",
"chalk": "1.1.3",
"cross-env": "3.1.3",
"compression": "1.6.2",
Expand All @@ -218,7 +219,6 @@
"immutable": "3.8.1",
"intl": "1.2.5",
"invariant": "2.2.1",
"ip": "1.1.3",
"lodash": "4.16.4",
"minimist": "1.2.0",
"react": "15.3.2",
Expand Down
16 changes: 7 additions & 9 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@

const express = require('express');
const logger = require('./logger');
const browserSync = require('../internals/scripts/browserSync');

const argv = require('minimist')(process.argv.slice(2));
const setup = require('./middlewares/frontendMiddleware');
const isDev = process.env.NODE_ENV !== 'production';
const ngrok = (isDev && process.env.ENABLE_TUNNEL) || argv.tunnel ? require('ngrok') : false;
const resolve = require('path').resolve;
const app = express();

// If you need a backend, e.g. an API, add your custom backend-specific middleware here
// app.use('/api', myApi);

// In production we need to pass these values in instead of relying on webpack
setup(app, {
const middleware = setup(app, {
outputPath: resolve(process.cwd(), 'build'),
publicPath: '/',
});
Expand All @@ -28,16 +27,15 @@ app.listen(port, (err) => {
return logger.error(err.message);
}

// Connect to ngrok in dev mode
if (ngrok) {
ngrok.connect(port, (innerErr, url) => {
// Configure browserSync in dev mode
if (process.env.NODE_ENV !== 'production') {
browserSync(port, middleware, (innerErr) => {
if (innerErr) {
return logger.error(innerErr);
}

logger.appStarted(port, url);
logger.appStarted();
});
} else {
logger.appStarted(port);
logger.appStarted();
}
});
21 changes: 5 additions & 16 deletions server/logger.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* eslint-disable no-console */

const chalk = require('chalk');
const ip = require('ip');

const divider = chalk.gray('\n-----------------------------------');

/**
* Logger middleware, you can customize it to make messages more personal
Expand All @@ -16,21 +13,13 @@ const logger = {
},

// Called when express.js app starts on given port w/o errors
appStarted: (port, tunnelStarted) => {
appStarted: () => {
console.log(`Server started ${chalk.green('✓')}`);
},

// If the tunnel started, log that and the URL it's available at
if (tunnelStarted) {
console.log(`Tunnel initialised ${chalk.green('✓')}`);
}

console.log(`
${chalk.bold('Access URLs:')}${divider}
Localhost: ${chalk.magenta(`http://localhost:${port}`)}
LAN: ${chalk.magenta(`http://${ip.address()}:${port}`) +
(tunnelStarted ? `\n Proxy: ${chalk.magenta(tunnelStarted)}` : '')}${divider}
${chalk.blue(`Press ${chalk.italic('CTRL-C')} to stop`)}
`);
// Called when BrowserSync starts w/o errors
browserSyncStarted: () => {
console.log(`BrowserSync started ${chalk.green('✓')}`);
},
};

Expand Down
17 changes: 10 additions & 7 deletions server/middlewares/frontendMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const addDevMiddlewares = (app, webpackConfig) => {
});

app.use(middleware);
app.use(webpackHotMiddleware(compiler));

const hotMiddleware = webpackHotMiddleware(compiler);
app.use(hotMiddleware);

// Since webpackDevMiddleware uses memory-fs internally to store build
// artifacts, we use it instead
Expand All @@ -40,6 +42,8 @@ const addDevMiddlewares = (app, webpackConfig) => {
}
});
});

return [middleware, hotMiddleware];
};

// Production middlewares
Expand All @@ -54,6 +58,8 @@ const addProdMiddlewares = (app, options) => {
app.use(publicPath, express.static(outputPath));

app.get('*', (req, res) => res.sendFile(path.resolve(outputPath, 'index.html')));

return [];
};

/**
Expand All @@ -63,11 +69,8 @@ module.exports = (app, options) => {
const isProd = process.env.NODE_ENV === 'production';

if (isProd) {
addProdMiddlewares(app, options);
} else {
const webpackConfig = require('../../internals/webpack/webpack.dev.babel');
addDevMiddlewares(app, webpackConfig);
return addProdMiddlewares(app, options);
}

return app;
const webpackConfig = require('../../internals/webpack/webpack.dev.babel');
return addDevMiddlewares(app, webpackConfig);
};
Loading