日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

將Vue組件庫更換為按需加載的方法步驟

瀏覽:144日期:2023-01-22 18:06:19

本文介紹了將Vue組件庫更換為按需加載的方法步驟,分享給大家,具體如下:

按需加載DEMO倉庫地址

背景

我司前端團(tuán)隊(duì)擁有一套支撐公司業(yè)務(wù)系統(tǒng)的UI組件庫,經(jīng)過多次迭代后,組件庫體積非常龐大。

組件庫依賴在npm上管理,組件庫以項(xiàng)目根目錄的 index.js 作為出口導(dǎo)出,文件中導(dǎo)入了項(xiàng)目中所有的組件,并提供組件安裝方法。

index.js

import Button from './button';import Table from './table';import MusicPlayer from './musicPlayer';import utils from '../utils'import * as directive from '../directive';import * as filters from '../filters';const components = { Button, Table, MusicPlayer}const install = (Vue) => { Object.keys(components).forEach(component => Vue.use(component)); // 此處繼續(xù)完成一些服務(wù)的掛載}if (typeof window !== ’undefined’ && window.Vue) { install(Vue, true);}export default { install, ...components}

組件庫并不導(dǎo)出編譯完成后的依賴文件,業(yè)務(wù)系統(tǒng)使用時(shí),安裝依賴并導(dǎo)入,就能注冊(cè)組件。

import JRUI from ’jr-ui’;Vue.use(JRUI);

組件庫的編譯是交由業(yè)務(wù)系統(tǒng)的編譯服務(wù)順帶編譯的。

即組件庫項(xiàng)目本身不會(huì)編譯,僅作為組件導(dǎo)出。node_module 就像一個(gè)免費(fèi)的云盤,用于存儲(chǔ)組件庫代碼。

因?yàn)榻?jīng)業(yè)務(wù)系統(tǒng)編譯,在業(yè)務(wù)系統(tǒng)中。組件庫代碼能夠和本地文件一樣,直接調(diào)試。而且非常簡單粗暴,并不需要做一些依賴導(dǎo)出的額外配置。

但也存在缺點(diǎn)

組件庫中無法使用更為特殊的代碼

vue-cli會(huì)靜態(tài)編譯在 node_module 引用的 .vue 文件,但不會(huì)編譯 node_module 中的其他文件,一旦組件庫代碼存在特殊的語法擴(kuò)展(JSX),或者特殊的語言(TypeScript)。此時(shí)項(xiàng)目啟動(dòng)會(huì)運(yùn)行失敗。

組件庫中使用 webpack 的特殊變量將不起效

組件庫中的 webpack 配置不會(huì)被業(yè)務(wù)系統(tǒng)去執(zhí)行,所以組件庫中的路徑別名等屬性無法使用

組件庫依賴每次都是全量加載

index.js 本身就是全量的組件導(dǎo)入,所以即使業(yè)務(wù)系統(tǒng)只使用了部分組件, index.js 也會(huì)將所有的組件文件(圖片資源,依賴)都打包進(jìn)去,依賴體積總是全量大小的。

業(yè)務(wù)系統(tǒng)并不存在只使用一兩個(gè)組件的情況,每個(gè)業(yè)務(wù)系統(tǒng)都需要絕大部分組件。幾乎每個(gè)項(xiàng)目都會(huì)使用比如 按鈕,輸入框,下拉選項(xiàng),表格 等常見基礎(chǔ)組件。只有部分組件僅在少數(shù)特殊業(yè)務(wù)線使用,例如 富文本編輯器,音樂播放器。

組件分類

為了解決上述問題,及完成按需引入的效果。提供兩種組件導(dǎo)出方式,全量導(dǎo)出,基礎(chǔ)導(dǎo)出。將組件導(dǎo)出分為兩種類型。基礎(chǔ)組件,按需引入組件。按需引入組件的評(píng)定標(biāo)準(zhǔn)為:

較少業(yè)務(wù)系統(tǒng)使用 組件中包含體積較大或資源文件較多的第三方依賴 未被其他組件內(nèi)部引用

全量導(dǎo)出模式導(dǎo)出全部組件,基礎(chǔ)導(dǎo)出僅導(dǎo)出基礎(chǔ)組件。在需要使用按需引入組件時(shí),需要自行引入對(duì)應(yīng)組件。

調(diào)整為按需引入

參考 element-ui 的導(dǎo)出方案,組件庫導(dǎo)出的組件依賴,要提供每個(gè)組件單獨(dú)打包的依賴文件。

將Vue組件庫更換為按需加載的方法步驟

全量導(dǎo)出 index.js 文件無需改動(dòng),在 index.js 同級(jí)目錄增加新文件 base.js,用于導(dǎo)出基礎(chǔ)組件。

base.js

