7

Tôi đang chạy một máy chủ tốc hành sẽ hoạt động như một API cho ứng dụng React của tôi đang được gói và phục vụ bởi webpack-dev-server.Thay thế mô-đun nóng - Đang cập nhật nhưng không hiển thị lại

tôi đang cố gắng để có được sự thay thế mô-đun nóng để làm việc, và tôi gần như ở đó, khi tôi thực hiện thay đổi các tập tin của tôi, tôi có được điều này trong bảng điều khiển

Console output of HMR

Nhưng ứng dụng này là không bao giờ tái -kết thúc, trừ khi được làm mới theo cách thủ công. Không biết nếu điều này có liên quan, nhưng khi tôi cập nhật các tệp .scss của mình, nó sẽ làm mới mà không cần làm như vậy và cập nhật như tôi mong đợi.

phiên bản:

"webpack": "2.1.0-beta.22"

"webpack-dev-server": "2.1.0-beta.8"

"react-hot-loader": "3.0.0-beta.5"

Tôi đã thử các webpack mới nhất nhưng nó đã cho tôi lỗi xác nhận rằng không thể được khắc phục.

Tôi đang chạy webpack qua: "webpack": "webpack-dev-server --port 4000 --env.dev" và máy chủ tốc hành của tôi đang được chạy trên http://localhost:3000.

Đây là tôi webpack.config.babel.js:

const webpack = require('webpack'); 
const { resolve, join } = require('path'); 
const { getIfUtils, removeEmpty } = require('webpack-config-utils') 

const getEntry = (ifDev) => { 
    let entry 

    if (ifDev) { 
    entry = { 
     app: [ 
     'react-hot-loader/patch', 
     'webpack/hot/dev-server', 
     'webpack-dev-server/client?http://localhost:4000/', 
     './js/index.js' 
     ], 
     vendor: ['react'] 
    } 
    } else { 
    entry = { 
     bundle: './js/index.js', 
     vendor: ['react'] 
    } 
    } 

    return entry 
} 

const config = env => { 
    const { ifProd, ifDev } = getIfUtils(env) 

    return { 
    entry: getEntry(ifDev), 
    output: { 
     path: resolve('./public/dist/'), 
     publicPath: 'http://localhost:4000/', 
     filename: '[name].bundle.js', 
    }, 
    context: resolve(__dirname, 'assets'), 
    devtool: env.prod ? 'source-map' : 'eval', 
    devServer: { 
     contentBase: resolve('./public/dist/'), 
     headers: { 'Access-Control-Allow-Origin': '*' }, 
     publicPath: 'http://localhost:4000/', 
     hot: true, 
     noInfo: true, 
     inline: true 
    }, 
    bail: env.prod, 
    module: { 
     loaders: [ 
     { test: /\.scss$/, loaders: [ 'style', 'css', 'sass' ], exclude: /node_modules|lib/ }, 
     { test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'babel-loader' ] }, 
     { test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'file-loader' } 
     ] 
    }, 
    resolve: { 
     extensions: ['.js', '.jsx'] 
    }, 
    plugins: removeEmpty([ 
     ifDev(new webpack.NoErrorsPlugin()), 
     ifDev(new webpack.NamedModulesPlugin()), 
     ifDev(new webpack.HotModuleReplacementPlugin()), 

     new webpack.DefinePlugin({ 
     'process.env': { NODE_ENV: JSON.stringify((env.prod) ? 'production' : 'development') } 
     }), 
     new webpack.optimize.CommonsChunkPlugin({ 
     name: 'vendor', 
     minChunks: Infinity, 
     filename: 'vendor.bundle.js' 
     }), 

     ifProd(new webpack.LoaderOptionsPlugin({ 
     minimize: true, 
     debug: false 
     })), 
     ifProd(new webpack.optimize.UglifyJsPlugin({ 
     compress: { warnings: false }, 
     output: { comments: false }, 
     sourceMap: false 
     })) 
    ]), 
    } 
} 

module.exports = config 

Đây là tôi .babelrc, nơi tôi gọi react-hot-loader

