2017-08-14 6 views
1

Ich versuche React-Hot-Loader 3 mit React-Hot-Loader 3, React-Router 4 und Webpack-Hot-Middleware (letzte Version, 2.18.2). HierReact Hot Reload mit React-Hot-Loader 3, React-Router 4 und Webpack-Hot-Middleware

ist mein server.js:

const express = require('express'); 
const bodyParser = require('body-parser'); 
const cookiesMiddleware = require('universal-cookie-express'); 
/* eslint-disable import/no-extraneous-dependencies */ 
const webpack = require('webpack'); 
const webpackDevMiddleware = require('webpack-dev-middleware'); 
const webpackHotMiddleware = require('webpack-hot-middleware'); 
const webpackHotServerMiddleware = require('webpack-hot-server-middleware'); 
/* eslint-enable import/no-extraneous-dependencies */ 
const clientConfig = require('./webpack.config.dev.client'); 
const serverConfig = require('./webpack.config.dev.server'); 

const PORT_NUMBER = process.env.PORT || 3000; 
const app = express(); 

app.use(bodyParser.urlencoded({ extended: true })); 
app.use(cookiesMiddleware()); 
app.use(express.static('public')); 

const multiCompiler = webpack([clientConfig, serverConfig]); 
const clientCompiler = multiCompiler.compilers[0]; 

app.use(webpackDevMiddleware(multiCompiler, { 
    publicPath: clientConfig.output.publicPath, 
    noInfo: true, 
    stats: { children: false }, 
})); 
app.use(webpackHotMiddleware(clientCompiler)); 
app.use(webpackHotServerMiddleware(multiCompiler, { 
    serverRendererOptions: { outputPath: clientConfig.output.path }, 
})); 

app.listen(PORT_NUMBER,() => { 
    // eslint-disable-next-line no-console 
    console.log(`Server listening at port ${PORT_NUMBER}`); 
}); 

Mein client entry point:

import React from 'react'; 
import { render } from 'react-dom'; 
import { AppContainer } from 'react-hot-loader'; 

import * as Bundles from './components/Bundles'; 
import App from './App'; 

const doRender =() => { 
    render(
    <AppContainer> 
     <App type="client" /> 
    </AppContainer>, 
    document.getElementById('content'), 
); 
}; 

const splitPoints = window.splitPoints || []; 
Promise.all(splitPoints.map(chunk => Bundles[chunk].loadComponent())) 
    .then(doRender); 

if (module.hot) { 
    module.hot.accept('./App', doRender); 
} 

.babelrc:

{ 
    "plugins": [ 
    "transform-decorators-legacy", 
    "transform-object-rest-spread" 
    ], 
    "presets": [ 
    ["es2015", { "modules": false }], 
    "react", 
    "stage-0" 
    ], 
    "env": { 
    "development": { 
     "plugins": ["react-hot-loader/babel"] 
    }, 
    "test": { 
     "plugins": ["transform-es2015-modules-commonjs"] 
    } 
    } 
} 

Es sieht aus wie ich jeden Schritt react-hot-loader's README gefolgt, aber immer wenn ich etwas ändern Code in einer Komponente, ich bekomme das ich Ssage in der Konsole:

[HMR] bundle rebuilding 
client.js:207 [HMR] bundle rebuilt in 8218ms 
process-update.js:27 [HMR] Checking for updates on the server... 
process-update.js:81 [HMR] The following modules couldn't be hot updated: (Full reload needed) 
This is usually because the modules which have changed (and their parents) do not know how to hot reload themselves. See http://webpack.github.io/docs/hot-module-replacement-with-webpack.html for more details. 

Hat jemand auf diesem einen gestolpert? Danke im Voraus!

Edit: hier ist mein Klient webpack config:

const path = require('path'); 
const webpack = require('webpack'); 
const autoprefixer = require('autoprefixer'); 
const StyleLintPlugin = require('stylelint-webpack-plugin'); 
const notifier = require('node-notifier'); 

const configFileName = './.env.development.json'; 
let envConfig; 

try { 
    // eslint-disable-next-line import/no-dynamic-require, global-require 
    envConfig = require(configFileName); 
} catch (e) { 
    envConfig = {}; 
} 

