问题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 DOM
return 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(
document.getElementById('example')
)
module.hot.accept();