前端公共资源完全共享的畅想
在每个前端项目中,多多少少都会依赖一些第三方资源,比如Query
,React
,Angular
,core-js
,babel-runtime
;如果我们能够尽最大程度的复用这些资源,那么我们就能够节约很大的首次请求成本,无需绞尽脑汁即可显著提升首屏首次加载速度。另外提升 webpack 构建速度,扯这么多构建优化方案,就设置 externals 效果最显著;
问题由来
前端资源如果可以尽可能的使用公共 CDN 上资源,但是集团内的公共资源太少,只有一些主流的框架或库,这就导致各个团队可能会维护一份自己的公共资源 CDN。现实中使用这些 CDN 略微麻烦,比如新起一个项目就需要这么以下步骤:
看下项目中依赖的哪些流行库可以在 CDN 上找到,譬如 react,先把这个脚本插入在页面模板。开发环境需要一些警告信息,所以最好不要使用压缩脚本。
1
2<script src="//cdn.bootcss.com/react/15.0.1/react-with-addons.js"></script>
<script src="//cdn.bootcss.com/react/15.0.1/react-dom.js"></script>生成环境的模板需要压缩过的脚本:
1
2<script src="//cdn.bootcss.com/react/15.0.1/react-with-addons.min.js"></script>
<script src="//cdn.bootcss.com/react/15.0.1/react-dom.min.js"></script>因为我们是使用
webpack
构建,所以,还需要配置 externals;形如1
2
3
4
5
6
7externals: {
react: 'React',
'react-dom': 'ReactDOM',
'react-addons-css-transition-group': 'React.addons.CSSTransitionGroup',
'react-addons-shallow-compare': 'React.addons.shallowCompare',
'react-addons-transition-group': 'React.addons.TransitionGroup',
},在上面
react-addons
的资源如果不指明,很可能出现某个第三方的组件库引入 react-addons,导致 react 依旧被打包在一起。维护需要人工成本。 如果哪一天要升级 react 版本,看到 CDN 上有新版本,还要把模板引用的版本号给改掉。
使用工具消灭重复劳动
如果我们使用用 webpack 为什么不用一个插件解决这些呢?但是,但是这儿有一个问题:
cdn 资源没规则,从 package.json 中完全看不出;
- 模块的依赖有可能已经打包在一起;如 react-router,将 依赖的小文件一起打包。
- 依赖不明确;如 bootstap 依赖 jquery 是在 dependencies 中指定的,而 react-router 其实只需要外部的 react,在 peerDependencies 中声明的。
- 现有的资源路径规则也不确定,如 bootcdn.cn 上 min.js 存在 -min.js 和 .min.js。
好吧,那我就自己维护一份,cdn-webpack-plugin 就是这个插件的雏形。为主流构建工具提供插件,也能够推动资源的共享。
理想与现实
理想如果实现了,那前端资源无需 npm install,直接引用 CDN 就可以了。另外我们还能够做一些优化:根据资源共同出现频率选择合适的资源 combo
如:react 全家桶 用到 redux 系列, redux react-redux react-thunk。
现实是,我们不可能维护所有资源的所有版本,不可能取代 npm 或 yarn。也不会如它们这么及时,一个第三方库 fix bug 升级,不大可能立即同步到 CDN 上。最大的问题还是第三方的资源不可信,除非几个大公司牵头组织一个第三方的资源库。