npm 6.14 + Babel 7 使用
Babel 是幹嘛的
用於將 ECMAScript 2015+ 版本的程式碼轉換為向後相容的 JavaScript 語法,以便能夠執行在當前和舊版本的瀏覽器或其他環境中。下面列出的是 Babel 能為你做的事情:
- 語法轉換
- 通過 Polyfill 方式在目標環境中新增缺失的特性 (通過 @babel/polyfill 模組)
- 原始碼轉換 (codemods)
npx
在Babel使用之前先介紹一下npx,因為後面用到npx,注意不是npm
npx是啥
npx是一種在npm中安裝工具,也可以被單獨的下載使用
在npm 5.2.0 的時候發現會買一送一,自動安裝了npx。
也就是說 npm5.2之後,會自動安裝
npx是解決什麼問題的
再也不需全域性安裝任何工具只需要npx <commang>
為什麼使用npx
全域性安裝劣勢:
-
佔用本機空間
npm會在machine上建立一個目錄(mac是
/usr/local/lib/node_modules
)存放所有global安裝的包, 其實node_module佔用的空間比較大的 -
版本問題:
假如一個專案中的某一個dependency是全域性安裝的,也就意味著不同的開發人員使用的這個dependency版本完全基於本地的版本,也就會導致不同的開發人員使用不同的版本
使用npx的優勢也就凸顯出來了:
-
當在執行
npx <command>
的時候,npx會做什麼事情?
- 幫你在本地(可以是專案中的也可以是本機的)尋找這個 command
- 找到了: 就用本地的版本
- 沒找到: 直接下載最新版本,完成命令要求
- 使用完之後不會在你的本機或者專案留下任何東西
- 幫你在本地(可以是專案中的也可以是本機的)尋找這個 command
因此優勢總結:
- 不會汙染本機
- 永遠使用最新版本的dependency
Babel使用
配置Node專案環境
執行
npm init -y
然後專案目錄下就會建立一個package.json,如
下載相應的包的命令
npm install --save-dev @babel/core @babel/cli @babel/preset-env npm install --save @babel/polyfill 或者簡寫: npm install -D @babel/core @babel/cli @babel/preset-env npm install @babel/polyfill
(--save-dev(簡寫-D)表示該版本只適用於開發環境中,命令會自動幫你寫在package.json的devDependencies中
--save(或者不寫)則表示該版本適用於生產環境中,命令會自動幫你寫在package.json的dependencies中 )
如:
使用Babel前要下載的包的意義和用法
@babel/core
Babel 的核心功能在 @babel/core模組,如果某些程式碼需要呼叫Babel的API進行轉碼,則就需要此模組。
用法如下
var babel = require('@babel/core');
// 字串轉碼
babel.transform('code();', options);
// => { code, map, ast }
// 檔案轉碼(非同步)
babel.transformFile('filename.js', options, function(err, result) {
result; // => { code, map, ast }
});
// 檔案轉碼(同步)
babel.transformFileSync('filename.js', options);
// => { code, map, ast }
// Babel AST轉碼
babel.transformFromAst(ast, code, options);
// => { code, map, ast }
@babel/polyfill
模組包括core-js和自定義regenerator runtime 來模擬完整的 ES2015+ 環境。
Babel預設只轉換新的JavaScript句法(syntax),而不轉換新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全域性物件,以及一些定義在全域性物件上的方法(比如Object.assign
)都不會轉碼。
舉例來說,ES6在Array
物件上新增了Array.from
方法。Babel就不會轉碼這個方法。如果想讓這個方法執行,必須使用babel-polyfill
,為當前環境提供一個墊片
@babel/preset-env
根據你需要支援的環境(配合targets中的瀏覽器資訊)自動決定適合你的 Babel 外掛
@babel/cli
@babel/cli是一個允許你從終端使用 babel 的工具。即用於命令列轉碼
全域性安裝命令
npm install -D @babel/cli -g
基本用法如下。
# 轉碼結果輸出到標準輸出(字串形式輸出)
$ babel example.js
# 轉碼結果寫入一個檔案
# --out-file 或 -o 引數指定輸出檔案
$ babel example.js --out-file compiled.js
# 或者
$ babel example.js -o compiled.js
# 整個目錄轉碼
# --out-dir 或 -d 引數指定輸出目錄
$ babel src --out-dir lib
# 或者
$ babel src -d lib
# -s 引數生成source map檔案
$ babel src -d lib -s
建立配置檔案
使用以下內容在專案的根目錄中建立名為 babel.config.js 的配置檔案:(配置檔案很重要)
module.exports = function(api){
api.cache(true)
const presets = [
["@babel/env", {
targets: {
ie:"10",
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
},
useBuiltIns: "usage"
}]
];
const plugins = [];
return {
presets,
plugins
}
}
//target表示你想要支援的瀏覽器的最低型號
// useBuiltIns: "usage" ——由於polyfill包很臃腫,Babel 的此設定將檢查你的所有程式碼,以查詢目標環境中缺少的功能,並僅包含所需的 polyfill。
開始使用
建立src資料夾,再在裡面建立index.js檔案,並輸入
(x => x * 2)(1)
在命令列中輸入
//表示src整個目錄轉碼到dist目錄下
npx babel src -d dist
結果如下
可以看到已經被成功編譯
es6相關特性編譯問題
class 不支援
上面安裝了@babel/polyfill
包 編譯Promise等全域性對物件沒問題,但是你會發現class類 這個特性編譯不了
如
這是因為還缺少一個外掛@babel/plugin-proposal-class-properties
安裝
npm install @babel/plugin-proposal-class-properties -D
在配置檔案中加入外掛配置
const plugins = [
'@babel/plugin-proposal-class-properties'
];
此時的babel.config.js
module.exports = function(api){
api.cache(true)
const presets = [
["@babel/env", {
targets: {
ie:"10",
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
},
useBuiltIns: "usage"
}]
];
const plugins = [
'@babel/plugin-proposal-class-properties'
];
return {
presets,
plugins
}
}
執行編譯
npx babel src -d dist
編譯結果