這篇文章主要介紹webpack中使用tree-shaking的方法,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比信豐網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式信豐網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋信豐地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
1.什么是tree-shaking
webpack 2 的到來帶來的最棒的新特性之一就是tree-shaking 。tree-shaking源自于rollup.js,先如今,webpack 2也有類似的做法。
webpack 里的tree-shaking的到來不得不歸功于es6規(guī)范的模塊。為什么這么說,如今的前端模塊規(guī)范很多,比較出流行的比如commonJS , AMD , es6 ,我簡單的說一下commonJS和es6模塊的區(qū)別。
commonJS 模塊
commonJS的模塊規(guī)范在Node中發(fā)揚(yáng)光大,總的來說,它的特性有這幾個(gè):
1.動(dòng)態(tài)加載模塊
commonJS和es6的最大區(qū)別大概就在于此了吧,commonJS模塊的動(dòng)態(tài)加載能夠很輕松的實(shí)現(xiàn)懶加載,優(yōu)化用戶體驗(yàn)。
2.加載整個(gè)模塊
commonJS模塊中,導(dǎo)出的是整個(gè)模塊。
3.每個(gè)模塊皆為對(duì)象
commonJS模塊都被視作一個(gè)對(duì)象。
4.值拷貝
commonJS的模塊輸出和 函數(shù)的值傳遞相似,都是值的拷貝
es6 模塊
1.靜態(tài)解析
即在解析階段就確定輸出的模塊,所以es6模塊的import一般寫在被引入文件的開頭。
2.模塊不是對(duì)象
在es6里,每個(gè)模塊并不會(huì)當(dāng)做一個(gè)對(duì)象看待
3.加載的不是整個(gè)模塊
在es6模塊中經(jīng)常會(huì)看見一個(gè)模塊中有好幾個(gè)export 導(dǎo)出
4.模塊的引用
es6模塊中,導(dǎo)出的并不是模塊的值拷貝,而是這個(gè)模塊的引用
在結(jié)合es6模塊和commonJS模塊的區(qū)別之后,我們知道es6的特點(diǎn)是靜態(tài)解析,而commonJS模塊的特點(diǎn)是動(dòng)態(tài)解析的,因此,借于es6模塊的靜態(tài)解析,tree-shaking的實(shí)現(xiàn)才能成為可能。
在webpack中,tree-shaking指的就是按需加載,即沒有被引用的模塊不會(huì)被打包進(jìn)來,減少我們的包大小,縮小應(yīng)用的加載時(shí)間,呈現(xiàn)給用戶更佳的體驗(yàn)。
2.怎么使用tree-shaking
說了這么多那到底如何使用tree-shaking呢?
webpack默認(rèn)es6規(guī)范編寫的模塊都能使用tree-shaking。這是什么意思呢?下面來看個(gè)例子。
首先奉上我的demo目錄如下:
├─dist
└─index.html
├─node_modules
└─...
├─src
├─scripts
├─assets
├─webpack.config.js
└─package.json
dist用來存放打包好的代碼
src相反的用來存放源文件
src里的scripts目錄用來存放js腳本文件,assets用來存放靜態(tài)資源文件
以下幾條命令過后開始我們的tree-shaking之旅
npm install --save-dev webpack webpack-dev-server webpack.config.js const webpack = require('webpack') const path = require('path') module.exports = { entry:'./src/scripts/main.js', output:{ path:path.resolve(__dirname,'dist/'), filename:'main.bundle.js' }, plugins:[ new webpack.HotModuleReplacementPlugin() ], devServer:{ port:4200, contentBase:path.resolve(__dirname,'dist/'), historyApiFallback:true, hot:true } }
接下來是main.js,直接引入了sayHello
import { sayHello } from './greeter.ts';
sayHello();
相應(yīng)的main.js的依賴greeter.js
export function sayHello(){ alert('hello') }
export function sayWorld(){ alert('world') }
在dist目錄下有個(gè)index.html 用來引入打包后的bundle
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript" src="./main.bundle.js"></script> </body> </html>
以上就是整個(gè)demo的代碼,接下來的事情我們直接webpack打包試試看
去掉打包后冗長的代碼只看chunk傳參的部分:
[
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__person__ = __webpack_require__(1);
Object(__WEBPACK_IMPORTED_MODULE_0__person__["a" /* sayHello */])();
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHello; });
/* unused harmony export sayWorld */
function sayHello(){
alert('hello');
}
function sayWorld(){
alert('world');
}
/***/ })
/******/ ]
我們關(guān)注這一行
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHello; });
實(shí)際上只return了一個(gè)sayHello。
因此我們現(xiàn)在只需要壓縮一下整個(gè)Js代碼,就能把沒引用的sayWorld剔除。
鍵入以下命令進(jìn)行壓縮
webpack --optimize-minimize
由于壓縮后的代碼只有一行了,我們移步尾部:
function(e,n,r){"use strict";function t(){alert("hello")}r.d(n,"a",function(){return t})}]);
可以看到sayWorld函數(shù)已經(jīng)被成功剔除。
我們啟動(dòng)webpack-dev-server
webpack-dev-server
在瀏覽器中輸入
http://localhost:4200
每次都需要在命令行里輸入?yún)?shù),豈不是很麻煩,還有沒有其他更好的辦法呢?
(1)我們可以把這串命令放入package.json的scripts字段,然后通過npm start來自動(dòng)執(zhí)行
(2)其實(shí)–optimize-minimize的底層實(shí)現(xiàn)是一個(gè)插件UglifyJsPlugin,因此,我們可以直接在webpack.config.js里配置它
在webpack.config.js里配置插件
const path = require('path'); const webpack = require('webpack'); module.exports = { entry:'./src/scripts/main.js', output:{ filename:'main.bundle.js', path:path.join(__dirname,'dist') }, plugins:[ new webpack.optimize.UglifyJsPlugin(), // <----------- 壓縮js new webpack.HotModuleReplacementPlugin() ], devServer:{ port:4200, historyApiFallback:true, hot:true, contentBase:path.join(__dirname,"dist/") } }
然后我們webpack打包
即看到同樣的效果
function(e,n,r){"use strict";function t(){alert("hello")}r.d(n,"a",function(){return t})}]);
在tree-shaking觸發(fā)打包后,僅僅是撇開了模塊的引用,但還是要結(jié)合壓縮工具來進(jìn)行,這才是完整的一次tree-shaking
那如果是typescript該怎么使用tree-shaking呢?
3.如何在typescript里使用tree-shaking
要在webpack里使用ts,首先我們必須安裝tsc
npm install --save-dev typescript
之后我們需要解析ts文件的loader
npm install --save-dev ts-loader
然后在webpack.config.js進(jìn)行配置
const webpack = require('webpack') const path = require('path')
module.exports = { entry:'./src/scripts/main.ts', output:{ path:path.resolve(__dirname,'dist/'), filename:'main.bundle.js' }, module:{ rules:[ { test:/\.ts$/, use:['ts-loader'] } ] }, plugins:[ new webpack.optimize.UglifyJsPlugin(), new webpack.HotModuleReplacementPlugin() ], devServer:{ port:4200, contentBase:path.resolve(__dirname,'dist/'), historyApiFallback:true, hot:true } }
獻(xiàn)上我的兩份文件main.ts , greeter.ts (這兩份文件除了后綴名基本沒有改動(dòng))
main.ts
import { sayHello } from './greeter.ts'; sayHello();
greeter.ts
export var sayHello = function(){ alert('hello') } export var sayWorld = function(){ alert('world') }
之后我們需要做的是,創(chuàng)建一個(gè)tsconfig.json的配置文件供tsc解析,這時(shí),坑來了。
下面是我的tsconfig.json文件
{ "compilerOptions":{ "target":"es5", "sourceMap":true }, "exclude":[ "./node_modules" ] }
好像沒有什么不對(duì)
接著我們webpack
看下打包壓縮后的代碼的最后一部分:
"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.sayHello=function(){alert("hello")},n.sayWorld=function(){alert("world")}}]);
sayWorld居然還是存在?。。≡趺椿厥?,為什么沒有被觸發(fā)tree-shaking優(yōu)化?
這是因?yàn)閠sc編譯后的代碼為es5 ,而正因如此,tsc默認(rèn)使用了commonJS的規(guī)范來加載模塊,因此并沒有觸發(fā)tree-shaking,那我們要怎么做?
修改一下tsconfig.json,把target改為es6即可!
{ "compilerOptions":{ "target":"es6", "sourceMap":true }, "exclude":[ "./node_modules" ] }
再次打包
看一下打包后的bundle
function(e,n,r){"use strict";r.d(n,"a",function(){return t});var t=function({alert("hello")}}]);
果然是觸發(fā)了tree-shaking
開啟webpack-dev-server
webpack-dev-server
可以看到成功打印hello
以上是“webpack中使用tree-shaking的方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站標(biāo)題:webpack中使用tree-shaking的方法
瀏覽地址:http://aaarwkj.com/article4/iihpoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、微信公眾號(hào)、服務(wù)器托管、外貿(mào)網(wǎng)站建設(shè)、軟件開發(fā)、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)