const eslintSettings = { 
    extends: path.join(__dirname, '.eslintrc.js'), 
    configFile: path.join(__dirname, '.eslintrc.js'), 
    emitWarning: true, 
    cache: true, 
}; 
const babelSettings = { 
    extends: path.join(__dirname, '.babelrc'), 
    cacheDirectory: true, 
}; 

const excludes = [ 
    /node_modules(?![/\\]@local-package[/\\])/, 
]; 
const roots = [ 
    path.join(__dirname, '../../node_modules'), 
    path.join(__dirname, 'node_modules'), 
    path.join(__dirname, 'client'), 
]; 

const getCommonCSSLoaders = enableCSSModules => [ 
    { 
    loader: 'style-loader', 
    }, 
    { 
    loader: 'css-loader', 
    options: { 
     modules: enableCSSModules, 
     importLoaders: 1, 
     localIdentName: '[name]_[local]_[hash:base64:3]', 
    }, 
    }, 
    { 
    loader: 'postcss-loader', 
    options: { 
     sourceMap: true, 
     ident: 'postcss', 
     plugins:() => [ 
     // eslint-disable-next-line global-require, import/no-extraneous-dependencies 
     require('postcss-flexbugs-fixes'), 
     autoprefixer({ 
      env: 'development', 
      flexbox: 'no-2009', 
     }), 
     ], 
    }, 
    }, 
]; 

const rules = [ 
    { 
    enforce: 'pre', 
    test: /\.js$/, 
    exclude: /node_modules/, 
    loader: 'eslint-loader', 
    options: eslintSettings, 
    }, 
    { 
    test: /\.js$/, 
    exclude: excludes, 
    loader: 'babel-loader', 
    options: babelSettings, 
    }, 
    { 
    test: /\.css$/, 
    exclude: excludes, 
    use: [ 
     ...getCommonCSSLoaders(true), 
    ], 
    }, 
    { 
    test: /\.css$/, 
    include: excludes, 
    use: [ 
     ...getCommonCSSLoaders(false), 
    ], 
    }, 
    { 
    test: /\.scss$/, 
    exclude: excludes, 
    use: [ 
     ...getCommonCSSLoaders(true), 
     { 
     loader: 'resolve-url-loader', 
     }, 
     { 
     loader: 'sass-loader', 
     options: { 
      sourceMap: true, 
     }, 
     }, 
    ], 
    }, 
    { 
    test: /.*\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif)$/i, 
    use: [ 
     { 
     loader: 'url-loader', 
     options: { 
      name: 'images/[name].[hash].[ext]', 
      limit: 20000, 
     }, 
     }, 
     { 
     loader: 'image-webpack-loader', 
     options: { 
      mozjpeg: { 
      quality: 80, 
      }, 
      pngquant: { 
      quality: '80-90', 
      }, 
      bypassOnDebug: true, 
     }, 
     }, 
    ], 
    }, 
]; 

const plugins = [ 
    new webpack.LoaderOptionsPlugin({ 
    debug: true, 
    }), 
    new webpack.HotModuleReplacementPlugin(), 
    new webpack.NoEmitOnErrorsPlugin(), 
    new StyleLintPlugin({ 
    configFile: path.join(__dirname, '.stylelintrc.js'), 
    files: [ 
     '**/*.s?(a|c)ss', 
     '../shared/**/*.s?(a|c)ss', 
    ], 
    emitErrors: false, 
    }), 
    new webpack.NormalModuleReplacementPlugin(/\/components\/Bundles/, './components/AsyncBundles'), 
    new webpack.NormalModuleReplacementPlugin(/\/Bundles/, './AsyncBundles'), 
    new webpack.optimize.CommonsChunkPlugin({ 
    name: 'client', 
    async: 'common', 
    children: true, 
    minChunks: (module, count) => { 
     if (module.resource && (/^.*\.(css|scss)$/).test(module.resource)) { 
     return false; 
     } 
     return count >= 3 && module.context && !module.context.includes('node_modules'); 
    }, 
    }), 
    new webpack.optimize.CommonsChunkPlugin({ 
    name: 'client', 
    children: true, 
    minChunks: module => module.context && module.context.includes('node_modules'), 
    }), 
    new webpack.optimize.CommonsChunkPlugin({ 
    name: 'vendors', 
    minChunks: module => module.context && module.context.includes('node_modules'), 
    }), 
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), 
    // eslint-disable-next-line func-names 
    function() { 
    this.plugin('done', (stats) => { 
     notifier.notify({ 
     title: 'Webpack : Build Succeeded', 
     message: `${stats.compilation.errors.length} Error(s) - ${stats.compilation.warnings.length} Warning(s)`, 
     }); 
    }); 
    this.plugin('failed',() => { 
     notifier.notify({ 
     title: 'Webpack', 
     message: 'Build Failed HARD', 
     }); 
    }); 
    }, 
]; 

