2017-08-15 1 views
0

bricoler avec webpack et les choses associées pour la première fois. J'essaie de combiner les avantages de webpack-dev-server et de browser-sync pour le faire quand je mets à jour un composant de réaction que mon navigateur ne recharge pas, il utilise simplement le remplacement de module chaud. il y a plein de plats à partager je suppose, mais je pars de zéro.React - webpack hmr

im au point où HMR est activé et à l'écoute des modifications. Je modifie un composant et il reçoit le changement et dit App est à jour. Mais la vue ne change pas quelques secondes plus tard, je reçois une erreur Web Socket. error

si cela est difficile à lire dit essentiellement Erreur de socket Web, socket fermé avant poignée de main terminé ...

ma config webpack

const webpack = require("webpack"); 
const path = require("path"); 
const SRC_DIR = path.resolve(__dirname,'src'); 
const DIST_DIR = path.resolve(__dirname,'dist'); 
const HtmlWebpackPlugin = require('html-webpack-plugin'); 
const CleanWebpackPlugin = require('clean-webpack-plugin'); 
const ExtractTextPlugin = require("extract-text-webpack-plugin"); 
const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); 

module.exports = { 

    entry: [ 
     'react-hot-loader/patch', 
     'webpack/hot/only-dev-server', 
     `${SRC_DIR}/index.js` 
    ], 
    output: { 
     path: DIST_DIR, 
     publicPath: '', 
     filename: 'bundle.js' 

    }, 

    module: { 
     rules: [ 
      { 
       test: /\.scss$/, 
       use: ExtractTextPlugin.extract({ 
        fallback: 'style-loader', 
        use: ['css-loader','sass-loader'] 
       }) 
      }, 
      { 
       test: /\.(png|svg|jpg|gif)$/, 
       use: ['file-loader'] 
      }, 
      { 
       test: /\.js?$/, 
       use: ['babel-loader'], 
       include: SRC_DIR 
      } 
      ] 
    }, 

    plugins: [ 
     new CleanWebpackPlugin(['dist']), 
     new HtmlWebpackPlugin({ 
      inject: false, 
      template: require('html-webpack-template'), 
      appMountId: 'root', 
      devServer: '0.0.0.0' +':'+ 8081, 
      title: "Webpack 4 React" 
     }), 
     new ExtractTextPlugin("styles.css"), 
     new webpack.HotModuleReplacementPlugin(), 
     new webpack.NamedModulesPlugin(), 
     new BrowserSyncPlugin({ 
      host: process.env.IP, 
      port: process.env.PORT, 
      //server: { baseDir: ['dist'] }, 
      ui: { 
       port: 8082 
      }, 
      proxy: process.env.IP +':'+ 8081 
     }, 
     { 
      reload: false 
     } 
     ) 
     ], 

    devtool: 'source-map', 

    devServer: { 
     publicPath:'', 
     host: process.env.IP, 
     port: 8081, 
     hot: true 
    } 
}; 

partie babel de package.json

"babel": { 
    "presets":["es2015","react"], 
    "plugins": ["react-hot-loader/babel"] 
} 

de nombreuses pièces en mouvement et des approches rendent cette chose difficile à épingler. mais je me sens comme même si ce n'est pas la configuration la plus optimale, je suis proche de l'obtenir au travail. après tout, ma page de synchronisation de navigateur obtient le json HMR du WDS. peut-être que j'ai juste manqué quelque chose de simple. une chose étrange est le concept de chemin public par exemple, je n'arrive pas à faire marcher ça à moins que ce soit une chaîne vide. Comme je l'ai dit c'est le premier jour avec webpack, j'ai encore beaucoup à apprendre ici. Merci.

je devrais probablement ajouter mes index.js, le point d'entrée pour webpack

import { AppContainer } from 'react-hot-loader'; 
import React from 'react'; 
import ReactDOM from 'react-dom'; 
import App from './Components/App'; 
import './styles.scss'; 

const root = document.getElementById("root"); 
//ReactDOM.render(<App/>,root); 

const render = Component => 
    ReactDOM.render(
    <AppContainer> 
     <Component /> 
    </AppContainer>, 
    root 
); 

render(App); 

if (module.hot) module.hot.accept('./Components/App',() => render(App)); 

Répondre

0

Pour donner suite j'ai des choses de travail, avec quelques modifications mineures au code ci-dessus. La première chose est dans index.js. Il me manquait une déclaration pour le nouveau composant mis à jour. Alors:

if (module.hot) module.hot.accept('./Components/App',() => render(App)); 

est remplacé par le texte suivant:

if (module.hot) module.hot.accept('./Components/App',() => { 
    const newApp = require("./Components/App").default; 
    render(newApp); 
}); 

Depuis que je suis en utilisant React et réagir à chaud chargeur, la magie est fait et mes changements prennent effet sans rechargement de la page et donc perdre Etat. Une mise en garde que j'ai trouvée est que si mes changements impliquent la création d'un constructeur et d'un état pour un composant qui provoquera un rechargement de page, mais cela a du sens.

J'ai également dû changer la façon dont j'ai traité scss fichiers. J'utilisais le ExtractTextPlugin. Après quelques recherches, j'ai trouvé que c'est mieux pour la production, et ne supporte pas l'HMR. Cela vient directement de Webpack Docs. Donc j'ai dû modifier mon webpack.config.js. Je commente l'utilisation du plugin dans ma section plugins et change ma règle scss à la suivante.

{ 
       test: /\.scss$/, 
       use: [ 
        { 
         loader: 'style-loader' 
        },{ 
         loader: 'css-loader' 
        },{ 
         loader: 'sass-loader' 
        } 
        ] 
       /* no HMR better for production 
       use: ExtractTextPlugin.extract({ 
        fallback: 'style-loader', 
        use: ['css-loader','sass-loader'] 
       })*/ 
      }, 

Ce qui précède est toute règle scss avec mes vieux trucs tout en commentaire je peux l'ajouter à un fichier de configuration de production webpack à l'avenir. Maintenant, il est sur le prochain, en apportant redux et réagir routeur.