[Tool Note] — 關於Webpack #2 - Babel?

Webpack又來啦!

Introduction & 前言

最近這陣子剛好公司新的專案必須從頭開始,終於前後端分離,之前都是依附在 Laravel 底下,新專案是用 Vue Cli3 寫的,最近老闆猛然一提,才思考到舊手機支援問題,當下心整個懸在空中,糊塗的自己只顧著因為第一次自己從頭開始一個前端專案很興奮的心情,竟然忘了顧及支援度的問題,所以在今天上班時趕緊研究 babel/polyfill ,研究時 Vue Cli3 爆出一些警告訊息(內容就先不討論了),這時候想到了前陣子摸過的 Webpack

相較於這次的專案,之前許多頁面都是單純SPA一頁式的網頁 ( HTML CSS JavaScript ),而且只有在手機上跑,不會到萬惡的 Bug Maker IE 跑,所以基本上不是非常舊的東西還是都支援。但最後還是碰到了有手機不能跑的問題,其實會發現這種不能跑的情況是從一個拿 Iphone6 IOS9 的同事身上開始…

溫馨提醒:強烈建議還沒看過 關於Webpack #1 的同學們去看看[Tool Notes] — 關於Webpack #1 - 第一次就上手

因為發生了這種狀況,所以 JavaScript 能不用 (註1)ES6 就盡量避免,但其實在那時候就決定要再回來用 Webpack 了,無奈最近時程真的是被壓縮壓縮超級壓縮呀…(苦笑

基礎打得穩 切版沒煩惱

近期六角開了一堂特別的線上直播課程,網頁切版直播班,因為覺得自己基本功不是很穩,近期切版時程太趕,希望自己能快速且精準又能寫出乾淨程式碼的情況下,就報名了,哎…出來寫前端,總是要還的,而且是別人說的倍數成長呀

因為課程開始前有新手任務,剛好要切一個版,就打算拿那個版面來練習,不過這篇文章不會介紹怎麼切,而是要先介紹怎麼編譯 ES6 => ES5 ,因為目前 ES5 的支援度還是比 ES6 高。

謎之音:如果 ES5 也不支援怎麼辦呢?

答:解決有 ES 看不到問題的人就@&^*$&)(#*@)…

*註1: ESECMAScript,他制定了瀏覽器腳本語言的標準,而 JavaScript 算是 ECMAScript 最著名的實現。詳情請點我*


單刀直入

廢話說了很多,這邊我們繼續說!這篇主要會提到 Babel,這就是前言提到的,新的 ES6 如果舊手機舊瀏覽器吃不到怎麼辦?那你就必須透過加工廠(Babel)加工把東西弄的適合過時的東西吃。

這邊假設 if ( 您已經看過 [Tool Notes] — 關於Webpack #1 - 第一次就上手 ) else if ( 或已經具備基本的 Webpack 概念 ) ,else ( 請看看就好尊重友善包容手下留情感激不盡,這邊就不在介紹如何初始化一個 Webpack 專案 ) 。

上一篇提過 modulepluginswebpack.config.js 裡的差別,前者是專們放 xxx-loader 的,後者顧名思義是專們放 plugins,沒錯,今天的主角 Babel 是要放在 module 裡的,有點像我們使用 pug 或是 scss 的預處理器,靠 loader 幫我們編譯成網頁看得懂的語言。


巴別塔?

首先在 官方網站 會看見其實 Babel 底下還有很多 Plugins,我們需要幾項東西。

  1. babel-loader => 最基本的橋樑, 透過它來讀取在 WebpackES6 的語言

  2. @babel/core => 最多人的疑惑,他說穿了就是幫你把你文件的字串透過 transform 方法轉為新的字符串,再返回給你,所以編譯時只帶入 babel-loader@babel/core 你會發現編譯過後東西原封不動地吐給你

  3. @babel/preset-env => Babel 怎麼編譯呢?在 WebpackLoader 裡面其實也有自己專屬的 Plugins,透過這個 Plugin 就能編譯


開動了

首先我們拿上次的範例繼續做,需要的可以 這邊 下載,建立好之後我們需要安裝 Babel,輸入下面程式碼安裝:

1
$ npm install babel-loader @babel/core @babel/preset-env --save-dev

再次複習 => –save–save-dev 都是將模塊安裝到項目目錄下,差別在前者是在 dependencies 寫入依賴,後者是在 devDependencies 寫入依賴。 寫入 dependencies 內的套件是您打包後在發布環境下還會用到的套件,而 devDependencies 則是開發環境下會用到的套件。

隨後到 Webpack.config.js 內在 module 裡新增 test: /\.(js)$/ 幾行程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader', // 這個會後執行
'css-loader' // 這個會先執行
]
},
{
//- ...略
},
{
//- ...略
},
{
//- 新增這幾行
test: /\.(js)$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},

接著之後到 /src/js/index.js 裡面輸入下面程式碼:

1
2
3
4
5
6
//- ES6 Example
const habit = ["Write Code", "Watch Udemy", "DeBug", "Sleep"];

habit.forEach(
(item, index) => console.log( `${index} => ${item}` )
);

範例程式碼

這邊使用了 ES6 常見的幾個語法,包含 const、字串模板、箭頭函式…等等,有興趣可以詳見 ES6 武功秘籍大全,語法糖真的香!

真甜真好吃

隨後輸入下面程式碼編譯:

1
$ npm run build:dev 或 npm run build

接著打開 dist/index.html 成功的話會在 console.log 裡看見下面這張圖:

勝利的果實

你會好奇真的編譯成功了嗎?可以打開 dist/main.bundle.js(或你編譯的檔案名稱),發現最下面有已經編譯好的程式碼:

請忽略箭頭

仔細瞧瞧原本的 Const 已經替換成 var, 原本的 “=>“ 箭頭函式也被編譯為 function 也有多了 return,真的是很貼心!

P.S: 那個箭頭並非 ES6 的箭頭函式哦!


然後呢?

然後就完成了,就這麼簡單!其實 Babel 幫我們做了很多事情,自己也並非真的深入地摸索過,但至少看到 ES6 能成功的編譯成 ES5 讓我安心不少。

如果你想瞧瞧到底有沒有編譯成功,可以試著把 babel-loader 下一行的 options 內容註解掉,再跑一次編譯,然後再打開編譯後的 JS 檔案,你會發現內容真的沒有編譯過:

並沒有成功編譯


Conclusion & 結論

這次並沒有做太深入的研究,時間上其實也挺有限的,不過說實在的,有編譯過真的讓人放心不少,而且 Webpack 真的可以把容量壓縮在最小卻能發揮最大效能這點,真的是推薦每一位前端真的都要玩玩看,期待之後還有繼續摸 Webpack 還會繼續 #3

接下來四月要為期八週的切版訓練,希望自己能練得更扎實,這邊推薦給可能在貧頸或是迷途的你,不管你是不是正在寫程式,我想找到你有興趣且會讓你有成就感的目標,是讓你過得快樂且會成長的有效方法之一!

最後這邊會再上傳一份更新過的 Webpack 到之前的 GitHub 上,有興趣的可以抓下來玩玩,也歡迎各路 Webpack 高手中手低手 或 有興趣的人一起來交流,但記得友善尊重包容,謝謝~

範例傳送門 => 點我

2020/04/12 後更: 上傳了新版的 Webpack 程式碼,內容包含 Vue 打包,請至此處觀看。


參考網站


題外話

最近安裝 npm 套件突然一直出現下列錯誤:

1
2
3
4
5
6
7
No receipt for 'com.apple.pkg.CLTools_Executables' found at '/'.

No receipt for 'com.apple.pkg.DeveloperToolsCLILeo' found at '/'.

No receipt for 'com.apple.pkg.DeveloperToolsCLI' found at '/'.

gyp: No Xcode or CLT version detected!

上網爬相關文章過後都說要輸入下面兩行指令:

1
2
$ sudo rm -rf $(xcode-select -print-path)
$ xcode-select --install

但是好像沒有用,20點跪求大神解答…