React Router 代码拆分
需要webpack, @babel/plugin-syntax-dynamic-import
, and loadable-components
.
wepack 用来实现动态 import;
使用 babel,就需要安装 @babel/plugin-syntax-dynamic-import
插件,这个插件允许 Babel 解析动态 import 的文件,webpack 把这些文件打包成单独文件;
.babelrc
配置如下:
{
"presets": ["@babel/preset-react"],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
loadable-components
是一个动态加载组件的库;
import loadable from "@loadable/component";
import Loading from "./Loading.js";
const LoadableComponent = loadable(() => import("./Dashboard.js"), {
fallback: <Loading />
});
export default class LoadableDashboard extends React.Component {
render() {
return <LoadableComponent />;
}
}
React.lazy 动态 import
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 = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);
Antd 按需加载
对 create-react-app 的默认配置进行自定义,这里我们使用 react-app-rewired (一个对 create-react-app 进行自定义配置的社区解决方案)。
引入 react-app-rewired 并修改 package.json 里的启动配置。由于新的 react-app-rewired@2.x 版本的关系,你还需要安装 customize-cra。
$ yarn add react-app-rewired customize-cra
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
}
然后在项目根目录创建一个 config-overrides.js
用于修改默认配置。
module.exports = function override(config, env) {
// do stuff with the webpack config...
return config;
};
babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件(原理),现在我们尝试安装它并修改 config-overrides.js
文件。
$ yarn add babel-plugin-import
+ const { override, fixBabelImports } = require('customize-cra');
- module.exports = function override(config, env) {
- // do stuff with the webpack config...
- return config;
- };
+ module.exports = override(
+ fixBabelImports('import', {
+ libraryName: 'antd',
+ libraryDirectory: 'es',
+ style: 'css',
+ }),
+ );
然后移除前面全量添加的 @import '~antd/dist/antd.css';
样式代码,并且按下面的格式引入模块。
// src/App.js
import React, { Component } from 'react';
- import Button from 'antd/es/button';
+ import { Button } from 'antd';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
}
}
export default App;
antd 组件的 js 和 css 代码都会按需加载。antd 默认支持基于 ES module 的 tree shaking,js 代码部分不使用这个插件也会有按需加载的效果。
webpack 代码拆分
参考:webpack 代码分离