我使用react-loadable一段时间来动态导入我的React组件.
在最近的React版本16.6中,React团队已经包含
React.lazy()了动态导入.
使用该react-loadable软件包还有什么好处,或者是时候转移到新的React版本了吗?
我已经在我的项目中成功添加了可加载反应的库来启用代码分割,我发现的唯一问题是webpack生成的块没有命名,它们被赋予整数名称.
我的反应可加载代码是
const AppRootLoadable = Loadable({
loader: () => import(/* webpackChunkName: "app" */ './App'),
loading: () => null,
render(loaded) {
const Component = loaded.default;
return <Component />;
},
});
Run Code Online (Sandbox Code Playgroud)
我已添加评论告诉webpack 3我希望这个块被命名为app.我做错了什么吗?
我想用服务器端渲染拆分我的反应代码。为此,我有两个选择。
React 文档建议对服务器渲染的应用程序使用可加载组件。但它每周的 NPM 下载量很少。
与之前的相比,该软件包的 NPM 每周下载量非常高,但根据loadable-components文档,该软件包不再维护。
react-loadable 长期以来一直是 React 代码拆分的推荐方式。但是,今天它不再维护,并且与 Webpack v4+ 和 Babel v7+ 不兼容。文档链接
请用适当的包裹来引导我。
这基本上都是我的代码.我正在运行Hapi并尝试使用react-loadable来服务器渲染我的React应用程序.
我在这里为代码添加了很多缺失的部分.
const location = req.url.pathname
const context = {}
const modules = []
const Router = () => (
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/me" component={Profile} />
<Route component={NotFound} />
</Switch>
)
const App = () => (
<StaticRouter location={location} context={context}>
<main>
<Header />
<Router />
<Footer />
</main>
</StaticRouter>
)
const preloadables = [ Home, Login, Profile, NotFound ]
await Promise.all(preloadables.map(preloadable => preloadable.preload()))
const html = ReactDOMServer.renderToString(
<Loadable.Capture report={moduleName => …Run Code Online (Sandbox Code Playgroud) 使用时react-loadable,这些异步组件中引发的错误(例如错误的导入)不会轻易提醒您。
我希望能够在开发环境中禁用react-loadable(绕过它,并同步加载所有内容)并在生产环境中启用它,但是我不知道如何重写react-loadable来完成这项工作:
import Loadable from 'react-loadable';
import LoadingComponent from './Loading';
// My reused loadable component everywhere
// In production
export default options =>
Loadable({
loading: LoadingComponent,
delay: 200,
...options,
});
// Ideally a dev version that skips loadable
// In development, without any async import
export default options => options.loader(); // Does not work
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
我遇到了一个问题,试图通过使用我的反应APP中使用块
反应可装载
它在开发模式下的webpack-dev-server中工作得很好,但是当我构建项目并将其提供给服务器时,异步组件已加载,但其中的代码未被执行.所以页面只是使用加载器进行渲染,这些加载器应该被渲染,直到加载组件.控制台或其他东西没有错误,一切都很清楚,块脚本插入到负载的html头,没有任何反应:(
Example async component
import Loadable from 'react-loadable';
const AsyncComponent = Loadable({
loader : () => (import('../../components/AsyncComponent')),
loading : () => (<div>Loading....</div>),
});
Run Code Online (Sandbox Code Playgroud)
并呈现
<Route path="/path/to/asynccomponent" render={() =>(<AsyncComponent />)} />
Run Code Online (Sandbox Code Playgroud)
UPD:传递给加载组件的错误TypeError:无法在o处读取undefined↵的属性'call'(http:// localhost:3000/assets/js/bundle-8866517f8f287a1d3c6b.js:1:318
通过安装修复它
巴贝尔-插件语法动态导入
并将exctractCssPlugin选项更新为
new exctactCss({filename:'css/style.css',allChunks:true})
请在标记为重复之前正确阅读此内容,我向您保证我已经阅读并尝试了每个人在 stackoverflow 和 github 上提出的有关此问题的所有建议。
我的应用程序中有一条路由,如下所示;
<div>
<Header compact={this.state.compact} impersonateUser={this.impersonateUser} users={users} organisations={this.props.organisations} user={user} logOut={this.logout} />
<div className="container">
{user && <Route path="/" component={() => <Routes userRole={user.Role} />} />}
</div>
{this.props.alerts.map((alert) =>
<AlertContainer key={alert.Id} error={alert.Error} messageTitle={alert.Error ? alert.Message : "Alert"} messageBody={alert.Error ? undefined : alert.Message} />)
}
</div>
Run Code Online (Sandbox Code Playgroud)
路由渲染Routes呈现一个切换用户角色的组件,并根据该角色延迟加载正确的路由组件,该路由组件为主页呈现一个开关。简化后如下所示。
import * as React from 'react';
import LoadingPage from '../../components/sharedPages/loadingPage/LoadingPage';
import * as Loadable from 'react-loadable';
export interface RoutesProps {
userRole: string;
}
const Routes = ({ userRole }) => { …Run Code Online (Sandbox Code Playgroud) 我正在使用 NextJS 和 Fullcalendar。
我尝试fullcalendar在这个例子中使用动态导入(有关更多信息,这个示例解决方案来自这里)。
它奏效了,但有一个问题。几乎每 5 次刷新尝试中就有 1 次以错误告终Please import the top-level fullcalendar lib before attempting to import a plugin(就像这样,但在我的情况下版本是正确的)
之后,我发现 next/dynamic 的模块选项已被弃用。我认为这是我的问题的根源(我不确定 100%,但至少它已被弃用并需要更新)。
正如文档所说,处理动态导入的新方法是这样的:
const DynamicComponent = dynamic(() =>
import('../components/hello').then((mod) => mod.Hello)
)
Run Code Online (Sandbox Code Playgroud)
但是因为我们需要多次导入,所以我找到了这个解决方案。
目前,似乎一切正常,但我的代码无效。
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import "@fullcalendar/common/main.css"; // @fullcalendar/react imports @fullcalendar/common
import "@fullcalendar/daygrid/main.css"; // @fullcalendar/timegrid imports @fullcalendar/daygrid
import "@fullcalendar/timegrid/main.css"; // @fullcalendar/timegrid is a …Run Code Online (Sandbox Code Playgroud) 目标:支持基于某些安全性或定义的用户角色要求的动态加载Javascript模块,这样,即使在开发工具中标识了模块名称,也无法通过控制台成功导入。
可以轻松地将JavaScript模块上载到Firebase(#AskFirebase)之类的云存储服务,并且可以firebase.functions().httpsCallable("ghost");基于自定义声明或类似测试的使用Firebase Cloud Function有条件地检索代码。
export const ghost = functions.https.onCall(async (data, context) => {
if (! context.auth.token.restrictedAccess === true) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
}
const storage = new Storage();
const bucketName = 'bucket-name.appspot.com';
const srcFilename = 'RestrictedChunk.chunk.js';
// Downloads the file
const response = await storage
.bucket(bucketName)
.file(srcFilename).download();
const code = String.fromCharCode.apply(String, response[0])
return {source: code};
})
Run Code Online (Sandbox Code Playgroud)
...将一个Webpack的React组件放入云端,在服务器端进行安全检查后有条件地将其下载到客户端,然后将import()其下载到用户的客户端环境中并进行渲染。
将Javascript存储在云中并有条件地下载到客户端很容易。在客户端中有了webpack的代码后,就可以像Function(downloadedRestrictedComponent)将其使用时那样将其添加到用户环境中,import('./RestrictedComponent')但是我不知道是如何从组件中获取默认导出的,以便我可以实际渲染事情。
import(pathToComponent)返回加载的模块,据我所知,没有选项传递import()字符串或流,而只是传递模块的路径。并且Function(downloadedComponent) …
我们使用反应和反应可加载.
在我们的应用程序初始化期间,我们将验证该component.preload方法是否存在于<Route />我们定义的每个方法.
如果缺少该方法,我们会显示一条警告,指出该组件应该是可加载的.
我们使用webpack 4,有没有办法自动包装组件,所以我们不必手动完成它?
这是组件的外观:
/** MyComponent.js: page component */
export default () => <div>Hello world</div>;
Run Code Online (Sandbox Code Playgroud)
这是包含在可反应加载组件中的相同组件:
/**
* preconfigured react-loadable
* See https://github.com/jamiebuilds/react-loadable#how-do-i-avoid-repetition)
*/
import MyLoadable from '@scopped/react-loadable';
/** loadable component */
export default MyLoadable({
loader: () => import('./MyComponent'), /** import page component */
});
Run Code Online (Sandbox Code Playgroud)
<Route />中声明node_modules.<Resource />(来自react-admin)而不是声明<Route />react-loadable ×10
reactjs ×9
webpack ×6
javascript ×4
firebase ×1
fullcalendar ×1
import ×1
next.js ×1
node.js ×1
react-dom ×1
react-router ×1
typescript ×1