navigation

[react] Hooks

[React from zero practice 01- background] code split [React from zero practice 02- background] permission control [React from zero practice 03- background] custom hooks [React from zero practice 04- background] docker-compose Deploy React + Egg +nginx+mysql [React From zero practice 05- background] Gitlab-CI using Docker automated deployment

[source code – Webpack01 – precompiler] AST abstract syntax tree [source code – Webpack02 – Precompiler] Tapable [source code – Webpack03] hand written webpack-compiler simple compilation process [source code] Redux React-redux01 [source] Axios [source] vuex [source -vue01] Data reactive and initialize render [source -vue02] Computed responsive – Initialize, access, Update Procedure [source -vue04] Watch Listening properties – Initialize and update [source -vue04] vue. set and vm.$set [source -vue05] vue.extend

Vue. NextTick and VM.$nextTick

[Deployment 01] Nginx [Deployment 02] Docker deployVue project [Deployment 03] gitlab-CI

[Deep 01] Execution context [Deep 02] Prototype chain [Deep 03] Inheritance [Deep 04] Event loop [Deep 05] Curri Bias function [Deep 06] Function memory [Deep 07] Implicit conversions and operators [Deep 07] Browser caching mechanism (HTTP caching mechanism) [Deep 08] Front-end security [Deep 09] Deep copy [Deep 10] Debounce Throttle [Deep 10] Front-end routing [Deep 12] Front-end modularization [Deep 13] Observer mode Publish subscribe mode Bidirectional data binding [Deep 14] Canvas [Deep 15] webSocket Webpack HTTP and HTTPS CSS- Interview Handwriting Promise algorithms – Find and sort

Front knowledge

Some words

Automatic delimiter lighthouse priority vendor third party Suspense fallbackCopy the code

(1) Why do code splitting

  • (A file) split into (B file, C file)
  • Load A 2MB file A, and load two 1MB files B and C. Due to asynchronous and parallel loading, it may be faster to load after splitting
  • When changing the code, only A small part of the code is changed, and the whole file A is repackaged to generate A new file A', the client has to reload the whole file A'; After code splitting, if the modified code is in file B, only file B needs to be repackaged, and the client only needs to reload file B, and file C will be cached
  • You can also do on-demand loading, lazy loading, route lazy loading, solve the white screen, and ultimately improve performance

