使用babel-plugin-import?實(shí)現(xiàn)自動(dòng)按需引入方式
babel-plugin-import 實(shí)現(xiàn)自動(dòng)按需引入
Vant 支持一次性導(dǎo)入所有組件,引入所有組件會(huì)增加代碼包體積,因此不推薦這種做法
babel-plugin-import 是一款 babel 插件,它會(huì)在編譯過程中將 import 的寫法自動(dòng)轉(zhuǎn)換為按需引入的方式。
1、下載
npm i babel-plugin-import -D
2、
(1)在.babelrc 中添加配置
注意:webpack 1 無需設(shè)置 libraryDirectory
{
? "plugins": [
? ? ["import", {
? ? ? "libraryName": "vant",
? ? ? "libraryDirectory": "es",
? ? ? "style": true
? ? }]
? ]
}(2)對(duì)于使用 babel7 的用戶,可以在 babel.config.js 中配置
module.exports = {
? plugins: [
? ? ['import', {
? ? ? libraryName: 'vant',
? ? ? libraryDirectory: 'es',
? ? ? style: true
? ? }, 'vant']
? ]
};3、接著你可以在代碼中直接引入 Vant 組件,插件會(huì)自動(dòng)將代碼轉(zhuǎn)化為方式二中的按需引入形式
import { Button } from 'vant';babel-plugin-import 的組件按需加載原理
對(duì)比webpack懶加載
webpack 懶加載是將源碼中的 import、require 引入的文件編譯之后再根據(jù)動(dòng)態(tài)加載語法配置(通常以頁面路由為基本單位)將較大的代碼拆分并構(gòu)建出較小的 chunk 包,運(yùn)行時(shí)執(zhí)行到相應(yīng)業(yè)務(wù)邏輯時(shí)才去加載執(zhí)行對(duì)應(yīng) chunk 代碼。

