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 liveReload option to enable/disable refreshing the page #1812

Closed
wants to merge 16 commits into from
Closed
5 changes: 5 additions & 0 deletions bin/options.js
Expand Up @@ -17,6 +17,11 @@ const options = {
type: 'boolean',
describe: 'Broadcasts the server via ZeroConf networking on start',
},
liveReload: {
type: 'boolean',
describe: 'Enables/Disables live reloading on changing files',
default: true,
},
lazy: {
type: 'boolean',
describe: 'Lazy',
Expand Down
9 changes: 8 additions & 1 deletion client-src/default/index.js
Expand Up @@ -47,6 +47,7 @@ if (!urlParts.port || urlParts.port === '0') {
}

let hot = false;
let liveReload = false;
let initial = true;
let currentHash = '';
let useWarningOverlay = false;
Expand Down Expand Up @@ -85,6 +86,10 @@ const onSocketMsg = {
hot = true;
log.info('[WDS] Hot Module Replacement enabled.');
},
liveReload() {
liveReload = true;
log.info('[WDS] Live Reloading enabled.');
},
invalid() {
log.info('[WDS] App updated. Recompiling...');
// fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
Expand Down Expand Up @@ -271,7 +276,9 @@ function reloadApp() {
// broadcast update to window
self.postMessage(`webpackHotUpdate${currentHash}`, '*');
}
} else {
}
// allow refreshing the page only if liveReload isn't disabled
if (liveReload) {
let rootWindow = self;
// use parent window for reload (in case we're in an iframe with no valid src)
const intervalId = self.setInterval(() => {
Expand Down
9 changes: 6 additions & 3 deletions lib/Server.js
Expand Up @@ -1000,9 +1000,12 @@ class Server {

const watcher = chokidar.watch(watchPath, watchOptions);

watcher.on('change', () => {
this.sockWrite(this.sockets, 'content-changed');
});
// disabling refreshing on changing the content
if (this.options.liveReload !== false) {
watcher.on('change', () => {
this.sockWrite(this.sockets, 'content-changed');
});
}

this.contentBaseWatchers.push(watcher);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/options.json
Expand Up @@ -168,6 +168,9 @@
"lazy": {
"type": "boolean"
},
"liveReload": {
"type": "boolean"
},
"log": {
"instanceof": "Function"
},
Expand Down Expand Up @@ -377,6 +380,7 @@
"inline": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverinline)",
"key": "should be {String|Buffer}",
"lazy": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverlazy-)",
"liveReload": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#livereload-)",
"log": "should be {Function}",
"logLevel": "should be {String} and equal to one of the allowed values\n\n [ 'info', 'warn', 'error', 'debug', 'trace', 'silent' ]\n\n (https://github.com/webpack/webpack-dev-middleware#loglevel)",
"logTime": "should be {Boolean} (https://github.com/webpack/webpack-dev-middleware#logtime)",
Expand Down
4 changes: 4 additions & 0 deletions lib/utils/createConfig.js
Expand Up @@ -88,6 +88,10 @@ function createConfig(config, argv, { port }) {
options.hotOnly = argv.hotOnly;
}

if (argv.liveReload === false) {
options.liveReload = false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if (argv.contentBase === false) {
we should test --no-live-reload because be default liveReload should be true


// TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4)
// We should prefer CLI arg under config, now we always prefer `clientLogLevel` from `devServer`
if (!options.clientLogLevel && argv.clientLogLevel) {
Expand Down
104 changes: 104 additions & 0 deletions test/ContentBase.test.js
Expand Up @@ -19,6 +19,110 @@ describe('ContentBase', () => {
let server;
let req;

describe('Test disabling live reloading', () => {
const nestedFile = path.join(contentBasePublic, 'assets/example.txt');

jest.setTimeout(30000);

beforeAll((done) => {
server = helper.start(
config,
{
contentBase: contentBasePublic,
watchContentBase: true,
liveReload: false,
},
done
);
req = request(server.app);
});

afterAll((done) => {
helper.close(() => {
done();
});
fs.truncateSync(nestedFile);
});

it('Should not reload on changing files', (done) => {
let reloaded = false;

server.contentBaseWatchers[0].on('change', () => {
// it means that file has changed

// simulating server behaviour
if (server.options.liveReload !== false) {
Object.defineProperty(window.location, 'reload', {
configurable: true,
});
window.location.reload = jest.fn();
window.location.reload();
reloaded = true;
}
expect(reloaded).toBe(false);

done();
});

// change file content
setTimeout(() => {
fs.writeFileSync(nestedFile, 'Heyo', 'utf8');
}, 1000);
});
});

describe('Testing live reloading', () => {
const nestedFile = path.join(contentBasePublic, 'assets/example.txt');

jest.setTimeout(30000);

beforeAll((done) => {
server = helper.start(
config,
{
contentBase: contentBasePublic,
watchContentBase: true,
liveReload: true,
},
done
);
req = request(server.app);
});

afterAll((done) => {
helper.close(() => {
done();
});
fs.truncateSync(nestedFile);
});

it('Should reload on changing files', (done) => {
let reloaded = false;

server.contentBaseWatchers[0].on('change', () => {
// it means that files has changed

// simulating server behaviour
if (server.options.liveReload !== false) {
Object.defineProperty(window.location, 'reload', {
configurable: true,
});
window.location.reload = jest.fn();
window.location.reload();
reloaded = true;
}
expect(reloaded).toBe(true);

done();
});

// change file content
setTimeout(() => {
fs.writeFileSync(nestedFile, 'Heyo', 'utf8');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed many typos, now is everything ok?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this comment is my mistake. Sorry...

}, 1000);
});
});

describe('to directory', () => {
const nestedFile = path.join(contentBasePublic, 'assets/example.txt');

Expand Down
24 changes: 24 additions & 0 deletions test/CreateConfig.test.js
Expand Up @@ -11,6 +11,8 @@ const argv = {
hot: true,
// Can be `--no-hot-only` in CLI (misleading and undocumented)
hotOnly: false,
// Can be `--live-reload` in CLI (misleading and undocumented)
liveReload: true,
};

describe('createConfig', () => {
Expand Down Expand Up @@ -346,6 +348,28 @@ describe('createConfig', () => {
expect(config).toMatchSnapshot();
});

it('liveReload option', () => {
const config = createConfig(
webpackConfig,
Object.assign({}, argv, { liveReload: true }),
{ port: 8080 }
);

expect(config).toMatchSnapshot();
});

it('liveReload option (in devServer config)', () => {
const config = createConfig(
Object.assign({}, webpackConfig, {
devServer: { liveReload: true },
}),
argv,
{ port: 8080 }
);

expect(config).toMatchSnapshot();
});

it('hot option (in devServer config)', () => {
const config = createConfig(
Object.assign({}, webpackConfig, {
Expand Down
29 changes: 29 additions & 0 deletions test/__snapshots__/CreateConfig.test.js.snap
Expand Up @@ -699,6 +699,35 @@ Object {
}
`;

exports[`createConfig liveReload option (in devServer config) 1`] = `
Object {
"hot": true,
"hotOnly": false,
"liveReload": true,
"noInfo": true,
"port": 8080,
"publicPath": "/",
"stats": Object {
"cached": false,
"cachedAssets": false,
},
}
`;

exports[`createConfig liveReload option 1`] = `
Object {
"hot": true,
"hotOnly": false,
"noInfo": true,
"port": 8080,
"publicPath": "/",
"stats": Object {
"cached": false,
"cachedAssets": false,
},
}
`;

exports[`createConfig mimeTypes option - with force 1`] = `
Object {
"hot": true,
Expand Down