打包: webpack 代码分离
参考:webpack 代码分离
动态 import() 语法
import("./math").then(math => {
console.log(math.add(16, 26));
});
确保 Babel 能够解析动态 import 语法,需要使用 babel-plugin-syntax-dynamic-import
安装
npm install --save-dev @babel/plugin-syntax-dynamic-import
.babelrc
{
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
React.lazy
const OtherComponent = React.lazy(() => import('./OtherComponent'));
此代码将会在组件首次渲染时,自动导入包含 OtherComponent
组件的包。
React.lazy
接受一个函数,这个函数需要动态调用 import()
。它必须返回一个 Promise
,该 Promise 需要 resolve 一个 defalut
export 的 React 组件。
然后应在 Suspense
组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)。
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
异常捕获边界(Error boundaries)
如果模块加载失败(如网络问题),它会触发一个错误。你可以通过异常捕获边界(Error boundaries)技术来处理这些情况,以显示良好的用户体验并管理恢复事宜。
import MyErrorBoundary from './MyErrorBoundary';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
const MyComponent = () => (
<div>
<MyErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</MyErrorBoundary>
</div>
);
基于路由的代码分割
应用中使用 React.lazy
和 React Router 这类的第三方库,来配置基于路由的代码分割。
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);