中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue中Tree-Shaking的原理是什么

發布時間:2023-04-27 10:43:17 來源:億速云 閱讀:108 作者:zzz 欄目:開發技術

這篇文章主要介紹“Vue中Tree-Shaking的原理是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Vue中Tree-Shaking的原理是什么”文章能幫助大家解決問題。

什么是Tree-Shaking

Tree-Shaking這個概念在前端領域是因為rollup.js而起,后來webpack等也加入支持Tree-Shaking的行列中。簡單來說就是移除掉項目中永遠不會被執行的代碼(dead code),實際情況中,代碼雖然依賴了某個模塊,但其實只使用其中的某些功能。通過Tree-shaking,將沒有使用的模塊代碼移除掉,這樣來達到刪除無用代碼的目的。

Tree-shaking的原理和支持

  • 實現tree-shaking的基礎是依賴于ES6的模塊特性,即模塊必須是ESM(ES Module)。這是因為ES6模塊的依賴關系是確定的、靜態的,和運行的時的狀態無關,可以進行靜態分析。

  • 現在主流的打包工具都支持Tree-shaking,例如最早支持的rollup,后來支持的webpack,以及vite等等。

可以被Tree-shaking

有以下代碼,其中工具函數文件中包含了foobar,在shaking文件中只使用了foo,在main文件中引用了foo,但沒有使用:

// utils.js
export const foo = () => {
    console.log('foo')
}
export const bar = () => {
    console.log('bar')
}
// shaking.js
import { foo } from './utils.js'
const fn = () => {
    console.log('fn')
    foo()
}
fn()
// main.js
import { foo, bar } from './utils.js'
const main = () => {
    console.log('main')
    bar()
}
main()

現在分包使用rollup.js打包shaking.jsmain.js文件

# 打包shaking文件
npx rollup shaking.js -f esm -o bundle.js
# 打包main文件
npx rollup main.js -f esm -o mian-bundle.js

先來看bundle.js文件的內容,utils文件中foo打包進去,而bar沒有被引用,則被移除。

const foo = () => {
    console.log('foo');
};
const fn = () => {
    console.log('fn');
    foo();
};
fn();

再來看main-bundle.js文件的內容,utils文件中bar打包進去,而foo雖然被引用,但是沒有在main.js文件中使用,則被移除。

const bar = () => {
    console.log('bar');
};
const main = () => {
    console.log('main');
    bar();
};
main();

不可以被Tree-shaking

有些代碼看著無用,但是確不能被Tree-shaking移除,例如我們對上面的代碼進行重寫

// utils.js
// 新增以下代碼
export default {
    name: function () {
        console.log('絕對零度')
    },
    age: () => {
        console.log(18)
    }
}
// shaking.js
import userInfo,  { foo } from './utils.js'
const fn = () => {
    console.log('fn')
    userInfo.name()
    foo()
}
fn()

再次使用rollup.js打包文件

const foo = () => {
    console.log('foo');
};
var userInfo = {
    name: function () {
        console.log('絕對零度');
    },
    age: () => {
        console.log(18);
    }
};
const fn = () => {
    console.log('fn');
    userInfo.name();
    foo();
};
fn();

有意思的問題來了,這次我們僅僅使用name方法,而age方法也被打包進來,說明Tree-shaking沒有生效。究其原因,export default導出的是一個對象,無法通過靜態分析判斷出一個對象的哪些變量未被使用,所以tree-shaking只對使用export導出的變量生效。

另外一個問題是,如果一個函數被調用的時候會產生副作用,那么就不會被移除。再次在utils文件中增加下面代碼

// utils.js新增的代碼
export const empty = () => {
    const a = 1
}
export const effect = (obj) => {
    obj && obj.a
}

再次導入使用然后打包

// shaking.js文件
import userInfo,  { foo, empty, effect } from './utils.js'
const fn = () => {
    console.log('fn')
    userInfo.name()
    empty()
    effect()
    foo()
}
fn()

打包后發現新增加了一個effect函數,而同時新增的empty函數被移除,分析原因發現effect函數就是一個純讀取函數,但是這個函數可能會產生副作用。試想一下,如果obj對象是一個通過Proxy創建的代理對象,那么當我們讀取對象屬性時,就會觸發代理對象的get方法,在get方法中是可能產生副作用的,比如調用其它的方法或者修改一些變量等等。

const foo = () => {
    console.log('foo');
};
const effect = (obj) => {
    obj && obj.a;
};
var userInfo = {
    name: function () {
        console.log('絕對零度');
    },
    age: () => {
        console.log(18);
    }
};
const fn = () => {
    console.log('fn');
    userInfo.name();
    effect();
    foo();
};
fn();

由于rollup.js分析靜態代碼很困難,所以他們給我們提供一個機制,明確告訴rollup,這部分代碼沒有副作用可以移除。/*#__PURE__*/就是解決這個問題的辦法,只需要在effect方法前面加上上面的代碼,程序運行的時候就會認為他是沒有副作用的,可以放心的進行Tree-shaking

/*#__PURE__*/const effect = (obj) => {
    obj && obj.a;
};

Vue中的應用

在Vue的框架源碼中,存在這大量的特性開關,打包編譯或者使用的時候通過配置特性開關可以通過Tree-shaking機制讓代碼資源最優化。
比如Vue3為了支持Vue2options Api,寫了大量的兼容代碼,但是如果我們再使用Vue3中不使用options Api,就可以通過一個叫做__VUE_OPTIONS_API__的特性開關去關閉這個特性,這樣最終打包的Vue代碼就不會包含這部分,進而減少代碼體積。

關于“Vue中Tree-Shaking的原理是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

云安县| 昌邑市| 福海县| 上饶市| 隆安县| 邵东县| 高唐县| 罗城| 阳朔县| 六安市| 桑日县| 常山县| 合水县| 呼伦贝尔市| 城口县| 金秀| 交口县| 集贤县| 普陀区| 东兰县| 开远市| 罗甸县| 宜君县| 邯郸市| 兴隆县| 乌审旗| 天气| 海原县| 香格里拉县| 邻水| 理塘县| 潜江市| 烟台市| 宝坻区| 凯里市| 双桥区| 天镇县| 大埔县| 繁峙县| 广饶县| 山阳县|