(2) Three angles of code segmentation

  • Split into (business code – often changing) and (third party dependency code – almost constant)
    • The business code will change with the iteration of requirements, etc., while the third party dependency package is basically the same, so you can split the third party dependency package separately, such as vender.js, which is basically the same. After the code is released, the user side does not reload the code, but the browser will automatically cache it
  • Routes are cut according to routes, that is, routes are lazily loaded
    • For example, when entering the route of the home page, only the part of the code of the home page needs to be loaded
    • (The home page has dependencies on other modules. Synchronous imports can also be broken into more granular packages. Dynamic imports can be dynamically loaded and split through the import() function
  • Cut according to components
    • The code is cut according to routing mode. If component A contains COMPONENT C and component B also contains component C, the two packages respectively contain the code of component C, resulting in redundancy.
    • Cutting the code into components avoids the above problems, but the problem is that the number of packages increases dramatically, requiring developers to weigh the pros and cons themselves.

(3) the import (specifiers) function

  • When import loads modules, it is not possible to load modules at runtime like require, so with the import() proposal, modules are loaded dynamically

  • Parameter: path of the module

  • Return value: returns a PROMISE object

  • Application:

    • Load on demand: Load modules when needed
    • Conditional loading: Performs conditional loading in if statements
    • Dynamic module path: Allows module paths to be generated dynamically
  • Note:

    • Import () returns a Promise instance object that, when loaded successfully,Module objectAs a.then()methodsparameter, can be passedDeconstruction assignmentGet output interface
    • If the module has a default output interface, you can directly obtain the default interface through parameters, that is.then(moudle => module.default)
    • By loading multiple modules
    • When Webpack parses into the import() syntax, code splitting is done automatically. If you use the Create React App, it’s out of the box and you can use the feature right away. You can also configure WebPack yourself
    • When using Babel, you want to make sure that Babel can parse dynamic import syntax rather than transform it. For this you need @babel/ plugin-syntactic -dynamic-import
import(/* webpackChunkName: "AsyncTest" */'.. /.. /components/async-test') .then(({ default: AsyncTest }) => { ... }).catch(err => console.log(err)) load asynchronously, load dynamically (import()) - Code split how to name the package 1. /* webpackChunkName: "AsyncTest" */ 2. Use the @babel/ plugin-syntactic -dynamic-import plugin to write the magic comment 3 above. In new projects created via create-react-app => Babel-preset -react-app dependency => @babel/preset-env dependency => @babel/plugin-syntax-dynamic-import Synchronous load (import) - Code split how to name package 1. Configure the package name by setting Optimization => splitchunks => cashGroupsCopy the code

(4) webpack => optimization

  • For projects built with WebPack
    • For modules imported synchronously, code splitting requires the configuration of optimity.splitchunks
    • Modules imported asynchronously (import()) do not require any configuration
  • optimization.splitchunks
    • automaticNameDelimiter:
      • Specifies the connection of the split package,Source group name Connection entry name(E.g. vendors~main.js)
      • The default is~
    • maxAsyncRequests
      • Maximum number of concurrent requests when loading on demand. Default is 30
    • maxInitialRequests
      • Entry maximum number of parallel requests, default 30
    • chunks:
      • A string or a function
      • String, the valid value isall.asyncandinitial, all indicates that both synchronous and asynchronous modules are split
      • Function specifies which modules need to be split
      • Chunks need to be paired with cashGroups
    • cacheGroups
      • Priority: Defines the priority of each group
        • When a module meets multiple group rules, the module is packaged into a file with high priority
        • A larger number indicates a higher priority. The default value of the default group is negative, and the default value of the custom group is 0
      • Filename: indicates the name of the packed module
      • ReuseExistingChunk: Boolean
        • If module A was introduced in A previous module and packaged, and now module A is introduced, the previously packaged A is reused
    • minChunks(maxChunks)
      • The minimum number of references to whether a module is split, that is, at least how many times the module is referenced before it is split
    • minSize(maxSize)
      • Minimum size (in bytes) of whether or not a module is split
  • Website shows
  • SplitChunksPlugin
The default configuration item for optimity.splitchunks is: module.exports = {//... Optimization: {splitChunks: {chunks: 'all', all async initial minSize: {splitChunks: {chunks: 'all', MinRemainingSize: 0, maxSize: 0, // RemainingSize: 0, maxSize: 0 MaxAsyncRequests: (maxAsyncRequests) maxAsyncRequests: (maxInitialRequests) (maxAsyncRequests) AutomaticNameDelimiter: '~', // the connection in the packed name, group name + connection + entry file name enforceSizeThreshold: 50000, cacheGroups: {defaultVendors: {// Group name test: /[\\/]node_modules[\\/]/, // Match the range to node_modules priority: -10 // Priority, when a module meets multiple group rules, the module will be packaged into a file with high priority // filename: 'vender.js' // Specify the name of the module}, default: {// All modules that are introduced, and those that do not satisfy the defaultVendors group rules above, will then be matched with the DEFAULT group rules: minChunks: 2, Priority: -20, reuseExistingChunk: True, // the module has been packaged before, then reuse}}}}} directly;Copy the code

(5) Error boundary

JavaScript errors in part of the UI should not break the entire application. To address this, React introduces “Error Boundaries”



Code segmentation implementation in React

(1) React. Lazy and Suspense implement code segmentation

    1. The react.lazy (() => import()) argument is a function that must return a promSIE object. React.lazy currently supports only default export
    1. Suspense components, fallback properties accept any React elements you want to show during component loading. You can place the Suspense component anywhere on top of lazy loading components. You can even package multiple lazy-loaded components in one girl component.
import React, { useState, Suspense } from 'react' import { Button } from 'antd'; const Home = (props: any) => { console.log(props); const [AsyncTest, setAsyncTest] = useState<any>() const [AsyncTest2, SetAsyncTest2] = useState<any>() // import() const asyncLoad1 = () => {import(/* webpackChunkName: "AsyncTest" */'.. /.. /components/async-test') .then(({ default: AsyncTest }) => { setAsyncTest((element: Any) => element = AsyncTest)}).catch(err => console.log(err))} // React.lazy() + segmentation of const asyncLoad2 = () => { const Test2 = React.lazy(() => import(/* webpackChunkName: "AsyncTest2" */'.. /.. /components/async-test2')) setAsyncTest2((component: any) => component = Test2) } return ( <div> <header>home page bigscreen</header> <Button onClick={() => { asyncLoad1(); </Button> {AsyncTest? AsyncTest() : null} {/* {AsyncTest ? <AsyncTest />: null} */} <Suspense fallback={<div>Loading... </div>}> {AsyncTest2 ? <AsyncTest2 /> : null} </Suspense> </div> ) } export default HomeCopy the code

(2) React-based code segmentation (React. Laze) (Suspense) (React-router-config)

  • Similar to the vue
React.lazy Suspense react-router-config routes.js------------------ const Login = lazy(() => import(/* webpackChunkName:  'Login' */'.. /pages/login')) const HomeBigScreen = lazy(() => import(/* webpackChunkName: 'HomeBigScreen' */'.. /pages/home/bigscreen.home')) const HomeAdmin = lazy(() => import(/* webpackChunkName: 'HomeAdmin' */'.. /pages/home/admin.home')) const Layout = lazy(() => import(/* webpackChunkName: 'Layout' */'.. /pages/layout')) const routes: RouteModule[] = [ { path: '/login', component: Login, }, { path: '/', component: Layout, routes: / / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - embedded routines by {path: '/ home - bigscreen, exact: true, component: HomeBigScreen, }, { path: '/home-admin', exact: true, component: HomeAdmin, }, ] } ] router.js------------------ import { renderRoutes } from 'react-router-config' //--------------------- <Suspense fallback={<div>loading... <Suspense fallback={<div>loading... < / div >} > / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Suspense lazy, Suspense.fallback <Switch> {renderRoutes(routes)} </Switch> </Suspense> ) } layout.js---------------- const render = () => { if (systemType === SYSTEMTYPE.ADMIN) { return ( <div className={styles.layoutAdmin}> <header className={styles.header}>layout page admin</header> {renderRoutes(props.route.routes)} //--------------------------- renderRoutes(props.router.routes) </div> ) } else { return ( <div className={styles.layoutBigScreen}> {renderRoutes(props.route.routes)} </div> ) } }Copy the code

(3) React-based code segmentation (third-party library React-Loadable)

  • Github.com/jamiebuilds…

Program source code

  • Program source code
  • Deployment effect Preview address

data

www.html.cn/create-reac… Do code sharding in React: juejin.cn/post/684490…