webpack 懶加載主要發(fā)生在 JS 拆分出不同的 Chunk 這一過程中。
babel-plugin-import 按需加載是以組件為基本單位產(chǎn)出 js、css、less 文件,借助插件或者部分引入的寫法,使得項(xiàng)目代碼或 babel 編譯后的代碼中只包含使用到的組件的 js、css、less 等。
首先是執(zhí)行時(shí)機(jī)不同,babel-plugin-import 按需加載是在源碼編寫階段或者 babel 編譯 js 階段,而 webpack 懶加載則是在構(gòu)建生成打包產(chǎn)物階段。
其次是原理不同,babel-plugin-import 按需加載是在源碼階段就去掉了無關(guān)代碼,而 webpack 懶加載則是將經(jīng)過 tree-shaking 優(yōu)化過后的大文件包進(jìn)行拆分在適當(dāng)?shù)倪\(yùn)行時(shí)進(jìn)行按需加載。兩者并不沖突,可以一前一后共同作用。
實(shí)現(xiàn)原理
babel-plugin-import 按需加載目的是減少項(xiàng)目構(gòu)建打包產(chǎn)物的大小,提高項(xiàng)目線上首屏渲染速度,減少白屏?xí)r間,減少流量消耗。
若是采用手動(dòng)引入需要使用到的組件以及其對(duì)應(yīng)的樣式文件,那么在 webpack 構(gòu)件時(shí)組件庫中其他未被引入的文件不會(huì)被打包。
import Button from 'lib/button'; import 'lib/lib/button/style';
若是自動(dòng)引入:
npm i babel-plugin-import -D
module.exports = {
plugins: [
['import', {
libraryName,
libraryDirectory: 'es',
style: true
}, libraryName]
]
};
import { Button } from libraryName;組件其實(shí)就是對(duì)一堆 js、css 以及 less 等文件的總稱,自動(dòng)引入的本質(zhì)是將引入組件的寫法通過插件來轉(zhuǎn)換成手動(dòng)引入組件對(duì)應(yīng)的代碼以及樣式文件的寫法。核心原理依然是對(duì)源碼的 import 導(dǎo)入寫法進(jìn)行轉(zhuǎn)換——詞法語法分析,AST轉(zhuǎn)換,代碼生成。
該插件主要參數(shù):
"libraryName": "", // 組件庫名稱,對(duì)應(yīng) import 語法中的包名
"libraryDirectory": "lib", // 編譯之后各個(gè)組件單元所在文件夾名稱
"style": true, // 是否引入組件對(duì)應(yīng)樣式文件,也可以傳入 less 來引入 less 文件
"styleLibraryDirectory": "", // 編譯之后引入的組件樣式文件所在文件夾名稱
"camel2DashComponentName": false, // 是否將駝峰命名的導(dǎo)入變量轉(zhuǎn)換為對(duì)應(yīng)的橫線連接命名的文件名
"customName": (name, file) => { return `/lib/${name}` }, // 自定義編譯之后引入的組件名
"customStyleName": (name, file) => { return `/lib/css/${name}` }, // 自定義編譯之后引入樣式文件的名稱插件中使用到的鉤子函數(shù)有:
const methods = [ 'ImportDeclaration', // import 導(dǎo)入聲明 'CallExpression', // 函數(shù)調(diào)用 'MemberExpression', 'Property', 'VariableDeclarator', 'ArrayExpression', 'LogicalExpression', 'ConditionalExpression', 'IfStatement', 'ExpressionStatement', 'ReturnStatement', 'ExportDefaultDeclaration', 'BinaryExpression', 'NewExpression', 'ClassDeclaration', 'SwitchStatement', 'SwitchCase', ];
Visitor 對(duì)象上還配置了 Program 鉤子,該鉤子是在 babel 處理一個(gè)獨(dú)立文件(或者叫做模塊更合適,node 規(guī)范定義一個(gè)文件就是一個(gè)模塊)時(shí)執(zhí)行,其中若不按此方式具體指定則默認(rèn)為 enter 鉤子。
const Program = {
// 進(jìn)入鉤子
enter(path, options) {
// 1. 根據(jù)插件接受到的配置參數(shù)初始化插件 Plugin 數(shù)組
// 2. 遍歷插件 Plugin 數(shù)組,依次執(zhí)行各個(gè)插件的初始化方法 ProgramEnter
},
// 退出鉤子
exit() {
// ...
}
}轉(zhuǎn)換 import 語法需要識(shí)別 ES6 模塊規(guī)范的默認(rèn)導(dǎo)入、部分導(dǎo)入以及整體導(dǎo)入等語法,主要邏輯包括鑒別是否是部分導(dǎo)入,只有部分導(dǎo)入才表示導(dǎo)入具體組件,轉(zhuǎn)換導(dǎo)入變量名等。
// 1. 部分導(dǎo)入
import { Button } from '';
console.log(Button);
// 2. 默認(rèn)導(dǎo)入
import default from '';
console.log(default.Button);
// 3. 全部導(dǎo)入
import * as D from '';
console.log(D.Button);整體處理邏輯如下:
- ImportDeclaration 鉤子中將部分導(dǎo)入、默認(rèn)導(dǎo)入和整體導(dǎo)入的語句記錄到插件全局狀態(tài)對(duì)象上,同時(shí)將節(jié)點(diǎn)的 path 對(duì)象記錄至插件全局狀態(tài)對(duì)象上;
- 插件全局狀態(tài)對(duì)象上存儲(chǔ)的 path 對(duì)象會(huì)在 Program 退出時(shí)遍歷執(zhí)行 remove 方法,從而移除了所有原始的導(dǎo)入語句;
- 在 MemberExpression、CallExpression、buildExpressionHandler、buildDeclaratorHandler等鉤子函數(shù)中執(zhí)行 importMethod 函數(shù);
- importMethod 函數(shù)會(huì)根據(jù)插件的配置參數(shù)計(jì)算出真實(shí)文件導(dǎo)入路徑、是否導(dǎo)入樣式文件、樣式文件名、是否轉(zhuǎn)換默認(rèn)導(dǎo)入等配置,從而使用 @babel/helper-module-imports 提供的 addSideEffect 方法添加對(duì)應(yīng)的部分導(dǎo)入語句。
- 重命名導(dǎo)入模塊的變量描述符 Identifier。
以鉤子函數(shù)為入口,根據(jù)不同的節(jié)點(diǎn)類型取找到不同節(jié)點(diǎn)與變量相關(guān)的屬性;
校驗(yàn)變量的 name 是否存在于插件全局狀態(tài)的 specfied 中,即變量是否是導(dǎo)入組件指向的變量;
通過 path.scope.hasBinding、path.scope.getBinding 排除掉其他作用域的變量;
借助 importMethod 方法計(jì)算轉(zhuǎn)換后模塊對(duì)應(yīng)的變量名然后修改節(jié)點(diǎn)對(duì)應(yīng)的變量名。
變量描述符 Identifier可能指向的鉤子有:
Property VariableDeclarator ArrayExpression LogicalExpression ConditionalExpression IfStatement ExpressionStatement ReturnStatement ExportDefaultDeclaration BinaryExpression NewExpression SwitchStatement SwitchCase ClassDeclaration
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue element中axios下載文件(后端Python)
這篇文章主要介紹了vue element中axios下載文件(后端Python)的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05
Vue中金額、日期格式化插件@formatjs/intl的使用及說明
這篇文章主要介紹了Vue中金額、日期格式化插件@formatjs/intl的使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
Vue中關(guān)于異步請(qǐng)求數(shù)據(jù)未更新的解決
本文將探討Vue中異步請(qǐng)求數(shù)據(jù)未更新的常見原因,并提供解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
vue組件中iview的modal組件爬坑問題之modal的顯示與否應(yīng)該是使用v-show
這篇文章主要介紹了vue組件中iview的modal組件爬坑問題之modal的顯示與否應(yīng)該是使用v-show,本文通過實(shí)例圖文相結(jié)合的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
利用Vue-draggable組件實(shí)現(xiàn)Vue項(xiàng)目中表格內(nèi)容的拖拽排序
這篇文章主要介紹了利用Vue-draggable組件實(shí)現(xiàn)Vue項(xiàng)目中表格內(nèi)容的拖拽排序,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06
Vue中router-view和component :is的區(qū)別解析
這篇文章主要介紹了Vue中router-view和component :is的區(qū)別解析,router-view用法直接填寫跳轉(zhuǎn)路由,路由組件會(huì)渲染<router-view></router-view>標(biāo)簽,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
vue v-for循環(huán)重復(fù)數(shù)據(jù)無法添加問題解決方法【加track-by=''索引''】
這篇文章主要介紹了vue v-for循環(huán)重復(fù)數(shù)據(jù)無法添加問題解決方法,結(jié)合實(shí)例形式分析了vue.js通過在v-for循環(huán)中添加track-by='索引'解決重復(fù)數(shù)據(jù)無法添加問題相關(guān)操作技巧,需要的朋友可以參考下2019-03-03