const config = { 
    name: 'client', 
    target: 'web', 
    devtool: 'inline-source-map', 
    entry: ['webpack-hot-middleware/client', 'react-hot-loader/patch', './client/src/entry/js/polyfills', './client/src/entry/js/client'], 
    output: { 
    filename: 'client/[name].js', 
    chunkFilename: 'client/chunks/[name].chunk.js', 
    path: path.join(__dirname, 'public/dist'), 
    publicPath: '/dist/', 
    pathinfo: true, 
    }, 
    module: { 
    rules, 
    }, 
    plugins, 
    resolve: { 
    modules: roots, 
    }, 
    resolveLoader: { 
    modules: roots, 
    }, 
    node: { 
    fs: 'empty', 
    net: 'empty', 
    tls: 'empty', 
    }, 
}; 

module.exports = config; 
+0

benötigen webpack Konfigurationsdateien. Oder überprüfe meine [boilderplate] (https://github.com/reactGo/reactGo/pull/919.) @ Zephir77167 – ZeroCho

+0

In der Tat habe ich meinen Beitrag bearbeitet, um ihn hinzuzufügen. Ich habe Ihren Textbaustein überprüft, konnte aber nicht herausfinden, was in meiner Implementierung fehlte – Zephir77167

Antwort

1

Vielleicht hat es etwas mit Ihrer webpack.config Datei zu tun? Hast du die heißen Sachen in deinem Eintrag eingerichtet?

const config = { 
    entry: [ 
     'babel-polyfill', 

     'react-hot-loader/patch', // activate HMR for React 
     `webpack-hot-middleware/client?path=http://${HOST}:${PORT}/__webpack_hmr`, // bundle the client for webpack-hot-middleware and connect to the provided endpoint 

     './src/client.jsx', 
    ], 

Ich habe mehr Glück habe mit Hapi als meinen Server mit webpack-hot-Middleware und webpack-dev-Middleware. Hier ist ein Ausschnitt

import Webpack from 'webpack'; 
import HapiWebpackPlugin from 'hapi-webpack-plugin'; 

const config = require('../../../webpack.config.js'); // eslint-disable-line global-require 
const compiler = Webpack(config); 

const options = { 
    assets: { 
     // webpack-dev-middleware options - https://github.com/webpack/webpack-dev-middleware 
     index: '/public/index.html', 
    }, 
    hot: { 
     // webpack-hot-middleware options - https://github.com/glenjamin/webpack-hot-middleware 
    }, 
    compiler, 
}; 

server.register({ 
    register: HapiWebpackPlugin, 
    options, 
}, (error) => { 
    if (error) { 
     console.error(error); 
    } 
}); 

Wenn Sie Hapi, um zu versuchen, check out my hapi-react-hot-loader-example

Hier ist meine volle webpack.config

const path = require('path'); 
const webpack = require('webpack'); 
const CopyWebpackPlugin = require('copy-webpack-plugin'); 
const ExtractTextPlugin = require('extract-text-webpack-plugin'); 
const HtmlWebpackPlugin = require('html-webpack-plugin'); 
const ProgressBarPlugin = require('progress-bar-webpack-plugin'); 
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin'); 
const RobotstxtPlugin = require('robotstxt-webpack-plugin').default; 

const PORT = process.env.PORT || 3000; 
const HOST = process.env.HOST || 'localhost'; 
const NODE_ENV = process.env.NODE_ENV || 'production'; 
const isProduction = (NODE_ENV === 'production'); 
const isDevelopment = (NODE_ENV === 'development'); 

const config = { 
    entry: isDevelopment 
     ? [ 
      'babel-polyfill', 

      'react-hot-loader/patch', // activate HMR for React 
      `webpack-hot-middleware/client?path=http://${HOST}:${PORT}/__webpack_hmr`, // bundle the client for webpack-hot-middleware and connect to the provided endpoint 

      './src/client.jsx', 
     ] 
     : [ 
      'babel-polyfill', 

      './src/client.jsx', 
     ], 

    resolve: { 
     extensions: ['.js', '.jsx', '.json'], 
    }, 

    output: { 
     path: path.join(__dirname, 'dist/public/'), 
     filename: isDevelopment 
      ? 'main.js' 
      : 'assets/scripts/[name].[chunkhash].js', 
    }, 

    module: { 
     rules: [ 
      { 
       test: /\.css$/, 
       use: ['css-hot-loader'].concat(
        ExtractTextPlugin.extract({ 
         fallback: 'style-loader', 
         use: [ 
          { 
           loader: 'css-loader', 
           options: {minimize: true}, 
          }, 
          { 
           loader: 'postcss-loader', 
          }, 
         ], 
        }) 
       ), 
      }, 
      { 
       test: /\.jsx?$/, 
       use: ['babel-loader'], 
       include: path.join(__dirname, 'src'), 
      }, 
     ], 
    }, 

    plugins: [ 
     new ProgressBarPlugin(), 

     new webpack.DefinePlugin({ 
      'process.env.NODE_ENV': JSON.stringify(NODE_ENV), 
     }), 

     isDevelopment 
      ? null 
      : new webpack.optimize.ModuleConcatenationPlugin(), 

     isDevelopment 
      ? new webpack.HotModuleReplacementPlugin() // enable HMR globally 
      : null, 
     isDevelopment 
      ? new webpack.NamedModulesPlugin() // prints more readable module names in the browser console on HMR updates 
      : null, 
     isDevelopment 
      ? new webpack.NoEmitOnErrorsPlugin() // do not emit compiled assets that include errors 
      : null, 

     new ExtractTextPlugin({ 
      filename: isDevelopment 
       ? 'assets/styles/main.css' 
       : 'assets/styles/[name].[chunkhash].css', 
     }), 

     isDevelopment 
      ? null 
      : new webpack.optimize.CommonsChunkPlugin({ 
       name: 'vendor', 
       minChunks: module => /node_modules/.test(module.resource), 
      }), 

     isDevelopment 
      ? null 
      : new webpack.optimize.CommonsChunkPlugin({name: 'manifest'}), 

     isProduction 
      ? new webpack.optimize.UglifyJsPlugin() 
      : null, 

     new HtmlWebpackPlugin({ 
      template: path.resolve(__dirname, 'src/index.html'), 
      minify: isProduction ? {collapseWhitespace: true, collapseInlineTagWhitespace: true} : false, 
      alwaysWriteToDisk: true, 
     }), 
     new HtmlWebpackHarddiskPlugin(), 

     new CopyWebpackPlugin([ 
      { 
       context: 'src/assets/media', 
       from: '**/*', 
       to: 'assets/media', 
      }, 
     ]), 

     new RobotstxtPlugin({ 
      policy: [ 
       isProduction 
        ? {userAgent: '*', allow: '/'} 
        : {userAgent: '*', disallow: '/'}, 
      ], 
     }), 
    ].filter(Boolean), 

    devtool: isProduction 
     ? 'none' 
     : 'cheap-module-eval-source-map', 

    performance: { 
     maxAssetSize: 500000, 
    }, 
}; 

module.exports = config; 
+0

Danke, ich habe die Reihenfolge 'reac-hot-loader/patch' und 'webpack-hot-middleware/client' geändert, um Ihre Konfiguration nachzuahmen, und es hat funktioniert ! – Zephir77167