原文
翻译
这个文件可以作为设置React Hot Loader的常见问题的repository,以及解决方案。知道一个问题?你可以随意提交一个PR。
它应该是什么样子?
页面加载时
保存一个文件时
如果您看不到某些message或某些request,或者某些requests失败,则表示配置不正确。将您的设置与React Hot Boilerplate进行比较可能会帮助您发现错误。
常见的TypeScript错误
如果您是TypeScript用户,使用HMR进行设置,将别名模块作为任何类似的东西并不罕见,像下面这样:
const anyModule = module as any; if (anyModule.hot) { anyModule.hot.accept('./app',() => render(App)); }
千万不要这样做!!每次进行更改时都会导致整页重新加载。你应该改成下面这种写法:
if ((module as any).hot) { (module as any).hot.accept('./app',() => render(App)); }
或者
declare const module: any; if (module.hot) { module.hot.accept('./app',() => render(App)); }
然后,你就能在控制台看到正确的输出了
[HMR] Updated modules: // ... [HMR] App is up to date.
不能build
1、Cannot resolve 'file' or 'directory' react/lib/ReactMount
如果你使用预编译的React而不是react npm包,React Hot Loader配置将需要一些调整。请参考 Usage with External React(链接好像已经不准确了)。
确保你的Webpack.config的resolve.extensions部分中有'.js',否则Webpack将无法在require中明确指定扩展名的情况下找到任何JS文件。
2、SyntaxError: 'import' and 'export' may only appear at the top level
如果您将React Hot Loader与Babel(ex 6to5)一起使用,请确保React Hot Loader停留在Webpack配置中的loaders数组中的Babel左边(这种写法在webpack2时代):
{ test: /\.jsx?$/,loaders: ['react-hot','babel'],include: path.join(__dirname,'src') }
Webpack将加载器从右到左,我们需要将Babel的输出提供给React Hot Loader,反之亦然。
3、Error: Invalid path './' (or similar)
如果您在Webpack配置中使用相对输出路径,请使用path.resolve():
var path = require('path'); module.exports = { ...,output: { path: path.resolve('./my-relative-path'),... } };
如果您使用了WebpackDevServer CLI模式,并且在切换到Node后崩溃,则会出现Error: Invalid path '',您可能没有在输出中指定任何路径。你可以把路径:__dirname放在那里,因为它对于开发配置无关紧要。
4、Module not found: Error: Cannot resolve module 'react-hot'
你可能使用了npm链接来在不同的文件夹中使用一个包的开发版本,而React Hot Loader错误地处理了它。您应该在加载程序配置中使用include,仅选择加载应用程序的文件。
页面引发的错误
Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined
Uncaught TypeError: Cannot read property 'env' of undefined
[socket.io] Cannot use 'in' operator to search for 'document' in undefined
确保你已经排除了:/node_modules/或者更好的办法是,在加载器配置中包含:path.join(__ dirname,'src')(路径取决于你的应用程序),就像这一行一样。您从不需要使用React Hot Loader处理node_modules。如果你使用其他的加载器如jsx?harmony或babel,那么他们很可能也需要包含指定的。
不能热更新
通常,解决这类错误的最好方法是认真的比较你的设置和React Hot Boilerplate,看看有什么不同。
尝试使用WebpackDevServer Node接口而不是CLI!
WebpackDevServer CLI模式的行为与Node API略有不同。如果有疑问,我建议你使用React Hot Boilerplate这样的Node API。
Uncaught RangeError: Maximum call stack size exceeded
当使用WebpackDevServer CLI标志--hot时,不应该再使用HotModuleReplacementPlugin(),反之亦然,它们是互斥的,但是所期望的效果将适用于它们中的任何一个。
No 'Access-Control-Allow-Origin' header is present on the requested resource.
如果您尝试从另一个端口上的URL访问Webpack Dev Server,则可以尝试:
更改WebpackDevServer选项以包含CORS头
new WebpackDevServer(webpack(config),{ publicPath: config.output.publicPath,hot: true,headers: { 'Access-Control-Allow-Origin': '*' } })
确保webpack.config.js中的webpack-dev-server客户端主机和端口与开发服务器的主机和端口匹配:
entry: [ 'webpack-dev-server/client?http://localhost:3000',// WebpackDevServer host and port 'webpack/hot/only-dev-server','./src/app' ]
以下模块不能热更新:(他们需要全部重新加载!)
如果在编辑根组件时出现此警告,这可能是因为您不会从中导出任何内容,并从那里调用React.render。把你的根组件放在一个单独的文件(例如App.jsx)中,并从index.js中调用React.render。
如果将根组件编写为无状态简单函数而不是使用React.Component,则还会在v1.x中获得此警告。这个问题已经在v3.x中完全解决了。
如果您编辑非组件文件所需的非组件文件,也可能会出现此警告。这意味着热门更新冒泡,但应用程序无法处理它。这个是正常的!只需刷新。
如果你得到这个警告和一个404的hot-update.json文件,你可能使用的是一个古老版本的webpack-dev-server(只是更新它)。
我看到“[WDS] Hot Module Replacement enabled”,但是当我编辑App.js时没有任何反应
如果您正在运行node 0.11.13,则可能需要尝试更新到0.12。有人说这有助于解决这个问题。还要确保你的需求与文件具有相同的文件名。有App.js和require('app')可能会在某些系统上启动监听。
OS X还有一个很少发生的错误,导致一些文件夹在文件系统更改监视方面“断开”。这里有一些建议的修复(已经不存在了)。
我看到“[HMR] Nothing hot updated.”,当我编辑App.js时没有任何反应
如果在入口配置选项中有几个入口点,请确保webpack/hot/only-dev-server位于每个入口点中:
entry: { app: ['./src/app','webpack/hot/only-dev-server'],editor: ['./src/editor',...,client: 'webpack-dev-server/client?http://localhost:3000' }
你不得不在你的主机页面中包含“client.js”以使热更新工作。例如:
<script src="/static/bundle-client.js"></script> <script src="/static/bundle-app.js"></script> <script src="/static/bundle-entry.js"></script>
没有webpack/hot/only-dev-server(或者如果你喜欢偶尔重载的webpack/hot/dev-server)的入口点将不知道如何应用热更新。
Syntax error: Unexpected token <
如果您将WebpackDevServer与Express等现有服务器结合使用,并在热更新中获取此错误消息,那是因为Webpack被配置为从当前主机名请求热更新。因此,如果您的Express服务器在8000上,并且Webpack配置中的publicPath配置为/build/,则会从http://localhost:8000/ build/请求热更新,您的情况由Express提供。相反,您需要将publicPath设置为指向WebpackDevServer正在运行的端口。例如,它可以是http://localhost:9000/build/。
没有足够的监听
验证您的系统中是否有足够的可用监听。如果此值太低,Webpack中的文件监听器将无法识别这些更改:
cat /proc/sys/fs/inotify/max_user_watches
将fs.inotify.max_user_watches=524288添加到/etc/sysctl.d/99-sysctl.conf,然后执行sysctl --system。 Ubuntu用户(可能还有其他用户):echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p。
hot-update.json文件的404错误
首先,确保你有最新版本的Webpack和Webpack Dev Server(> = 1.7是好的)。当没有更新可用时,早期版本使用404代码,所以在技术上不是一个错误。
现在,看看他们被请求的路径。 Webpack使用来自Webpack config的output.publicPath来确定这个路径。如果您忘记指定它,Webpack将请求从相对路径到当前路径的更新,所以任何客户端路由都会打断它。
通常情况下,如果你是从根服务脚本的话,你希望它是'/',如果你有一个脚本的虚拟路径,或者像'http://localhost:port/scripts/ 只使用Webpack的脚本,但有另一个主要的服务器,如Express。此配置变量还必须匹配创建WebpackDevServer实例时指定的publicPath选项。看看React Hot Boilerplate来获得一个想法。
其他问题
build变慢了!!
确保你已经包括限制在你的应用程序的模块在加载程序配置。您从不需要使用React Hot Loader处理node_modules。
我的build文件怎么这么大!!
确保你有独立的开发和生产配置。在生产配置中,您不需要在装载程序或webpack-dev-server/client或webpack/hot/only-dev-server中进行反应。他们只是为了发展。为了便于维护,您可以在调用Webpack之前设置环境变量并在config中读取它。
还要确保你在生产配置中有这些插件(在webpack3中,可能略有不同):
// 移除一下react源码中的debugging new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }),// 保持哈希在编译之间一致 new webpack.optimize.OccurrenceOrderPlugin(),// 压缩代码 new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false } })
哦,不要忘记从生产配置中删除devtool:'eval'。否则Uglify根本不会丑化任何东西。
我只能通过 / 刷新访问我的单页应用程序(SPA)
问题是,默认情况下,WebpackDevServer不能正确处理HTML5历史记录,并且服务器不会按照它应该的路由URL。你可以通过设置historyApiFallback:true来解决这个问题。这是一个完整的例子:
var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config'); var port = 4000; var ip = '0.0.0.0'; new WebpackDevServer(webpack(config),historyApiFallback: true,}).listen(port,ip,function (err) { if(err) { return console.log(err); } console.log('Listening at ' + ip + ':' + port); });
在此之后,您应该可以通过任何已经定义的网址访问您的SPA。
React Hot Loader: this component is not accepted by Hot Loader
问题在于React Hot Loader无法替换新版本的某个Component的旧版本。原因总是一样的 - 新旧组件相同的时候,React Hot Loader不能理解它。
为什么?组件不会被提取为顶级变量。只有这样的组件React Hot Loader才能消化。
const SuperComponent = connect()( <-- last HoC withSomeStuff( <-- first HoC Component <-- a real component ) );
SuperComponent是一个顶级变量。和组件是。但是,使用SomeStuff也会产生一个(时态的)组件,对于React Hot Loader是绝对不可见的。
const WithSomeStuffComponent = withSomeStuff(Component); const SuperComponent = connect()(WithSomeStuffComponent);
所以是的 - 使用高阶函数组合和React Hot Loader是不可行的。所有的时间变量,步骤,备件必须分开。(笔者本人也遇到了这个问题,刚好在这里找到了答案)