React系列——react-hot-loader bug排除指南翻译

原文

react-hot-loader故障排除指南

翻译

这个文件可以作为设置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是不可行的。所有的时间变量,步骤,备件必须分开。(笔者本人也遇到了这个问题,刚好在这里找到了答案)

PS:有可能创建一个babel插件,它将提取所有的东西。但谁来创造它呢?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom