wepback作為前端最熱門的打包管理工具之一,學(xué)習(xí)一下是很有必要的,關(guān)于webpack的學(xué)習(xí)教程很多,并且官方也有對應(yīng)的中文文檔,所以本篇文章不再講解如何使用webpack,而是重點講解學(xué)習(xí)webpack前需要了解的一些概念。
什么是webpack
關(guān)于什么是webpack,一般的教程里面都會提到webpack是一個模塊化打包工作,但是很多初學(xué)者沒有模塊化這個概念,所以往往在第一步就被攔住了。所以在講什么是webpack之前,我想先講一下和模塊化相關(guān)的概念。
javascript的運行環(huán)境
因為我們平時寫的js代碼都在瀏覽器中運行,所以可能會造成一個錯覺,那就是js代碼只能在瀏覽器中運行,其實瀏覽器只是js的一個運行環(huán)境,除了在瀏覽器,還可以在服務(wù)器上運行,也就是node環(huán)境,感興趣的可以自己下載node.js試一下,在node.js里面可以直接運行js代碼。所以有些語法在瀏覽器里面并不支持,比如es6的module,即使在最新的瀏覽器里面也不行,這些語法只能在node環(huán)境中運行,直接在瀏覽器中使用會報錯。
什么是模塊化?
在講模塊化之前,我們先復(fù)習(xí)一下less,我們在a.less文件中定義了一個顏色變量@white:#fff,現(xiàn)在我在b.less中想用到這個@white變量應(yīng)該怎么辦呢?使用@import 'a'就可以了。在上面那段less代碼中,其實我們就用到了模塊化編程,只不過是基于less的?,F(xiàn)在我們再來看一下js如何實現(xiàn)模塊化編程。
傳統(tǒng)的寫法比較簡單,就是把自己需要的js文件全部放到index,html中引入,在引入的時候還需要確保引入的順序是正常的,本質(zhì)上來說,就是把所有代碼全部引入到一個js文件中。而現(xiàn)在我們采用模塊化的寫法,就會相對來說結(jié)構(gòu)清晰一點,比如在main.js里面需要使用jquery,那么我們可以在main.js里面這么寫:import $ from "jquery",在index.html里面只需要引入main.js即可,采用這種寫法可以讓文件間的依賴關(guān)系更加清楚,實現(xiàn)按需加載,同時結(jié)構(gòu)也會更加合理。
JS的模塊規(guī)范有哪些
在es6之前,主要采用AMD和CMD這2中規(guī)范,AMD規(guī)范比較好的一個實現(xiàn)庫是require.js,CMD對應(yīng)的是seajs,還有一點node.js也是符合CMD規(guī)范的,所以cmd規(guī)范的代碼可以直接在node環(huán)境下運行。而js的最新版本es6則提供了原生的module語法,以實現(xiàn)對模塊化的支持
CMD語法:
// 定義模塊
module.exports =function(){
vargreet =document.createElement('div');
greet.textContent ="Hi there and greetings!";returngreet;};
//引用模塊
letgreeter =require('./Greeter.js');
ES6語法:
//定義模塊
etdog="我愛哈士奇"
exportdefaultdog
//引用模塊
importdogfrom'animal'
webpack干了什么
上面已經(jīng)提到這些模塊化的語法是不能在瀏覽器環(huán)境中運行的,所以我們需要這些將這些互相依賴的文件進行編譯(打包),編譯成瀏覽器能夠運行的代碼。而webpack做的就是這個打包操作,比如我們在main.js里面依賴了add.js文件,而add.js文件使用import $ form 'jquery',那么webpack會發(fā)現(xiàn)main.js需要add.js,然后將add.js導(dǎo)入,導(dǎo)入add.js的時候發(fā)現(xiàn)add.js需要jquery,然后又將jquery給導(dǎo)入,最后生成了一個總的js文件,這樣我們的代碼就可以到瀏覽器環(huán)境上運行了。
webpack與es6
es6提供了很多激動人心的新特性,但是這些新特性并不被所有的瀏覽器支持,為了使用這些新特性,我們可以使用babel插件,將我們的代碼es6代碼轉(zhuǎn)換成es5代碼。但是對于一些es6新的api,比如promise等,需要使用babel-polyfill,而如何使用babel-polyfill呢?只要在需要對es6轉(zhuǎn)換成es5的文件頭部加上import 'babel-polyfill';很明顯,這是es6的模塊語法,表示這個文件依賴babel-profill這個文件,所以我們需要使用打包工具來進行打包,這樣才能運行這段代碼。所以,想要學(xué)習(xí)es6,webpack是必須要邁過去的一道坎。
如何學(xué)習(xí)webpack
談了這么多,總算要到如何學(xué)習(xí)了。學(xué)習(xí)資料的話,可以去看一些已經(jīng)整理好的資料或者官網(wǎng)的文檔,了解config的基本語法就可以開始擼了。這里推薦一個練手的項目:多動癥簡歷。這是一個很有意思的項目,里面用到了es6+promise+webpack,如果你能將這段代碼進行打包,并實現(xiàn)以下幾個要求,那么你webpack可以說是入門了。如果你對這個多動癥簡歷項目感興趣,可以去看一下項目作者的這篇文章:用原生js寫一個"多動癥"的簡歷,推薦直接閱讀項目的源代碼,從中可以學(xué)到很多知識。
- 使用babel-loader將es6轉(zhuǎn)換成es5
- 將css單獨的打包成一個文件
- 壓縮js代碼
- 壓縮css代碼
- 使用html模板生成index.html
至于上面這些功能如何實現(xiàn),需要用到哪些插件,希望你能自己去百度,去google,去stackoverflow。只有自己練過,才算徹底掌握,如果只是簡單的跟著官網(wǎng)項目做幾個簡單的demo,其實沒什么意義。
踩坑記錄
這是我在使用webpack時遇到的一些坑,webpack的版本號是3.0,如果你也遇到了,可以參考一下下面的解決方案。
使用extract-text-webpack-plugin生成單獨的css時,可能會報錯chunk.sortModules is not a function ,解決方案是回退extract-text-webpack-plugin版本號到2.1.2,npm i extract-text-webpack-plugin@2.1.2。
一般的壓縮js插件無法壓縮es6,如果想對es6代碼進行壓縮,可以使用UglifyjsWebpackPlugin。但是如果教程一步一步來還是會報錯Unexpected token: name (doc)。解決方案是將babel配置拿出來,不要放在webpack.config中,單獨的放到.babelrc中。
使用了extract-text-webpack-plugin后無法進行css壓縮?
可以使用optimize-css-assets-webpack-plugin這一插件來解決。
webpack和gulp有什么區(qū)別
兩者雖然在某些功能上類似,比如都可以壓縮代碼,編譯less等。但是兩者的定位不同,剛才也提到過了,webpack本質(zhì)上是一個打包工具,支持CMD的語法,將多個互相依賴的js文件打包成一個js文件。而gulp則是一個自動化工具,用來處理less編譯,代碼壓縮這些,gulp的核心概念是管道,所有文件在管道中流通,然后在流的過程中依次進行代碼壓縮,less編譯等操作,最后再將這些文件流輸出到指定目錄。所以兩者在功能以及定位上都有很大的不同。