import Button from './Button';import Table from './table';const components = { Button, Table}const install = (Vue) => { Object.keys(components).forEach(component => Vue.use(component));}export default { install, ...components}

修改組件庫腳手架工具,增加額外打包配置。用于編譯組件文件,輸出編譯后的依賴。

vue.config.js

const devConfig = require(’./build/config.dev’);const buildConfig = require(’./build/config.build’);module.exports = process.env.NODE_ENV === ’development’ ? devConfig : buildConfig;

config.build.js

const fs = require(’fs’);const path = require(’path’);const join = path.join;// 獲取基于當(dāng)前路徑的目標(biāo)文件const resolve = (dir) => path.join(__dirname, ’../’, dir);/** * @desc 大寫轉(zhuǎn)橫杠 * @param {*} str */function upperCasetoLine(str) { let temp = str.replace(/[A-Z]/g, function (match) { return '-' + match.toLowerCase(); }); if (temp.slice(0, 1) === ’-’) { temp = temp.slice(1); } return temp;}/*** @desc 獲取組件入口* @param {String} path*/function getComponentEntries(path) { let files = fs.readdirSync(resolve(path)); const componentEntries = files.reduce((fileObj, item) => { // 文件路徑 const itemPath = join(path, item); // 在文件夾中 const isDir = fs.statSync(itemPath).isDirectory(); const [name, suffix] = item.split(’.’); // 文件中的入口文件 if (isDir) { fileObj[upperCasetoLine(item)] = resolve(join(itemPath, ’index.js’)) } // 文件夾外的入口文件 else if (suffix === 'js') { fileObj[name] = resolve(`${itemPath}`); } return fileObj }, {}); return componentEntries;}const buildConfig = { // 輸出文件目錄 outputDir: resolve(’lib’), // webpack配置 configureWebpack: { // 入口文件 entry: getComponentEntries(’src/components’), // 輸出配置 output: { // 文件名稱 filename: ’[name]/index.js’, // 構(gòu)建依賴類型 libraryTarget: ’umd’, // 庫中被導(dǎo)出的項(xiàng) libraryExport: ’default’, // 引用時(shí)的依賴名 library: ’jr-ui’, } }, css: { sourceMap: true, extract: { filename: ’[name]/style.css’ } }, chainWebpack: config => { config.resolve.alias .set('@', resolve('src')) .set('@assets', resolve('src/assets')) .set('@images', resolve('src/assets/images')) .set('@themes', resolve('src/themes')) .set('@views', resolve('src/views')) .set('@utils', resolve('src/utils')) .set('@mixins', resolve('src/mixins')) .set('jr-ui', resolve('src/components/index.js')); }}module.exports = buildConfig;

此時(shí)我們的 npm run build 命令,執(zhí)行的便是以上這段 webpack 配置。

配置中,會(huì)尋找組件目錄的所有入口文件。對(duì)每個(gè)入口文件根據(jù)設(shè)置進(jìn)行編譯輸出到指定路徑。

