随着 web
网页的流行,越来越多的人选择使用网页来代替传统的 APP
,随之而来的就是网页越来越庞大,前端性能的问题尤其显现。一些大的项目都会做一些性能优化来提高访问速度,以提升用户的体验,比如:按需加载,资源优化等。
按需加载可以提高页面加载速度,如果当前页面只使用了某个功能,我们可以选择只加载这个功能,避免过于庞大的包加载进页面而需要等等过长的时间。
接下来我们先讨论一个问题:什么时候需要按需加载呢?
如果打包的产物是一个文件,这个文件又很大,一次性下载下来的速度就会比较慢,可能会造成刚进入页面时长时间的白屏的情况,这种体验非常不好;如果打包成多个文件,但是浏览器在同一时间内可以发出的请求数有限制,这也会导致用户等待。按需加载就可以很好的去解决这些问题。
那么我们如何按需加载呢?
简单有效的方式是使用 babel-plugin-import。
什么是 babel-plugin-import
?
babel-plugin-import
是阿里开源的一款 babel
插件,它会在编译过程中将 import
的写法自动转换为按需引入的方式,主要用于组件的按需引入。
如何在项目中添加 babel-plugin-import
?
使用方法
安装
npm install babel-plugin-import --save-dev
配置
通过 .babelrc 配置文件或者 babel-loader 引入。
{
"plugins": [["import", options]]
}
其中
options
为具体的配置项
如果使用 babel7
,可以做如下的配置:
{
"plugins": [["import", options, "antd"]]
}
接下来一起看看具体的配置项 options
:
{
"libraryName": "antd",
"style": true, // or 'css' or 'function'
"libraryDirectory": "components", // default: lib
"camel2DashComponentName": false, // default: true
"styleLibraryDirectory": "lib",
"customName": (name: string, file: object) => {
const filename = file.opts.filename;
if (name === 'TimePicker'){
return 'antd/lib/custom-time-picker';
}
if (filename.indexOf('/path/to/my/different.js') >= 0) {
return 'antd/lib/custom-name';
}
return `antd/lib/${name}`;
}
}
libraryName 代表库的名称
style 引入样式,可以指定 css、true 或者 function
libraryDirectory 组件所在目录,默认:lib
camel2DashComponentName 将引入的组件名转化为"-"连接的文件名
styleLibraryDirectory 样式文件路径
customName 自定义导入文件路径,也可以是一个文件,例如:require('path').resolve(__dirname, './customName.js')
customName.js
文件如下:
module.exports = function customName(name) {
return `antd/lib/${name}`;
};
使用示例
上来讲述了使用方法,我们一起来看看配置后的结果吧!
{ "libraryName": "antd" }
import { Button } from 'antd';
import { TimePicker } from "antd"
ReactDOM.render(<Button>xxxx</Button>);
// 最后输出结果
var _button = require('antd/lib/button');
var TimePicker = require('antd/lib/time-picker');
ReactDOM.render(<_button>xxxx</_button>);
上面只配置了
libraryName
为antd
,按照默认路径lib
引入组件。
{ "libraryName": "antd", style: "css" }
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);
// 最后输出结果
var _button = require('antd/lib/button');
require('antd/lib/button/style/css');
ReactDOM.render(<_button>xxxx</_button>);
配置
style: "css"
,直接引入经过打包后的 antd 样式文件
{ "libraryName": "antd", style: true }
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);
// 最后输出结果
var _button = require('antd/lib/button');
require('antd/lib/button/style');
ReactDOM.render(<_button>xxxx</_button>);
配置
style: true
,在项目编译阶段,可以对引入的 antd 样式文件进行编译,从而可以压缩打包尺寸
{
"libraryName": "antd",
"style": (name: string, file: Object) => {
if(name === 'antd/lib/utils'){
return false;
}
return `${name}/style/2x`;
}
}
配置 style: (name) =>
${name}/style/2x
,引入 css 文件路径是ComponentName/style/2x
。
{
"libraryName": "element-ui",
"styleLibraryDirectory": "lib/theme-chalk",
}
import { Button } from 'element-ui';
// 最后输出结果
var _button = require('element-ui/lib/button');
require('element-ui/lib/theme-chalk/button');
配置
"styleLibraryDirectory": "lib/theme-chalk"
,指定样式在lib/theme-chalk
目录下。
{
"libraryName": "element-ui",
"camel2DashComponentName": false,
}
import { TimePicker } from "antd"
// 最后输出结果
var _button = require('antd/lib/TimePicker');
配置
camel2DashComponentName: false
,不会将组件名转化为"-"连接的文件名
{
"libraryName": "antd",
"customName": (name: string, file: object) => {
const filename = file.opts.filename;
if (name === 'TimePicker'){
return 'antd/lib/custom-time-picker';
}
if (filename.indexOf('/path/to/my/different.js') >= 0) {
return 'antd/lib/custom-name';
}
return `antd/lib/${name}`;
}
}
import { TimePicker } from "antd"
// 最后输出结果
var _button = require('antd/lib/custom-time-picker');
配置
customName
,可以根据指定路径引入组件。
现在我们可以方便地使用按需加载了,不止是开源的组件库,或者是我们自研的组件库都可以使用这种方法。但是也需要我们的组件库支持,也就是说我们的组件库要符合一定的目录结构,export
导出也要符合规范才可以。
总结
有了 babel-plugin-import
后我们可以愉快地进行开发了,只需要在项目中配置一次就不需要关心了。