express使用webpack热加载替换时候遇到的坑

来源:互联网 发布:创业软件中签号 编辑:程序博客网 时间:2024/04/29 17:51

问题1:

bundle.js:25  GET http://127.0.0.1:3000/public/assets/f4827a9158e0a42d64c7.hot-update.json 404 (Not Found)

保存componet文件时候提示hot-update.json文件404。

修复方案:

 Webpack 的文档如下

The publicPath specifies the public URL address of the output files when referenced in a browser.

需要把webpack.config.js下的publicPath改成绝对路径。修改如下:

    output: {
         path: '/',
        publicPath: 'http://127.0.0.1:3000/public/assets/',
        filename: 'bundle.js'
    },

但是我修改后仍然提示json 404。找了半天发现是静态路径的坑。在express中app.js设置如下:

app.use(express.static(path.join(__dirname, 'public')));

所以访问路径中public重复了,修改为 publicPath: 'http://127.0.0.1:3000/assets/',解决了问题


问题2:

提示:the following modules couldn't be hot updated (Full reload needed)

如下图:

这是入口文件没设置module.hot.accept()的锅。/(ㄒoㄒ)/~~

官方地址: http://webpack.github.io/docs/hot-module-replacement.html


问题3:

提示如下:

This usually means you called setState() on an unmounted component. This is a no-op 


参考修改链接为:http://www.cnblogs.com/wonyun/p/5889008.html

原因是:

发生在异步处理的情况下,例如事件或者异步请求的情况,这时在回调函数中调用component的setState方法时,可能会出现当前组件还没有mounted到dom中,此时调用该方法会报如下错误警告:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the LineSuggest component.

由于ES6下的react component是extends React.Component,所以component的isMount()方法不可用

虽然isMount()方法为一个反模式,不推荐;但是为了解决问题,为此网上有一些对应的解决方法,如下

  • componentDidMount函数中设置一个flag, 然后在componentWillUnMount中重置该flag,具体代码如下:

    componentDidMount(){    this.mounted = true; //flag    listener = document.body.addEventListener('click', ()=>{        if(this.mounted){            this.setState({open: false});        }    }, false)}componentWillUnMount(){    this.mounted = false; //重置flag    listener && document.body.removeEventListener('click', listener, false);}

    该种情况具体可以参考这里

  • hack一个isMount方法。
    由于React.findDOMNode(component)是在component mounted时才能正常使用的方法,否则会抛异常;所以利用这个情况可以hack一个方法,具体如下:

    function isMounted (component) {  // exceptions for flow control :(  try {React.findDOMNode(component);return true;  } catch (e) {// Error: Invariant Violation: Component (with keys: props,context,state,refs,_reactInternalInstance) contains `render` method but is not mounted in the DOMreturn false;  }  };
官网文章提示修改问题如下:

Just set a _isMounted property to true in componentDidMount and set it to false in componentWillUnmount, and use this variable to check your component's status.

说的好有道理。地址:https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html


app.js 相关代码:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');


var routes = require('./routes/index');
var users = require('./routes/users');


var app = express();


var webpack = require('webpack');


var webpackDevServer=require("webpack-dev-server")
var webpackMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware  = require('webpack-hot-middleware');
var config = require('./webpack.config.js');
var compiler = webpack(config);
app.use(webpackMiddleware(compiler,{
  publicPath: config.output.publicPath,
  noInfo: false,
  reload: true,
  stats: { colors: true }
})); 
app.use(webpackHotMiddleware(compiler,{
  log: console.log
}));


// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');


// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));


webpack.config.js相关代码:

 var webpack = require('webpack');
module.exports = {
    entry: [
    'webpack/hot/dev-server',
    'webpack-hot-middleware/client?http://0.0.0.0:3000',
      __dirname+'/public/assets/js/entry.js'
    ],
    output: {
         path: '/',
        publicPath: 'http://127.0.0.1:3000/public/assets/',
        filename: 'bundle.js'
    },
    // output: { 
    //     path: '/public/assets/',
    //     publicPath: '/public/assets/',
    //     filename: 'bundle.js'
    // },
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    module: {
        loaders: [
            {test: /\.js$/, loader: "jsx"},
            {test: /\.css$/, loader: "style!css"},
            {test: /\.(jpg|png)$/, loader: "url?limit=8192"},
            {test: /\.scss$/, loader: "style!css!sass"}
        ]
    }
};


entry.js相关代码

var React = require('react');
var Greet = require('./greet');


ReactDOM.render(
<Greet />,
document.getElementById('example')
)
module.hot.accept();

0 0
原创粉丝点击