前言
之前用 Babel 轉換語法,都是靠框架和 cli轉換,沒試過從頭自己設定。直到最近,接了沒只用原生 Javascript 的小案。身爲 ES6++ 的愛好者,一定要使用 Babel 才能存活啊,最後只好自己從頭研究XD 查了一下,發現很多設定其實已經過時,因此這邊寫一份筆記整理,希望能減少其他人研究的時間。
Babel 做什麼
Babel 能把比較新的 Javascript (關鍵字: ES6,ES2015 等),轉換成目前 Browser 能看得懂的 Javascript (ES5),讓 Developers 能用新語法的同時,不會讓網頁壞掉。
Babel 的 2 種模式
- Babel 默認只轉換語法(Syntax), 像是:
a. Arrow function ( () => {} )
b. Spread ( [ …state, isOpen ] )
c. Destructing ( const { data } = res )
d. Default Parameters ( ( id = NaN ) => {})
- 而自帶的 Api 、原生內置 Methods,需要加上 polyfill 後才能使用,像是:
a. Promise
b. Symbol
c. Array.from
d. Object.assign
e. fetch
1. 轉換語法(Syntax)
直接轉換語法是非常方便的,以下放了 Webpack 和 Gulp 的範例。
1.1 Webpack
Webpack:1
npm install -D babel-loader @babel/core @babel/preset-env webpack
1 | // webpack.config.js |
1.2 Gulp:
1 | npm install --save-dev gulp-babel @babel/core @babel/preset-env |
1 | const gulp = require('gulp') |
想要快的話,可在 Babel 網站的 Try It Out 直接轉換。(似乎沒有比較方便?)
2. Polyfill
相較於直接轉換 Syntax,Polyfill 才是讓人頭疼的地方。有時候需要支援的 Browser 太舊(eg: IE11),龐大的 Polyfill bundle 拖累了其他不需要 Polyfill 的 Browser。儘量用只需要的 Polyfill 變成是需要優化的目標。
2.1 Polyfill:用Webpack
2.1.1 entry 加入 @babel/polyfill
這是最早期的做法,就是讓 Webpack 也 bundle polyfill的檔案:
1 | // webpack.config.js |
2.1.2 useBuiltIns
以前的做法是轉換語法(Syntax)和 Polyfill 是分開設定,現在在設定同一處統一用 useBuiltIns 設定,還有加上target(browserlist)的功能,讓設定方便很多。
useBuiltIns 有三種設定方式:
a. entry
b. usage
c. disable(就是不要加 polyfill 咯,就不解釋了)
2.1.2 a.) useBuiltIns : ‘entry’
在你的app入口加上這個:1
2// app.js
import '@babel/polyfill'
根據1.1和2.1.1的基礎做更動:
1 | // webpack.config.js |
2.1.2 b.) useBuiltIns : ‘usage’
在app入口拿掉:1
2// app.js
- import '@babel/polyfill'
1 | // webpack.config.js |
上面設定完之後,就會根據你在寫 code 的過程中,加上需要的 polyfill。
但是由於 Babel 不能判斷你 code 裏面的 type,所以不能載入正確的 Polyfill。比方說:
1 | import "core-js/modules/es7.array.includes"; |
2.1.3 手動引入要的 core.js
1 | import 'core-js/modules/es6.set.js' |
但如果需要很多 Polyfill 的話,一個個載入就會變得很麻煩。
2.2 Polyfill:不用Webpack
2.2.1 Gulp、Browser 引用打包
在引入@babel/polyfill下的dist\polyfill.min.js:1
2
3
4
5
6
7
8
9
10
11
12
13
14// gulpfile.js
const polyfill = 'node_modules/babel-polyfill/dist/polyfill.min.js'
var jsfiles = [
'js/lib/otherJsLibrary.js',
polyfill,
'js/index.js'
];
gulp.task('default', function() {
return gulp.src(jsfile)
.pipe(concat('index.min.js')) //合併檔案
.pipe(uglify())
.pipe(gulp.dest('dist/')) //輸出
});
或者直接抓出檔案,在 Browser 直接引入:
1 | <script src="polyfill.js"></script> |
這樣的結果當然就是 Bundle 整個會變得非常肥,不需要 Polyfill 的 Browser 也被迫下載,造成資源的浪費。
2.2.2 Polyfill.io
這個由金融時報(Financial Times)提供的服務,根據你的 UA 來判斷需要的 Polyfill(當然你可以指定,點這裏可以看文檔),用法也很簡單,在你的網頁加上:1
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
在不同的 Browser 看就會發現很回傳的東西不太一樣:
這個是 Chrome 下看到的
這是 IE 11 下看到的
當然若有安全上的考量,可以到他們的github,下載然後自己 Deploy 在自己的 Server 上吧!
雖然在特定較舊的 Browser,還是有很肥的問題,但是卻拯救了其他 90% 的 Browser!
總結
總結那麼多方法,代表說我之前活動案被折磨很慘(誤),個人覺得最好的方法,是搭配 Webpack 的 Babel,加上自己架設的 Polyfill services,但是實際效果有待確定,有空再更新使用效果。