Обновления в моем приложении React не учитываются на сервере разработки Webpack

Я пытаюсь настроить среду для своего приложения React, используя Webpack и Babel. Я использую JSX для реализации компонентов, и я хотел бы использовать перезагрузку в реальном времени.

Вот мой package.json файл:

{
  (...)
  "scripts": {
    "start": "webpack-dev-server --hot --inline"
  },
  "dependencies": {
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.11.1",
    "jsx-loader": "^0.13.2",
    "react": "^15.1.0",
    "react-dom": "^15.1.0",
    "react-hot-loader": "^1.3.0",
    "webpack": "^1.13.1",
    "webpack-dev-server": "^1.14.1"
  }
}

Вот моя конфигурация Webpack:

var webpack = require('webpack');
var path = require('path');

var BUILD_DIR = path.resolve(__dirname, 'src/client/public');
var APP_DIR = path.resolve(__dirname, 'src/client/app');

var config = {
  entry: [
    'webpack-dev-server/client?http://0.0.0.0:8080',
    'webpack/hot/only-dev-server',
    APP_DIR + '/index.jsx'
  ],
  output: {
    path: BUILD_DIR,
    filename: 'bundle.js'
  },
  module : {
    loaders : [
      {
        test : /\.jsx?/,
        include : APP_DIR,
        loaders: ['react-hot', 'babel']
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
};

module.exports = config;

После выполнения npm run start и с этой конфигурацией я вижу в своей консоли, что обновления в файле JSX обнаруживаются, но браузер не обновляется. Более того, если я просматриваю файл module.js, мои обновления не учитываются.

Выполнив команду webpack -d, они...

См. этот репозиторий: https://github.com/templth/react-webpack-hot-reload .

Дополнительные подсказки. Я вижу следующие следы в консоли JavaScript браузера:

[HMR] Waiting for update signal from WDS...
Download the React DevTools for a better development experience: https://(...)/react-devtools
XHR finished loading: GET "http://localhost:8080/sockjs-node/info?t=1467375470671".AbstractXHRObject._start @ abstract-xhr.js:132(anonymous function) (...)
[WDS] Hot Module Replacement enabled.
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
GET http://localhost:8080/src/client/0cf06dae430007853b6f.hot-update.json 404 (Not Found)hotDownloadManifest @ bootstrap (...)
[HMR] Cannot find update. Need to do a full reload!

only-dev-server.js:28 [HMR] (вероятно, из-за перезапуска сервера webpack-dev)

и в консоли, которая запустила сервер разработки webpack

Hash: 85771179bfa8706bc10f
Version: webpack 1.13.1
Time: 275ms
                           Asset      Size  Chunks             Chunk Names
                       bundle.js    991 kB       0  [emitted]  main
0.8073da5d40a8dd413f96.hot-update.js    3.6 kB    0, 0  [emitted] main, main
8073da5d40a8dd413f96.hot-update.json  36 bytes          [emitted]  
chunk    {0} bundle.js, 0.8073da5d40a8dd413f96.hot-update.js, 0.8073da5d40a8dd413f96.hot-update.js (main) 897 kB [rendered]
   [76] ./src/client/app/index.jsx 3.58 kB {0} [built]
     + 255 hidden modules
webpack: bundle is now VALID.

Большое спасибо за вашу помощь!


person Thierry Templier    schedule 01.07.2016    source источник


Ответы (2)


Ваша точка входа должна быть просто webpack/hot/dev-server

(webpack/hot/only-dev-server предназначен для случаев, когда вы хотите/нужно выполнить ручную перезагрузку, см. https://github.com/webpack/webpack/issues/418)

Кроме того, вам необходимо указать publicPath (например, output.publicPath) в вашей конфигурации dev. Например:

publicPath: 'http://localhost:8080/'

(Здесь необходим абсолютный путь для изображений в css для работы с исходными картами)

В вашей конфигурации продукта вам все еще нужно что-то здесь, например

publicPath: '/',

Вам также понадобится это в точке входа для работы HMR. (Он будет удален минификацией в prod как его «недостижимый» код)

if (module.hot) {
     module.hot.accept();
}
person Dan Brown    schedule 01.07.2016
comment
Большое спасибо за ваш ответ! Но у меня все еще такое же поведение. Я добавил некоторые следы в свой вопрос... - person Thierry Templier; 01.07.2016
comment
У меня ошибка 404 в браузере на такие запросы: bootstrap 0cf06da…:25 GET http://localhost:8080/src/client/0cf06dae430007853b6f.hot-update.json - person Thierry Templier; 01.07.2016
comment
Я думаю, вам придется установить publicPath на localhost:8080/src/client (так же, как ваш dev сервер) [ссылка]github.com/gaearon/react -hot-loader/blob/master/docs/ - person Dan Brown; 01.07.2016
comment
... или попробуйте localhost:8080/src/client/ - person Dan Brown; 01.07.2016
comment
еще несколько советов о том, что мне нужно было сделать: Антивирус может прервать горячую перезагрузку (исключить ваш рабочий каталог из вашего AV) Webstorm 2016 нуждается в неотмеченной опции использовать безопасную запись для горячей перезагрузки. Это может относиться к другим редакторам. (Безопасная запись: сначала пытается записать во временный файл) - person Dan Brown; 01.07.2016
comment
Я добавил свойство publicPath, но проблема осталась :-( Я отправил свой код в этот репозиторий на Github: github.com/templth/react-webpack-hot-reload. Не стесняйтесь взглянуть. Большое спасибо за вашу помощь! - person Thierry Templier; 01.07.2016
comment
Для всех ленивых, как я .. это мне очень помогло. После 3 дней биения головой о стену я понял, что мой publicPath был связан с относительной файловой системой, а не с общедоступным URL-адресом, как следует из его названия. (не все проблемы были связаны с этим т.к. я делал эгзотичную комбинацию --> koa2+wp2+react гл.3) - person Goran.it; 16.03.2017

ОБНОВЛЕНИЕ: Использование вашего репозитория github.

Возможное решение — использовать html-webpack-plugin для обслуживания ваших пакетов. Все, что вам нужно сделать, это установить его с помощью npm и добавить в конфигурацию ваших плагинов:

npm i html-webpack-plugin --save-dev

Применение:

var HtmlWebpackPlugin = require('html-webpack-plugin');

plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
        template: './src/client/index.html'
    }),
  ]

Удалите <script src="public/bundle.js" type="text/javascript"></script> из вашего index.html, теперь он будет автоматически добавлен для вас.

Затем откройте http://localhost:8080/, и все должно работать нормально.

Бонус: вы можете использовать html-loader и конфигурацию --inline, чтобы использовать горячую перезагрузку и для html.

npm я html-загрузчик --save-dev

Применение:

{
  test: /\.html$/,
  loader: 'html-loader'        
} 

Затем добавьте его в свой package.json:

"start": "webpack-dev-server --inline --hot"

Объяснение в https://webpack.github.io/docs/webpack-dev-server.html, раздел "Встроенный режим".


Еще одно решение, которое вы можете протестировать, — это использование конфигурации devServer в файле webpack.config.js:

module.exports = {
    devServer: {
        inline: true,
        port: 3333
    },
    ...

Затем я использую publicPath:

publicPath: 'http://localhost:3333/'

И в моем package.json:

"start": "webpack-dev-server --content-base app",

Удалите эти строки из webpack.config.js:

'webpack-dev-server/client?http://0.0.0.0:8080',
'webpack/hot/only-dev-server',

Также вы можете использовать просто «npm start», «run» в этом случае не нужен.

Надеюсь, поможет.

person Kadoo    schedule 01.07.2016
comment
Большое спасибо за ваш ответ! Вы имеете в виду, что при таком подходе предусмотрена перезагрузка в реальном времени? - person Thierry Templier; 01.07.2016
comment
Да. Я почти уверен, что этот подход использует горячую перезагрузку по умолчанию, но вы можете получить дополнительную информацию здесь webpack.github.io/docs/webpack-dev-server.html в разделе "Дополнительные параметры конфигурации". Я просто думаю, что так проще понять, как это использовать. - person Kadoo; 02.07.2016