我要迁移到Redux.
我的应用程序包含很多部分(页面,组件),因此我想创建许多reducer.Redux示例显示我应该使用combineReducers()生成一个reducer.
另外据我所知,Redux应用程序应该有一个商店,并在应用程序启动后创建它.在创建商店时,我应该通过我的组合减速机.如果应用程序不是太大,这是有道理的.
但是,如果我构建多个JavaScript包怎么办?例如,每个应用程序页面都有自己的包.我认为在这种情况下,一个联合减速器并不好.我查看了Redux的来源,并找到了replaceReducer()功能.这似乎是我想要的.
replaceReducer()当我在应用程序的各个部分之间移动时,我可以为我的应用程序的每个部分创建组合的reducer .
这是一个好方法吗?
在webpack 3配置中,我将使用下面的代码创建单独的vendor.js块:
entry: {
client: ['./client.js'],
vendor: ['babel-polyfill', 'react', 'react-dom', 'redux'],
},
output: {
filename: '[name].[chunkhash].bundle.js',
path: '../dist',
chunkFilename: '[name].[chunkhash].bundle.js',
publicPath: '/',
},
plugins: [
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime',
}),
],
Run Code Online (Sandbox Code Playgroud)
通过所有更改,我不知道如何使用Webpack 4.我知道这CommonChunksPlugin已被删除,因此有不同的方法来实现它.我也阅读了本教程,但我仍然不确定是否提取运行时块并正确定义output属性.
编辑: 不幸的是,我遇到了最流行的答案问题.看看我的答案.
几天前,我已将 Sentry 与我的网站集成,我注意到有时用户会在控制台中收到此错误:
ChunkLoadError: Loading chunk <CHUNK_NAME> failed.
(error: <WEBSITE_PATH>/<CHUNK_NAME>-<CHUNK_HASH>.js)
Run Code Online (Sandbox Code Playgroud)
因此,我调查了网络上的问题,发现了一些类似的情况,但与会话期间发布更新或缓存问题导致的丢失块有关。
这些情况和我的情况之间的主要区别在于,失败的块实际上可以从浏览器访问,因此加载错误并不取决于块哈希值的发布后刷新,而是(我猜)来自一些与网络相关的问题。这一统计数据强化了这一假设:大约 90% 的相关设备都是移动设备。
最后,我提出一个问题:我应该以某种方式管理这个问题(例如,如果失败则重试块加载),还是最好简单地忽略它并让用户手动刷新?
2021年9月28日编辑:
一个月后,问题仍然存在,但我没有收到用户的任何报告,而且我一直在使用 Hotjar 记录用户会话,但到目前为止尚未注意到任何相关内容。
我最近与 Sentry 支持人员进行了一次聊天,帮助我排除了与网络相关的假设:
我们的 React SDK 默认没有离线缓存,当捕获到错误时,它将在此时发送。如果应用程序无法连接到 Sentry 来发送事件,该事件将被丢弃,并且 SDK 不会尝试再次发送该事件。
哨兵鲁道夫
我可以确认这个问题很不寻常,我与您分享另一个有趣的统计数据:自第一次发生以来受影响的用户是332.227 名唯一访问者中的 882 名 (~0,26%),但我注意到90% 的事件来自 iOS(不是我一个月前注意到的通用移动设备),因此如果我计算 iOS 用户的相同比例(128.444 中的 794 名(882 名中的 90%)),我们接近 0.62%。虽然仍然很小,但在 iOS 上肯定更相关。
使用具有以下配置的split chunks插件:
{
entry: {
entry1: [entry1.js],
entry2: [entry2.js],
entry3: [entry3.js],
...
}
optimization: {
splitChunks: {
chunks: "all"
}
}
}
Run Code Online (Sandbox Code Playgroud)
代码将完美地分为:
vendors-entry1-entry2-entry3.js // common for all
vendors-entry1-entry3.js // vendors only required by both entry1, entry3
entry1-entry2.js // common code of entry1 and entry2
entry1.js // unique entry's code
entry2.js
entry3.js
Run Code Online (Sandbox Code Playgroud)
问题是,我现在如何在我的html中使用每个条目的特定供应商(或者在我的特定情况下使用ejs)?
使用HtmlWebpackPlugin建议只需创建一个index.html来加载上述所有内容,尽管用例很明显:
渲染entry1页面时 - 加载:
vendors-entry1-entry2-entry3.js
vendors-entry1-entry3.js
entry1-entry2.js
entry1.js
Run Code Online (Sandbox Code Playgroud)
渲染entry2页面时 - 加载:
vendors-entry1-entry2-entry3.js
entry1-entry2.js
entry2.js
Run Code Online (Sandbox Code Playgroud)
等等..
这是一个意外的问题,我遇到了Webpack代码在野外分裂:想象一下这种情况:
如何防止这种情况?
一种可能的解决方案是维护多个版本化的块集,但我想知道大型应用程序是否使用了更简单的解决方案.
如果使用了preload-webpack-plugin,则可以预取所有块,但它们只会在短时间内保持缓存(在Chrome中为5分钟).
如果我对我的角度应用程序进行更改,块名称将在构建时更改,旧版本将从dist文件夹中删除.一旦部署用户当前在该站点上然后导航到该站点的另一部分,我得到一个加载块失败错误,因为旧文件不再存在.
我的应用程序是使用角度cli构建的,因此它使用webpack打包.
无论如何,这是可以克服的.
使用webpack,如果我想对整个模块进行代码拆分,我可以更改
import Module from 'module'
在我的文件顶部
import('module').then(Module => {...
当我需要使用模块 ( docs ) 时。是否有可能做到这一点,但只有一个命名的导出?也就是说,我怎么能对以下内容进行代码拆分:
import {namedExport} from 'module'
我正在使用require.ensure在react-router路径创建分裂点.然而,我的build目录仍只具有app.js除vendor.js.我期待我使用的每个路径都有一个单独的js文件require.ensure.
我require.ensure在每条路径上使用过这样的:
<Route path= 'auth' getComponent={(nextState, callback) => {
require.ensure([], (require) => {
callback(null, require('containers/Authenticate/AuthenticateContainer.js').default)
}, 'auth')
}}/>
Run Code Online (Sandbox Code Playgroud)
我的构建的web包配置输出如下所示:
output: {
path: PATHS.build,
filename: '/[name].[chunkhash].js',
chunkFilename: '/[chunkhash].js'
}
Run Code Online (Sandbox Code Playgroud)
以下是我的路径文件和我的webpack配置文件的全部内容.
更新: 我弄清楚我做错了什么.我的容器项目结构如下:
-app
-containers
-containerA.
-containerA.js
-containerB
-containerB.js
-containerC
-containerC.js
-index.js
Run Code Online (Sandbox Code Playgroud)
问题:我仍然在路由文件中导出我需要的容器,如下所示:从'./containerB/containerB'导出containerB'删除index.js中的导出并直接从containerB.js中执行操作.
我们将完全使用React构建我们的新网站,并利用代码拆分和scss。每当请求新页面时,它首先将原始HTML加载到浏览器中,然后瞬间加载CSS样式,这似乎是一个FOUC问题。这带来了可怕的体验,我们需要弄清楚如何在渲染组件之前确保CSS已加载。有人对这个有经验么?当前,此问题似乎缺少在线信息。我们目前有10个js块,但只有一个main.XXXXXXX.css。
因为我们可以导入如下样式表:
<link rel="stylesheet" media="screen and (min-width: 900px)" href="widescreen.css">
<link rel="stylesheet" media="screen and (max-width: 600px)" href="smallscreen.css">
Run Code Online (Sandbox Code Playgroud)
这将通过仅加载符合media属性条件的css文件来帮助更快地加载网站.MDN
我没有运气搜索可以拆分查询的webpack配置,或者至少让我手动指定哪个css条目应该在哪个媒体上加载.
我唯一的解决方案是编写nodejs脚本并index.html在构建时注入,但在我看来这不是干净的方法.
那么有什么webpack配置这种东西?
code-splitting ×10
webpack ×8
javascript ×6
reactjs ×4
angular ×1
bundle ×1
console.log ×1
css ×1
deployment ×1
flux ×1
lazy-loading ×1
node.js ×1
react-router ×1
redux ×1
rendering ×1
sass ×1
webpack-4 ×1