Node.js - Автоматическое обновление в Dev
Я пытаюсь улучшить опыт DEV в моем Node. Для этого хочу:
a) перезагрузите сервер при изменении кода на стороне сервера
b) обновите браузер, когда изменяется код на стороне клиента.
Чтобы сделать это, я начал интегрировать nodemon и browserSync в мой gulp script.
В моем gulp script у меня есть следующая задача:
gulp.task('startDevEnv', function(done) {
// Begin watching for server-side file changes
nodemon(
{ script: input.server, ignore:[input.views] })
.on('start', function () {
browserSync.init({
proxy: "http://localhost:3002"
});
})
;
// Begin watching client-side file changes
gulp.watch([ input.css, input.js, input.html ], function() { browserSync.reload(); });
done();
});
При выполнении указанной задачи мой браузер открывает http://localhost:3000/. Мое приложение видно, как ожидалось. Однако в окне консоли я замечаю:
Error: listen EADDRINUSE :::3002
Я понимаю в некоторой степени. У меня есть app.set('port', process.env.PORT || 3002);
в моем файле server.js. Тем не менее, я думал, что это цель установки значения прокси. Тем не менее, всякий раз, когда я делаю изменение кода, я вижу следующую связанную ошибку в окне консоли:
[07:08:19] [nodemon] restarting due to changes...
[07:08:19] [nodemon] starting `node ./dist/server.js`
events.js:142
throw er; // Unhandled 'error' event
^
TypeError: args.cb is not a function
at Object.init (/Users/me/Website/Develop/node_modules/browser-sync/lib/public/init.js:25:25)
at null.<anonymous> (/Users/me/Website/Develop/gulpfile.js:142:25)
at emitNone (events.js:73:20)
at emit (events.js:167:7)
at Object.run (/Users/me/Website/Develop/node_modules/nodemon/lib/monitor/run.js:97:7)
at Function.run.kill (/Users/me/Website/Develop/node_modules/nodemon/lib/monitor/run.js:221:7)
at null.<anonymous> (/Users/me/Website/Develop/node_modules/nodemon/lib/monitor/run.js:333:7)
at emitOne (events.js:83:20)
at emit (events.js:170:7)
at restartBus (/Users/me/Website/Develop/node_modules/nodemon/lib/monitor/watch.js:162:7)
Me-MBP:Develop me$ events.js:142
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::3002
at Object.exports._errnoException (util.js:856:11)
at exports._exceptionWithHostPort (util.js:879:20)
at Server._listen2 (net.js:1238:14)
at listen (net.js:1274:10)
at Server.listen (net.js:1370:5)
at Object.<anonymous> (/Users/me/Website/Develop/dist/server.js:70:8)
at Module._compile (module.js:399:26)
at Object.Module._extensions..js (module.js:406:10)
at Module.load (module.js:345:32)
at Function.Module._load (module.js:302:12)
В этот момент изменения моего кода не отображаются в моем браузере. Я не понимаю, что я делаю неправильно. Я подозреваю, что мои порты неправильно сконфигурированы. Но я не уверен, как их настроить.
По умолчанию BrowserSync использует порт 3000. BrowserSync также использует порт 3001 для интерфейса BrowserSync. По этим двум причинам я решил установить порт на 3002 в файле server.js и создать прокси-сервер, показанный выше. Что я делаю неправильно?
Ответы
Ответ 1
Вам действительно не нужно использовать gulp для этого.
a) перезагрузите мой сервер при изменении кода на стороне сервера
Установите nodemon глобально, используя npm i -g nodemon
, затем в папке вашего приложения сделайте nodemon
или nodemon ${index-file-of-your-app}
.
b) обновите браузер, когда клиентский код будет изменен.
Используйте браузер или веб-пакет. Я предпочитаю использовать webpack; вам может понадобиться немного узнать о конфигурации, но хорошая вещь с webpack заключается в том, что вам не нужно ее обновлять. Как только изменения будут найдены, изменения будут автоматически отображены в браузере. https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack
Ответ 2
Возможно, мне не хватает некоторого контекста (например, я не уверен, что представляет собой input
), однако я думаю, что модуль reload модуля npm может решить вашу проблему. Вот пример со страницы пакета npm:
var express = require('express')
, http = require('http')
, path = require('path')
, reload = require('reload')
, bodyParser = require('body-parser')
, logger = require('morgan')
var app = express()
var publicDir = path.join(__dirname, '')
app.set('port', process.env.PORT || 3000)
app.use(logger('dev'))
app.use(bodyParser.json()) //parses json, multi-part (file), url-encoded
app.get('/', function(req, res) {
res.sendFile(path.join(publicDir, 'index.html'))
})
var server = http.createServer(app)
//reload code here
//optional reload delay and wait argument can be given to reload, refer to [API](https://github.com/jprichardson/reload#api) below
reload(server, app, [reloadDelay], [wait])
server.listen(app.get('port'), function(){
console.log("Web server listening on port " + app.get('port'));
});
Ответ 3
Ошибка EADDRINUSE, как правило, связана с подключением, уже открытым на указанном порту. Вероятно, это связано с тем, что предыдущий экземпляр соединения не был правильно закрыт при перезапуске приложения.
Посмотрите этот смысл и, в частности, попробуйте что-то подобное в вашем файле gulp:
'use strict';
var gulp = require('gulp');
var browserSync = require('browser-sync');
var nodemon = require('gulp-nodemon');
gulp.task('default', ['browser-sync'], function () {});
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:3002"
});
});
gulp.task('nodemon', function (cb) {
var started = false;
return nodemon({
script: 'app.js'
}).on('start', function () {
// to avoid nodemon being started multiple times
if (!started) {
cb();
started = true;
}
});
});
Ответ 4
@mateeyow прав.
Но если вы хотите, чтобы браузер автоматически перезагружался, вам также нужен плагин с настройками вставки.
Включить замену webpack-hot-замены только в памяти браузера, перезагрузить его.
Смотрите рок, например: https://github.com/orange727/rock/blob/master/app/templates/webpack/webpack.make.js#L255
Так же:
webpackConfig.plugins: [
new webpack.HotModuleReplacementPlugin(),
new LiveReloadPlugin({
appendScriptTag: true,
port: config.ports.livereload,
})];