Skip to content

Commit

Permalink
Merge pull request #14 from SmaatoUI/BT-104-styles-hmr
Browse files Browse the repository at this point in the history
[BT-104] HMR styles support
  • Loading branch information
dimadesu committed Jan 6, 2016
2 parents 93fede5 + 86d11a0 commit 936f108
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ dist
.sass-cache
reports
*.log
src/cssWebsocket/client.js
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ Copy assets from one location to another.
### compileCss

Compile SCSS with Compass RubyGem (gem install compass), and run the compiled
CSS through PostCSS with Autoprefixer.
CSS through PostCSS with Autoprefixer. Also starts WebSocket server to update
styles in browser without full page reload after styles are recompiled.

### compileHtml

Expand Down
1 change: 1 addition & 0 deletions demo/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ gulp.task('demoCompileJsAndWatch', gulpTasks.compileJs({
src: `${SOURCE_DIR}/index.js`,
dst: SCRIPTS_DST,
watch: true,
hmrPort: 3000,
}).task);

/**
Expand Down
2 changes: 1 addition & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ gulp.task('lint', lintJs({
}).task);

gulp.task('unit', () => {
return gulp.src('./src/**/*.js')
return gulp.src(['./src/**/*.js', '!./src/cssWebsocket/*'])
.pipe(gulpJasmine({
verbose: true,
}));
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
"karma-threshold-reporter": "0.1.15",
"phantomjs": "1.9.18",
"pre-commit": "1.1.2",
"reconnectingwebsocket": "1.0.0",
"rimraf": "2.4.3",
"vinyl-source-stream": "1.1.0",
"watchify": "3.5.0"
"watchify": "3.5.0",
"ws": "0.8.1"
},
"pre-commit": [
"test"
Expand Down
11 changes: 7 additions & 4 deletions src/compileCss.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

const autoprefixer = require('autoprefixer');
const cssMqpacker = require('css-mqpacker');
const cssWsServer = require('./cssWebsocket/server');
const del = require('del');
const gulp = require('gulp');
const gulpCompass = require('gulp-compass');
const gulpConnect = require('gulp-connect');
const gulpPostcss = require('gulp-postcss');
const gulpRename = require('gulp-rename');
const gulpReplace = require('gulp-replace');
Expand Down Expand Up @@ -74,15 +74,18 @@ module.exports = customConfig => {
const renameCompiledCss = `${config.subTaskPrefix}:renameDstIndexCss`;

gulp.task(renameCompiledCss, () => {
return gulp.src(`${config.dst}/*`)
const stream = gulp.src(`${config.dst}/*`)
// Replace occurences of index.css with dist.css inside of files
.pipe(gulpReplace('index.css', 'dist.css'))
// Rename files from *index*.* to *dist*.*
.pipe(gulpRename((path) => {
path.basename = path.basename.replace('index', 'dist');
}))
.pipe(gulp.dest(config.dst))
.pipe(gulpConnect.reload());
.pipe(gulp.dest(config.dst));

stream.on('finish', cssWsServer.sendUpdate);

return stream;
});

// Delete the original compiled CSS files.
Expand Down
12 changes: 12 additions & 0 deletions src/compileJs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
const babelify = require('babelify');
const browserify = require('browserify');
const browserifyHmr = require('browserify-hmr');
const cssWsConfigureClient = require('./cssWebsocket/configureClient');
const cssWsServer = require('./cssWebsocket/server');
const gulp = require('gulp');
const gulpUtil = require('gulp-util');
const vinylSourceStream = require('vinyl-source-stream');
Expand All @@ -14,6 +16,8 @@ module.exports = customConfig => {
dst: './dist/js',
watch: false,
hmrPort: 3123,
cssReloadPort: 4000,
cssReloadPath: '/css/dist.css',
}, customConfig);

if (!config.src) {
Expand Down Expand Up @@ -57,9 +61,17 @@ module.exports = customConfig => {
}
bundler.transform(babelify);

if (config.watch) {
cssWsConfigureClient(config.cssReloadPort, config.cssReloadPath);
bundler.add(__dirname + '/cssWebsocket/client.js');
}

// Compile the JS, using the bundle.
function compileJs() {
const bundle = bundler.bundle();
if (config.watch) {
cssWsServer.start(config.cssReloadPort);
}
return bundle
.on('error', function onCompileJsError(error) {
gulpUtil.log(gulpUtil.colors.red(error.message));
Expand Down
2 changes: 2 additions & 0 deletions src/compileJs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ describe('compileJs method', () => {
dst: './dist/js',
watch: false,
hmrPort: 3123,
cssReloadPort: 4000,
cssReloadPath: '/css/dist.css',
});
});

Expand Down
14 changes: 14 additions & 0 deletions src/cssWebsocket/client.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import ReconnectingWebSocket from 'reconnectingwebsocket';

// These variables will be supplied from gulp task config on the build step
const cssHref = '#{cssHref}';
const port = '#{port}';

const host = window.document.location.host.replace(/:.*/, '');
const ws = new ReconnectingWebSocket('ws://' + host + ':' + port);

ws.onmessage = () => {
document.querySelector("link[href^='" + cssHref + "']")
.setAttribute('href', cssHref + '?v=' + new Date().getTime());
};
21 changes: 21 additions & 0 deletions src/cssWebsocket/configureClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

const fs = require('fs');

module.exports = (cssReloadPort, cssReloadPath) => {
// Read the template for a client JS file
const lines = fs.readFileSync(__dirname + '/client.txt')
.toString()
.split('\n');

fs.open(__dirname + '/client.js', 'w', (err, fd) => {
lines.forEach(line => {
// Gulp task variables are supplied to a client JS file
const lineReplaced = line.toString()
.replace('#{cssHref}', cssReloadPath)
.replace('#{port}', cssReloadPort)
.concat('\n');

fs.writeSync(fd, lineReplaced);
});
});
};
35 changes: 35 additions & 0 deletions src/cssWebsocket/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

const WebSocketServer = require('ws').Server;

const server = {

instance: null,

start: (port) => {
if (server.instance) return;

server.instance = new WebSocketServer({
port,
});
},

stop: () => {
if (!server.instance) return;

server.instance.close();
},

sendUpdate: () => {
if (!server.instance || !server.instance.clients) return;

// In case site is opened in a number of browsers/tabs/windows
// there will be many clients connected.
// Send an update to all of them.
server.instance.clients.forEach(
client => client.send()
);
},

};

module.exports = server;

0 comments on commit 936f108

Please sign in to comment.