如何实现 React 模块动态导入 |
您所在的位置:网站首页 › react动态加载组件 › 如何实现 React 模块动态导入 |
如何实现 React 模块动态导入
React 模块动态导入 webpack & code splitting https://reactjs.org/docs/code-splitting.html https://zh-hans.reactjs.org/docs/code-splitting.html Code-Splitting 可以创建多个可在运行时动态加载的包 https://webpack.js.org/guides/code-splitting/ https://rollupjs.org/guide/en/#code-splitting https://github.com/browserify/factor-bundle 虽然您并未减少应用程序中的全部代码量,但避免了加载用户可能永远不需要的代码,并减少了初始加载过程中所需的代码量。 https://create-react-app.dev/docs/code-splitting/ https://nextjs.org/docs/advanced-features/dynamic-import React.lazy and Suspense are not yet available for server-side rendering. code-splitting & server-side rendering https://github.com/gregberge/loadable-components https://loadable-components.com/docs/server-side-rendering/ React.lazyReact.lazy 函数让你可以可以像导入将常规组件一样的渲染一个动态导入。 import OtherComponent from './OtherComponent'; // React.lazy const OtherComponent = React.lazy(() => import('./OtherComponent'));首次呈现此组件时,它将自动加载包含OtherComponent的捆绑包。 React.lazy 采用了必须调用动态 import()的函数。 这必须返回一个 Promise,该 Promise 解析为一个带有默认导出的模块,该模块包含一个 React组件。 然后,应该将懒惰的组件呈现在Suspense组件中,这使我们可以在等待懒惰的组件加载时显示一些后备内容(例如加载指示符)。 import React, { Suspense } from 'react'; const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( ); }fallback prop 支持在等待组件加载时接受要渲染的任何React元素 您可以将 Suspense 组件放置在 lazy 组件上方的任何位置 您甚至可以用一个 Suspense 组件包装多个惰性组件。 import React, { Suspense } from 'react'; const OtherComponent = React.lazy(() => import('./OtherComponent')); const AnotherComponent = React.lazy(() => import('./AnotherComponent')); function MyComponent() { return ( ); } Error boundaries错误边界 如果另一个模块无法加载(例如,由于网络故障),它将触发错误 您可以处理这些错误,以显示良好的用户体验,并通过错误边界管理恢复 创建错误边界后,您可以在惰性组件上方的任何位置使用它来在出现网络错误时显示错误状态。 import React, { Suspense } from 'react'; import MyErrorBoundary from './MyErrorBoundary'; const OtherComponent = React.lazy(() => import('./OtherComponent')); const AnotherComponent = React.lazy(() => import('./AnotherComponent')); const MyComponent = () => ( );https://reactjs.org/docs/error-boundaries.html Route-based code splitting基于路由的代码拆分 React Router & React.lazy 确定在应用程序中的何处引入代码拆分可能有些棘手 您要确保选择的位置能够平均拆分捆绑包,但不会破坏用户体验 路线是一个不错的起点 网络上的大多数人习惯了页面过渡,需要花费一些时间来加载 您还倾向于一次重新渲染整个页面,因此您的用户不太可能同时与页面上的其他元素进行交互 这是一个示例,说明如何使用带有 React.lazy 的 React Router 等库将基于路由的代码拆分为您的应用。 import React, { Suspense, lazy, } from 'react'; import { BrowserRouter as Router, Route, Switch, } from 'react-router-dom'; const Home = lazy(() => import('./routes/Home')); const About = lazy(() => import('./routes/About')); const App = () => ( );https://reactjs.org/docs/code-splitting.html#route-based-code-splitting react-router https://reacttraining.com/react-router/ Named Exports命名的导出 React.lazy 当前仅支持默认导出 如果要导入的模块使用命名的导出,则可以创建一个中间模块,将其重新导出为默认模块 这样可以确保摇树不停,并且不会拉扯未使用的组件 // ManyComponents.js export const MyComponent = /* ... */; export const MyUnusedComponent = /* ... */; // MyComponent.js // 中间模块, 导出为默认模块 export { MyComponent as default } from "./ManyComponents.js"; // MyApp.js import React, { lazy } from 'react'; const MyComponent = lazy(() => import("./MyComponent.js")); webpackhttps://webpack.js.org/guides/code-splitting/ module.exports = { entry: { main: './src/app.js', }, output: { // `filename` provides a template for naming your bundles (remember to use `[name]`) filename: '[name].bundle.js', // `chunkFilename` provides a template for naming code-split bundles (optional) chunkFilename: '[name].bundle.js', // `path` is the folder where Webpack will place your bundles path: './dist', // `publicPath` is where Webpack will load your bundles from (optional) publicPath: 'dist/' } };https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269 webpack & magic-commentshttps://webpack.js.org/api/module-methods/#magic-comments https://webpack.docschina.org/api/module-methods/#magic-comments // Single target import( /* webpackChunkName: "my-chunk-name" */ /* webpackMode: "lazy" */ /* webpackExports: ["default", "named"] */ 'module' ); // Multiple possible targets import( /* webpackInclude: /\.json$/ */ /* webpackExclude: /\.noimport\.json$/ */ /* webpackChunkName: "my-chunk-name" */ /* webpackMode: "lazy" */ /* webpackPrefetch: true */ /* webpackPreload: true */ `./locale/${language}` ); import(/* webpackIgnore: true */ 'ignored-module.js'); babelhttps://babeljs.io/ https://classic.yarnpkg.com/en/package/@babel/plugin-syntax-dynamic-import $ yarn add -D @babel/plugin-syntax-dynamic-importhttps://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import $ npm i -D @babel/plugin-syntax-dynamic-import { "plugins": ["@babel/plugin-syntax-dynamic-import"] } // webpack config const config = { entry: [ "core-js/modules/es.promise", "core-js/modules/es.array.iterator", path.resolve(__dirname, "src/main.js"), ], // ... }; // or // src/main.js import "core-js/modules/es.promise"; import "core-js/modules/es.array.iterator"; // ...https://babeljs.io/blog/2019/07/03/7.5.0#dynamic-import-9552httpsgithubcombabelbabelpull9552-and-10109httpsgithubcombabelbabelpull10109 https://www.npmjs.com/package/babel-plugin-dynamic-import-node https://github.com/airbnb/babel-plugin-dynamic-import-node $ yarn add -D babel-plugin-dynamic-import-node.babelrc { "plugins": ["dynamic-import-node"] } dynamic importhttps://webpack.js.org/guides/code-splitting/#dynamic-imports import("./emoji-component").then(emoji => { // 使用 promise console.log(emoji)); }); 切换路由react-router lazy-load延迟加载 / 懒加载 code splitting & dynamic importimport()类似函数的形式将模块名称作为参数,并返回一个Promise,该Promise始终解析为模块的名称空间对象 https://github.com/tc39/proposal-dynamic-import http://2ality.com/2017/01/import-operator.html#loading-code-on-demand https://create-react-app.dev/docs/code-splitting/ const moduleA = `ESM (code splitting & dynamic import)`; export { moduleA };这将使 moduleA.js 及其所有唯一依赖项成为单独的块,仅在用户单击“加载”按钮后才加载 import React, { Component } from 'react'; class App extends Component { handleClick = () => { import('./moduleA') .then(({ moduleA }) => { // Use moduleA }) .catch(err => { // Handle failure }); }; render() { return ( Load ); } } export default App;async / await & promise 如果愿意,还可以将其与 async / await 语法一起使用 // async / await async handleClick = () => { const moduleA = await import('./moduleA'); moduleA.then(({ moduleA }) => { // Use moduleA }) .catch(err => { // Handle failure }); };chunks https://create-react-app.dev/docs/production-build refs ©xgqfrms 2012-2020www.cnblogs.com 发布文章使用:只允许注册用户才可以访问! |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |