使用CRACO对CRA项目使用CDN导入
不少React项目都是用官方的 creat-react-app(CRA)创建的,这样方便专注于React本身,而不用去配置webpack,babel等,但是项目开发到了后期的时候想要做一些自定义优化又很困难,如果需要手动更改配置,可能需要一些方法和工具,本文主要讨论使用CRACO使用CDN导入体积较大的包,以一个使用了百度地图的项目为例。
安装配置CRACO
CRA本身就是将 webpack
,babel
等依赖配置完成封装起来后得到的一个工具,我们可以使用 eject
可以将这些依赖导出至 package.json
,同时也会得到这些依赖的配置文件,但是eject
本身是不可逆的,也就是说执行之后会删除CRA这个包,改变项目结构,之后的各种配置都需要自己维护,并不推荐。
Create React App Configuration Override(CRACO)可以重写CRA配置而不会改变项目结构,是目前比较主流的一种方法之一。
- 安装CRACO
1 |
|
- 在项目根目录创建CRACO配置文件
craco.config.js
默认的配置文件位置为项目根目录,默认文件名为 craco.config.js
1 |
|
- 更新
package.json
中的scripts
1 |
|
完成以上步骤就已经配置完成CRACO了,执行 npm run start
测试一下,没有问题就可以开始配置webpack和babel了
分析打包情况
首先我们需要知道打包的大致情况才能知道从哪里下手,使用 webpack-bundle-analyzer
可以展示打包后各个bundle对应的大小以及包含的依赖包。
- 安装 webpack-bundle-analyzer
1 |
|
- 更改
craco.config.js
配置
1 |
|
- 执行
npm run build
即可查看打包情况
可以看到这里的mapvgl这个依赖占了很大的体积,对于大体积的包可以考虑使用cdn导入的方式。
使用CDN导入依赖包
对于大体积的包,我们可以采用CDN导入的方式,可以减小打包体积,使用 webpack
的 externals
可以实现。
防止将某些
import
的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些*扩展依赖(external dependencies)*。
- 找到对应包的CDN链接(注意版本)
- 找到包对应externals中的key和value
简单来说key就是引入时的包名,value就是js文件执行后赋值给window的全局变量名称。,比如jQuery是这样引入的
1 |
|
查看 jquery
包,可以看到导出全局变量名称为jQuery
1 |
|
所以 externals
这样写
1 |
|
我们需要去寻找代码中导入包的方式,比如我当前要找出的包是mapvgl,查找依赖关系之后发现是react-bmapgl的依赖,所以我们需要去react-bmapgl这个包中找。
在layers这个包中可以看到
1 |
|
所以我们找到了对应的key,与jQuery一样,我们点击查看 mapvgl
这个包,发现是未格式化的js代码,使用在线格式工具格式化后,我们主要关注最前面的这段代码,有关模块规范知识可以自行搜索。
1 |
|
大致可以猜出 z
是window,写入了一个名为 mapvgl
的包,所以value值为 mapvgl
,同理找出 "mapvgl/dist/mapvgl.threelayers.min"
的value值也为 mapvgl
。
- 更改
craco.config.js
配置,在webpack
中添加externals
,填入CDN网址和包对应的 key 和 value
我们这里将 externals
的默认类型指定为 script
,可以直接在 webpack
配置中写入CDN网址,而不需要在 html
文件中写入 scipt
标签来导入包。
1 |
|
- 优化结果
执行 npm run start
,百度地图正常使用。
执行 npm run build
,分析打包体积,去掉了两个很大的包,体积明显下降。
之后也有需要也可以对 antd
, react
, react-dom
等比较大的几个包使用CDN导入,不过并不是导入越多越好,过多的script标签也会造成请求过多,造成网络卡顿,使用CDN导入主要是可以减小打包体积,降低服务器带宽压力。