{ 
    "presets": [["es2015", { modules: false }], "stage-0", "react"], 
    "plugins": ["react-hot-loader/babel"], 
    "env": { 
    "test": { 
     "plugins": ["istanbul"], 
     "presets": ["es2015", "stage-0", "react"] 
    } 
    }, 
    "sourceMaps": "inline" 
} 

Trả lời

4

Với Phản ứng nóng Loader v3 và Babel chuyển đổi, bạn muốn làm điều này trong thư mục gốc của thành phần của bạn (nơi bạn làm render của bạn, hoặc trong trường hợp bạn tạo cung cấp Redux của bạn):

render(
    <AppContainer> 
    <Root 
     store={ store } 
    /> 
    </AppContainer>, 
    document.getElementById('root') 
); 

if (module.hot) { 
    module.hot.accept('./containers/Root',() => { 
    const RootContainer = require('./containers/Root').default; 
    render(
     <AppContainer> 
     <RootContainer 
      store={ store } 
     /> 
     </AppContainer>, 
     document.getElementById('root') 
    ); 
    }); 
} 

Với sự phiên bản mới của Hot Loader, bạn phải chấp nhận một cách rõ ràng bản cập nhật nóng với module.hot.accept.

Trong một dự án Redux phức tạp hơn (với định tuyến và gia giảm tải lại nóng), bạn có thể làm một cái gì đó như thế này:

/** 
* Starts the React app with the Router, and renders it to the given DOM container 
* @param {DOMElement} container 
*/ 
export default function app(container) { 
    const store = createStore(
    combineReducers({ 
     ...reducers, 
     routing: routerReducer, 
     form: formReducer, 
    }), 
    compose(
     applyMiddleware(
     routerMiddleware(hashHistory), 
     thunkMiddleware, 
     promiseMiddleware 
    ), 
     process.env.NODE_ENV !== 'production' && window.devToolsExtension ? window.devToolsExtension() : (param) => param 
    ) 
); 

    if (module.hot) { 
    module.hot.accept('./reducers',() => { 
     const nextReducers = require('./reducers'); 
     const nextRootReducer = combineReducers({ 
     ...nextReducers, 
     routing: routerReducer, 
     form: formReducer, 
     }); 
     store.replaceReducer(nextRootReducer); 
    }); 
    } 

    const history = syncHistoryWithStore(hashHistory, store); 

    render({ store, history, container }); 

    store.dispatch(loadEventsWhenLoggedIn()); 

    if (module.hot) { 
    module.hot.accept('./render',() => { 
     const newRender = require('./render').default; 
     newRender({ store, history, container }); 
    }); 
    } 
} 

(và render.js)

/** 
* Starts the React app with the Router, and renders it to the given DOM container 
* @param {DOMElement} container 
*/ 
export default function render({ store, history, container }) { 
    ReactDOM.render(
    <Provider store={store}> 
     <div className='container'> 
     <Routes history={history} store={store} /> 
     </div> 
    </Provider>, 
    container 
); 
} 

Để biết thêm ví dụ, bạn nên có một cái nhìn tại Redux Dan Abramov của DevTools dụ repo, ví dụ tập tin này: https://github.com/gaearon/redux-devtools/blob/master/examples/todomvc/index.js

2

HMR hoạt động tự động cho CSS vì style-loader hỗ trợ mà out-of-the-box.

Với React không phải như vậy. Bạn cần react-hot-loader.

Install nó với NPM, và thay đổi này:

{ test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'babel-loader' ] }, 

Để:

{ test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'react-hot-loader', 'babel-loader' ] }, 

Nếu bạn muốn biết nhiều hơn, tôi khuyên bạn nên đọc "Webpack’s HMR & React-Hot-Loader — The Missing Manual".

+1

Tôi quên để thêm '.babelrc' của tôi, nơi tôi kêu gọi' react- hot-loader' trong '3.X' nó khuyến khích bạn di chuyển nó từ cấu hình của bạn để babel. – speak

Các vấn đề liên quan