import React from 'react';
import ReactDOM from 'react-dom';
import moment from 'moment';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
anathor.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import Container from './components/container';
ReactDOM.render(<Container />, document.getElementById('root'));
App.jsx:
import React from 'react';
import Container from './components/container';
export default function App() {
return (
<div>
<Container />
</div>
);
}
container.jsx:
import React from 'react';
import moment from 'moment';
export default function Container() {
return <div>容器</div>;
}
Code Splitting (代码分隔)可以将代码分隔到不同的bundle中,然后可以按需加载或者并行加载这个文件。从而在网页加载时获得更好的加载体验。 该文章主要以实践为主,因为之前自己在配置这方面折腾的比较少,😑😑
SplitChunksPlugin
首先简单搭建下webpack开发配置:
开发目录如下:
index.jsx:
anathor.jsx:
App.jsx:
container.jsx:
Selector.jsx:
现在直接跑
npm run build(webpack --mode production)
,看下打包情况:可以看出公共的依赖包并没有被单独拿出来,这时我们需要依靠
SplitChunksPlugin
来做这件事,而webpack 已内置了 SplitChunksPlugin,并且给设定了初始配置:上面的每个字段的意思参见Webpack4之SplitChunksPlugin。因为 chunks 被设置为了
async
,所以只对动态加载的文件进行分块。这里我们先将其改成all
相较于之前,
moment
与react
相关代码已被单独成包了。 但现在如果我想吧react以及react-dom单独拿出来呢?我们可以设置一个cacheGroup
:好,react相关代码也被单独拿出来了,,这时可能会问,为何react的代码不会被放到vendors中呢?这时因为
react
这个cacheGroup
的优先级(1)
大于vendors的优先级(-10
)。 之前我们讲到,chunks
的默认值为async
,现在我们来试试该效果,在another.jsx
引入如下代码,然后不设置splitChunks
:看的出来,,antd 被单独打包了,而moment还是在各个入口文件中各有一份,此时在设置为
all
试试:关于react路由动态加载
如果我们一开始就加载整个应用的代码,那会在首页即加载很多无关的代码,所以我们可以按照路由级别来按需加载相关代码。 通过上面的了解,我们可以对每个路由对应的组件使用
import()
这个方法来动态引入,然后webpack会根据此来分隔代码,从而实现按需加载。 但是import()
方法返回的是一个Promise
,并不能直接给react-router
来使用,所以我们需要一个组件。可以想一下,我们封装一个 加载组件,在组件未加载完成时,给个loading来提示,设置一个state,在组件加载好后,setState一下,不就ok 了? 可以看看umi/dynamic
,它是基于 react-loadable来实现的,而react-loadable
的大致思路也是上面我说的这种。未完待续......
参考
SplitChunksPlugin
Webpack Code Splitting