1 |
|
2 | var lr = require('tiny-lr');
|
3 | var servers = {};
|
4 |
|
5 | function LiveReloadPlugin(options) {
|
6 | this.options = options || {};
|
7 | this.port = this.options.port || 35729;
|
8 | this.ignore = this.options.ignore || new RegExp();
|
9 | this.lastHash = null;
|
10 | this.server = null;
|
11 | }
|
12 |
|
13 | Object.defineProperty(LiveReloadPlugin.prototype, 'isRunning', {
|
14 | get: function() { return !!this.server; }
|
15 | });
|
16 |
|
17 | LiveReloadPlugin.prototype.start = function start(watching, cb) {
|
18 | var port = this.port;
|
19 | if (servers[port]) {
|
20 | this.server = servers[port];
|
21 | cb();
|
22 | }
|
23 | else {
|
24 | this.server = servers[port] = lr(this.options);
|
25 | this.server.errorListener = function serverError(err) {
|
26 | console.error('Live Reload disabled: ' + err.message);
|
27 | if (err.code !== 'EADDRINUSE') {
|
28 | console.error(err.stack);
|
29 | }
|
30 | cb();
|
31 | };
|
32 | this.server.listen(this.port, function serverStarted(err) {
|
33 | if (!err) {
|
34 | console.log('Live Reload listening on port ' + port + '\n');
|
35 | }
|
36 | cb();
|
37 | });
|
38 | }
|
39 | };
|
40 |
|
41 | LiveReloadPlugin.prototype.done = function done(stats) {
|
42 | var hash = stats.compilation.hash;
|
43 | var files = Object.keys(stats.compilation.assets)
|
44 | .filter(function(file) { return !file.match(this.ignore); }, this);
|
45 |
|
46 | if (this.isRunning && hash !== this.lastHash && files.length > 0) {
|
47 | this.lastHash = hash;
|
48 | this.server.notifyClients(files);
|
49 | }
|
50 | };
|
51 |
|
52 | LiveReloadPlugin.prototype.failed = function failed() {
|
53 | this.lastHash = null;
|
54 | };
|
55 |
|
56 | LiveReloadPlugin.prototype.autoloadJs = function autoloadJs() {
|
57 | return [
|
58 | '// webpack-livereload-plugin',
|
59 | '(function() {',
|
60 | ' if (typeof window === "undefined") { return };',
|
61 | ' var id = "webpack-livereload-plugin-script";',
|
62 | ' if (document.getElementById(id)) { return; }',
|
63 | ' var el = document.createElement("script");',
|
64 | ' el.id = id;',
|
65 | ' el.async = true;',
|
66 | ' el.src = "http://localhost:' + this.port + '/livereload.js";',
|
67 | ' document.head.appendChild(el);',
|
68 | '}());\n'
|
69 | ].join('\n');
|
70 | };
|
71 |
|
72 | LiveReloadPlugin.prototype.scriptTag = function scriptTag(source) {
|
73 | var js = this.autoloadJs();
|
74 | if (this.options.appendScriptTag && this.isRunning) {
|
75 | return js + source;
|
76 | }
|
77 | else {
|
78 | return source;
|
79 | }
|
80 | };
|
81 |
|
82 | LiveReloadPlugin.prototype.applyCompilation = function applyCompilation(compilation) {
|
83 | compilation.mainTemplate.plugin('startup', this.scriptTag.bind(this));
|
84 | };
|
85 |
|
86 | LiveReloadPlugin.prototype.apply = function apply(compiler) {
|
87 | this.compiler = compiler;
|
88 | compiler.plugin('compilation', this.applyCompilation.bind(this));
|
89 | compiler.plugin('watch-run', this.start.bind(this));
|
90 | compiler.plugin('done', this.done.bind(this));
|
91 | compiler.plugin('failed', this.failed.bind(this));
|
92 | };
|
93 |
|
94 | module.exports = LiveReloadPlugin;
|