configureWebpack: { // 入口文件 entry: getComponentEntries(’src/components’), // 輸出配置 output: { // 文件名稱 filename: ’[name]/index.js’, // 輸出依賴類型 libraryTarget: ’umd’, // 庫中被導(dǎo)出的項(xiàng) libraryExport: ’default’, // 引用時(shí)的依賴名 library: ’jr-ui’, }},css: { sourceMap: true, extract: { filename: ’[name]/style.css’ }}

function getComponentEntries(path) { let files = fs.readdirSync(resolve(path)); const componentEntries = files.reduce((fileObj, item) => { // 文件路徑 const itemPath = join(path, item); // 在文件夾中 const isDir = fs.statSync(itemPath).isDirectory(); const [name, suffix] = item.split(’.’); // 文件中的入口文件 if (isDir) { fileObj[upperCasetoLine(item)] = resolve(join(itemPath, ’index.js’)) } // 文件夾外的入口文件 else if (suffix === 'js') { fileObj[name] = resolve(`${itemPath}`); } return fileObj; }, {}); return componentEntries;}

項(xiàng)目中的組件目錄為如下,配置將會(huì)將每個(gè)組件打包編譯導(dǎo)出到 lib 中

components 組件文件目錄│ │— button │ │— button.vue button組件│ └─ index.js button組件導(dǎo)出文件││— input │ │— input.vue input組件│ └─ index.js input組件導(dǎo)出文件││— musicPlayer│ │— musicPlayer.vue musicPlayer組件│ └─ index.js musicPlayer組件導(dǎo)出文件││ base.js 基礎(chǔ)組件的導(dǎo)出文件└─ index.js 所有組件的導(dǎo)出文件lib編譯后的文件目錄│ │— button │ │— style.css button組件依賴樣式│ └─ index.js button組件依賴文件││— input │ │— style.css input組件依賴樣式│ └─ index.js input組件依賴文件││— music-player│ │— style.css musicPlayer組件依賴樣式│ └─ index.js musicPlayer組件依賴文件││— base │ │— style.css 基礎(chǔ)組件依賴樣式│ └─ index.js 基礎(chǔ)組件依賴文件│└─ index │— style.css 所有組件依賴樣式 └─ index.js 所有組件依賴文件

獲取組件全部入口時(shí),對(duì)入口名稱做駝峰轉(zhuǎn)橫杠處理 upperCasetoLine,是因?yàn)?babel-plugin-import 在按需引入時(shí),如組件名稱為駝峰命名,路徑會(huì)轉(zhuǎn)換為橫杠分隔。

例如業(yè)務(wù)系統(tǒng)引入

import { MusicPlayer } from 'jr-ui'// 轉(zhuǎn)化為var MusicPlayer = require(’jr-ui/lib/music-player’);require(’jr-ui/lib/music-player/style.css’);

因?yàn)榻M件庫命名約定,組件文件夾命名大小寫并不以橫杠隔開。但為了讓 babel-plugin-import 正確運(yùn)行,所以此處對(duì)每個(gè)文件的入口文件名稱做了轉(zhuǎn)換處理。

如不經(jīng)過方法轉(zhuǎn)換名稱,也可以配置 babel.config.js 中的plugin-import配置 camel2DashComponentName 為 false,來禁用名稱轉(zhuǎn)換。

babel-plugin-import路徑命名issue

業(yè)務(wù)系統(tǒng)使用時(shí)

全量導(dǎo)出默認(rèn)導(dǎo)出全部組件

// 全量導(dǎo)出import JRUI from 'jr-ui';import 'jr-ui/lib/index/index.css';Vue.use(JRUI);

基礎(chǔ)導(dǎo)出僅導(dǎo)出基礎(chǔ)組件,如需要使用額外組件,需要安裝 babel-plugin-import 插件且配置 babel.config.js 來完成導(dǎo)入語句的轉(zhuǎn)換

npm i babel-plugin-import -D

業(yè)務(wù)系統(tǒng)——babel.config.js配置

module.exports = { presets: ['@vue/app', ['@babel/preset-env', { 'modules': false }]], plugins: [ [ 'import', { 'libraryName': 'jr-ui', 'style': (name) => { return `${name}/style.css`; } } ] ]}

基礎(chǔ)導(dǎo)出

import JRUI_base from 'jr-ui/lib/base';import 'jr-ui/lib/base/index.css';Vue.use(JRUI_base);// 按需使用額外引入的組件import { MusicPlayer } from 'jr-ui';Vue.use(MusicPlayer);

業(yè)務(wù)系統(tǒng)中調(diào)試組件庫代碼

如果仍然想調(diào)試組件庫代碼,在引入組件時(shí),直接引入組件庫依賴內(nèi)的 components 下的組件導(dǎo)出文件并覆蓋安裝。就能調(diào)試目標(biāo)組件。

import button from 'jr-ui/src/components/button';Vue.use(button);

優(yōu)化效果

在組件庫較大的情況下,優(yōu)化效果非常明顯。在使用基礎(chǔ)組件時(shí),體積小了一兆。而且還減少了很多組件內(nèi)不必要的第三方依賴文件資源。

將Vue組件庫更換為按需加載的方法步驟

案例倉庫地址,如有疑問和錯(cuò)誤的地方,歡迎大家提問或指出。祝你有個(gè)快樂的勞動(dòng)節(jié)假期 :)Have a nice day.

參考資料

vue-cli執(zhí)行解析babel-plugin-import

到此這篇關(guān)于將Vue組件庫更換為按需加載的方法步驟的文章就介紹到這了,更多相關(guān)Vue組件庫更換為按需加載內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产日韩免费| 国产在线观看www| 欧美在线影院| 日韩午夜在线| 天堂va欧美ⅴa亚洲va一国产| 午夜日韩影院| 久久精品系列| 欧美影院三区| 婷婷成人av| 久久精品国产久精国产| 精品日韩视频| 亚洲精品人人| 国产精品一区二区美女视频免费看| 久久久久观看| 蜜桃成人av| 91精品国产自产精品男人的天堂| 欧美日韩亚洲一区二区三区在线| 国产精品麻豆久久| 在线精品小视频| 蜜臀av国产精品久久久久| 国产探花一区二区| 久久精品主播| 日韩欧美美女在线观看| 精品五月天堂| 午夜在线视频一区二区区别| 欧美久久久网站| 久久精品1区| 日本麻豆一区二区三区视频| 国产中文字幕一区二区三区| 欧美天堂亚洲电影院在线观看| 欧美日韩1区| bbw在线视频| 日韩中文字幕av电影| 精品国产麻豆| 日韩一区二区三区高清在线观看| 国产va免费精品观看精品视频| 亚洲一区二区三区高清不卡| 精品视频97| 影音先锋久久精品| 最新中文字幕在线播放| 亚洲美女91| 日韩精品免费一区二区三区| 日韩欧美2区| 日本免费久久| 欧美在线黄色| 伊人成人网在线看| 国产精品igao视频网网址不卡日韩| 99久久夜色精品国产亚洲1000部| 日本色综合中文字幕| 久久亚洲国产| 亚洲精品一级二级三级| 99精品美女| 日韩av片子| 国产精品天堂蜜av在线播放| 亚洲男女自偷自拍| 欧美精品三级在线| 蜜臀av一区二区三区| 久久久久久美女精品| 欧美aa在线视频| 日本成人在线一区| 男女激情视频一区| 97人人精品| 美女久久精品| 日本aⅴ免费视频一区二区三区| 午夜国产一区二区| 久久国产日本精品| 国产精品久久久久久久免费观看| 欧美有码在线| 日韩国产91| 少妇高潮一区二区三区99| 免费中文字幕日韩欧美| 欧美/亚洲一区| 久久精品不卡| 久久精品青草| 久久精选视频| 久久精品国语| 日韩欧美一区二区三区在线视频 | 日韩毛片网站| 亚洲欧洲美洲国产香蕉| 久久国产精品99国产| 狠狠干成人综合网| 免费精品国产的网站免费观看| 日本精品在线中文字幕| 蜜桃精品在线| 99久久夜色精品国产亚洲狼| 免费高潮视频95在线观看网站| 久久久久伊人| 国产精品手机在线播放| 久久国产三级精品| 国产亚洲一区| 免费在线播放第一区高清av| 欧美一区二区三区久久精品| 国产亚洲一区二区三区啪| 国产情侣久久| 麻豆中文一区二区| 国产一区二区视频在线看| 精品淫伦v久久水蜜桃| 久久精品五月| 91看片一区| 人人香蕉久久| 欧美久久精品一级c片| 91久久亚洲| 久久高清国产| 日韩一区网站| 精品亚洲免a| 久久国产毛片| 首页亚洲欧美制服丝腿| 亚洲永久精品唐人导航网址| 中文字幕一区二区av| 国产精品亚洲人成在99www| 麻豆精品视频在线观看| 三上亚洲一区二区| 亚洲手机在线| 中文字幕日韩高清在线| 欧美精品影院| 97精品国产| 一本一本久久| 午夜亚洲福利| 国产一区二区三区四区二区| 成人久久一区| 亚洲毛片视频| 免费一级欧美片在线观看网站 | 欧美在线日韩| 国产精品福利在线观看播放| 久久人人精品| 蜜桃av一区二区| 国产精品欧美日韩一区| 日韩专区精品| 亚洲精品黄色| 国产精品一区二区美女视频免费看 | 午夜国产精品视频| 中文字幕日韩欧美精品高清在线| 国产精品99久久免费观看| 精品日韩视频| 日本一不卡视频| 黑森林国产精品av| 亚洲女人av| 国产高潮在线| 四虎国产精品免费久久| 久久精品女人| 久久国产66| 精品网站aaa| 视频一区二区三区中文字幕| 成人在线黄色| 四虎国产精品免费久久| 日韩大片免费观看| 免费成人在线观看| 精品久久国产一区| 久久亚洲风情| 色一区二区三区四区| 亚洲视频二区| 中文在线中文资源| 日韩1区2区日韩1区2区| 99精品视频在线| 97久久精品| 在线综合亚洲| 国产精品久久观看| 日本91福利区| 99视频在线精品国自产拍免费观看| 欧美激情福利| 亚洲伊人影院| 欧美日韩在线播放视频| 国产精品毛片久久久| 久久成人亚洲| 久久国产中文字幕| 丁香婷婷久久| 国产亚洲一区二区三区啪| 在线综合亚洲| 999精品色在线播放| 国产劲爆久久| 日韩精品1区2区3区| 亚洲欧美久久久| 亚洲午夜av| yellow在线观看网址| 国产伦理一区| 亚洲精品一二| 中文在线不卡| 美女久久久久| 久久激情网站| 日韩一区二区三区免费播放| 久久这里只有精品一区二区| 日韩av电影一区| 亚洲精品第一| 蜜桃伊人久久| 91九色精品国产一区二区| 欧美日韩精品免费观看视欧美高清免费大片 | 一区二区精品| 99国产精品视频免费观看一公开 | 国产麻豆综合| 亚洲午夜在线| 国产精品伦理久久久久久| 国产精品夜夜夜| 日韩精品免费视频人成| 日欧美一区二区| 亚洲a成人v| 日韩av二区在线播放| 日本a级不卡| 欧美日韩一区二区三区不卡视频| 日韩精品一二三区| 免费精品视频|