>[success] # babel -- 初步上手之各種配置@babel/preset-env
~~~
1.babel 各種錯綜復雜的配置,經常讓在開發階段犯難,通過將各種常用的配置說明一遍來弄懂
實際開發
~~~
>[info] ## @babel/preset-env
~~~
1.'@babel/preset-env' 是預設是一系列插件的集合,包含了我們在babel6中常用es2015,es2016,
es2017 等最新的語法轉化插件,允許我們使用最新的js語法,比如 let,const,箭頭函數等等,
但不包含低于 Stage 3 的 JavaScript 語法提案。這樣以后只要我們安裝一個'babel/preset-env'就
解決了大部分問題,簡單的說,它是 'babel 一個預設'主要用來幫助我們對語法進行轉換,會自動的
根據當前環境對js語法做轉換。常用配置屬性'targets' 'useBuiltIns' 'corejs'
{
"presets": [
[
"@babel/env"
]
]
}
~~~
>[danger] ##### target -- 指定語法最低版本瀏覽器兼容
~~~
1.'targets'解決:隨著低版本的瀏覽器逐步淘汰,一些新特性的語法在新瀏覽器已經支持,可能幾年后大家已經
不在使用IE,如果一股腦的全部兼容打包的體積也會變大,是否有必要全部轉換成'es5',我們更希望
他可以根據你所配置的瀏覽器的列表,自動的去加載當前瀏覽器所需要的插件,然后對es語法做
轉換。
2.'解決方法':
可以通過配置文件指定語法最低版本瀏覽器兼容這里其實配合的是'Browserslist',Browserslist 的數據都是來自
'https://caniuse.com/',現在我們知道各個版本瀏覽器支持的語法接下就是配置文件,配置文件是下面的優先級使用:
2.1.@babel/preset-env 里的 targets
2.2.package.json 里的 browserslist 字段
2.3.browserslistrc 配置文件
3.'使用效果':
描述項目支持的環境/目標環境,支持browserslist查詢寫法
{ "targets": "> 0.25%, not dead" } // 全球使用人數大于0.25%且還沒有廢棄的版本
支持最小環境版本構成的對象
{ "targets": { "chrome": "58", "ie": "11" } }
如果沒配置targets, Babel會假設你的目標是最老的瀏覽器 @babel/preset-env將轉換所有
ES2015-ES2020代碼為ES5兼容
~~~
>[danger] ##### useBuiltIns -- api 導入
~~~
1.'useBuiltIns'解決:首先'AST'語法樹解決是語法層面,可以簡單的理解將字符進行轉換,但是
新增加'api' 層面具有語義的方法,舉個例子當我們使用'Promise' 是其內部定義邏輯讓'Prmoise'
具備了實現效果。社區也為我們提供了這類賦予'語義' 的包'corejs',并且對'@babel/preset-env'
提供了一個'useBuiltIns'參數可以設置三個值'entry','usage','false'。默認使用false
2.關于三個值含義,需要知道'api'墊片和使用'target '屬性解決語法層面的配置他們都有一個共性
就是瀏覽器逐步升級普及那相對的有些東西就不需要對其打包時候也要轉換進去
2.1."useBuiltIns: false":在不主動import的情況下不使用preset-env來處理polyfills,此時不對
'api 墊片做操作',你可以引入你想要的處理'es api'的墊片例如此時
需要在文件引入'import "core-js/stable"' 和 'import "regenerator-runtime/runtime"',則無視配置的
瀏覽器兼容,引入所有的 polyfill。簡單的說目前社區給的'api'墊片庫推薦是'core-js' 你需要在項目
入口引入這個'api'墊片,但不會根據你'target'配置按需引入
2.2."useBuiltIns: entry"根據配置的瀏覽器兼容,引入瀏覽器不兼容的 polyfill。需要在入口文件手
文件引入'import "core-js/stable"' 和 'import "regenerator-runtime/runtime"',會自動根據 browserslist
替換成瀏覽器不兼容的所有 polyfill。這里需要指定 core-js 的版本(也就是要設置'corejs'字段版本)
2.3."useBuiltIns: usage"會根據配置的瀏覽器兼容,以及你代碼中用到的 API 來進行 polyfill,實現了按需添加。
總結 推薦使用."useBuiltIns: usage" 配置他自己動會做幫我們引入'corejs墊片',不用在手動全局引入,并且會對
指定瀏覽器版本進行配合,'注意和entry不同usage 是按需引入并且是和target 匹配,即你用了符合target沒有的墊片才引入'
~~~
* 說明corejs
~~~
1."useBuiltIns: usage"只是會幫你導入 并不會幫你按照corejs 包,因此記住手動安裝corejs
'npm install core-js'
~~~
* 說明'regenerator'
~~~
1.'regenerator' 是 facebook 實現的 'aync' 的 'runtime' 庫,babel 使用 'regenerator-runtime'來支持實現
'async' 'await' 的支持。
2.但是 不用安裝因為 @babel/preset-env 依賴里面有 'regenerator-runtime'
└─┬ @babel/preset-env@7.16.11
└─┬ @babel/plugin-transform-regenerator@7.16.7
└─┬ regenerator-transform@0.14.5
└─┬ @babel/runtime@7.17.2
└── regenerator-runtime@0.13.9
~~~
* 2.2圖 雖然 轉換代碼只是new Promise() 但實際符合target 墊片全部引入

* 2.3.圖 之引入了 Promise 相關的墊片

>[danger] ##### corejs
~~~
1.corejs是JavaScript的模塊化標準庫,其中包括各種ECMAScript特性的polyfill。轉換后代碼中引
入'api'的polyfill都是來源于corejs。它現有2和3兩個版本,目前2版本已經進入功能凍結階段了,新的功能會添加到3版本中。
2.這個選項只有在和 'useBuiltIns: "usage" '或 'useBuiltIns:"entry" '一起使用時才有效果,該屬性默
認為"2.0"。其作用是進一步約束引入的polyfill的數量。
~~~
>[danger] ##### 總結
~~~
1.@babel/preset-env + useBuiltins(entry) + preset-env targets,這樣@babel/preset-env
定義了 Babel 所需插件預設,同時由 Babel 根據 preset-env targets 配置的支持環境,自動按需加載 polyfills,
當 useBuiltins 配置為 usage,它可以真正根據代碼情況,分析 AST(抽象語法樹)進行更細粒度的按需引用
~~~
* 配置的小例子
~~~
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "entry",
targets: { chrome: 44 }
"corejs": 3,
}
]
],
"plugins": []
}
~~~
>[info] ## 上手案例
~~~
1.準備工作安裝'@babel/core' '@babel/cli' '@babel/preset-env'創建好了項目結構目錄
├─ lib
│ └─ index.js
├─ src
│ └─ index.js
├─ babel.config.json // 也可以是.babelrc文件
├─ package-lock.json
├─ package.json
└─ yarn.lock
2.后續執行的指令'npx babel src/index.js --out-dir lib'
3.如果下面'babel.config.json' 文件的內容僅僅是
{
"presets": [
[
"@babel/env"
]
]
}
我們執行第二步的運行指令發現lib文件夾下的index.js輸入如下:
"use strict";
var a = 1;
console.log(a);
var p = new Promise(function (res) {
console.log(res);
});
p.then(function (res) {
console.log(res);
});
'const' 按照我們的期望變成了'var','Promise' 因為是api而不是語法因此沒有轉譯也符合我們的預期
4.現在將'babel.config.json' 修改成下面的形式,但注意了這時候我們制定的'targets'中為 "chrome": "70"
,因為我們的項目不再想執行這令人糟心的ie了,運行指令后在lib文件夾下的index.js輸入如下
"use strict";
const a = 1;
console.log(a);
const p = new Promise(res => {
console.log(res);
});
p.then(res => {
console.log(res);
});
因為谷歌瀏覽器70的版本是完美支持const ,因此babel沒有必要將'const'轉換成'var'
5.這里更多建議配置'.browserslistrc' 因為不單單js可以這種選擇形式根據配置決定,后續如果你了解
'postcss-loader' 發現他也是類似的,我們不將這些控制的文件放在他們所屬指定配置文件中,而是
放到一個全局這種類似都可以統一進行識別文件'.browserslistrc'這樣就可以全局統一管理
~~~
>[danger] ##### useBuiltIns: false 說明

>[danger] ##### "useBuiltIns" 如何做到引入對應的core-js api
~~~
1.為什么在配置"useBuiltIns" 時候可以幫助我們引入core-js 符合對應環境適應的api,主要原因
'@babel/preset-env' 通過 targets 參數,按照 browserslist 規范,結 合'core-js-compat',
篩選出適配環境所需的 polyfills(或 plugins),通過合理配置幫助我們按需引入墊片
~~~
>[danger] ##### 更多配置說明
[當然了實際配置值遠遠大于'modules','useBuiltIns','corejs'配置項更多可以參考官網](https://babeljs.io/docs/en/babel-preset-env#usebuiltins-usage-experimental)
- 工程化 -- Node
- vscode -- 插件
- vscode -- 代碼片段
- 前端學會調試
- 谷歌瀏覽器調試技巧
- 權限驗證
- 包管理工具 -- npm
- 常見的 npm ci 指令
- npm -- npm install安裝包
- npm -- package.json
- npm -- 查看包版本信息
- npm - package-lock.json
- npm -- node_modules 層級
- npm -- 依賴包規則
- npm -- install 安裝流程
- npx
- npm -- 發布自己的包
- 包管理工具 -- pnpm
- 模擬數據 -- Mock
- 頁面渲染
- 渲染分析
- core.js && babel
- core.js -- 到底是什么
- 編譯器那些術語
- 詞法解析 -- tokenize
- 語法解析 -- ast
- 遍歷節點 -- traverser
- 轉換階段、生成階段略
- babel
- babel -- 初步上手之了解
- babel -- 初步上手之各種配置(preset-env)
- babel -- 初步上手之各種配置@babel/helpers
- babel -- 初步上手之各種配置@babel/runtime
- babel -- 初步上手之各種配置@babel/plugin-transform-runtime
- babel -- 初步上手之各種配置(babel-polyfills )(未來)
- babel -- 初步上手之各種配置 polyfill-service
- babel -- 初步上手之各種配置(@babel/polyfill )(過去式)
- babel -- 總結
- 各種工具
- 前端 -- 工程化
- 了解 -- Yeoman
- 使用 -- Yeoman
- 了解 -- Plop
- node cli -- 開發自己的腳手架工具
- 自動化構建工具
- Gulp
- 模塊化打包工具為什么出現
- 模塊化打包工具(新) -- webpack
- 簡單使用 -- webpack
- 了解配置 -- webpack.config.js
- webpack -- loader 淺解
- loader -- 配置css模塊解析
- loader -- 圖片和字體(4.x)
- loader -- 圖片和字體(5.x)
- loader -- 圖片優化loader
- loader -- 配置解析js/ts
- webpack -- plugins 淺解
- eslit
- plugins -- CleanWebpackPlugin(4.x)
- plugins -- CleanWebpackPlugin(5.x)
- plugin -- HtmlWebpackPlugin
- plugin -- DefinePlugin 注入全局成員
- webapck -- 模塊解析配置
- webpack -- 文件指紋了解
- webpack -- 開發環境運行構建
- webpack -- 項目環境劃分
- 模塊化打包工具 -- webpack
- webpack -- 打包文件是個啥
- webpack -- 基礎配置項用法
- webpack4.x系列學習
- webpack -- 常見loader加載器
- webpack -- 移動端px轉rem處理
- 開發一個自己loader
- webpack -- plugin插件
- webpack -- 文件指紋
- webpack -- 壓縮css和html構建
- webpack -- 清里構建包
- webpack -- 復制靜態文件
- webpack -- 自定義插件
- wepack -- 關于靜態資源內聯
- webpack -- source map 對照包
- webpack -- 環境劃分構建
- webpack -- 項目構建控制臺輸出
- webpack -- 項目分析
- webpack -- 編譯提速優護體積
- 提速 -- 編譯階段
- webpack -- 項目優化
- webpack -- DefinePlugin 注入全局成員
- webpack -- 代碼分割
- webpack -- 頁面資源提取
- webpack -- import按需引入
- webpack -- 搖樹
- webpack -- 多頁面打包
- webpack -- eslint
- webpack -- srr打包后續看
- webpack -- 構建一個自己的配置后續看
- webpack -- 打包組件和基礎庫
- webpack -- 源碼
- webpack -- 啟動都做了什么
- webpack -- cli做了什么
- webpack - 5
- 模塊化打包工具 -- Rollup
- 工程化搭建代碼規范
- 規范化標準--Eslint
- eslint -- 擴展配置
- eslint -- 指令
- eslint -- vscode
- eslint -- 原理
- Prettier -- 格式化代碼工具
- EditorConfig -- 編輯器編碼風格
- 檢查提交代碼是否符合檢查配置
- 整體流程總結
- 微前端
- single-spa
- 簡單上手 -- single-spa
- 快速理解systemjs
- single-sap 不使用systemjs
- monorepo -- 工程
- Vue -- 響應式了解
- Vue2.x -- 源碼分析
- 發布訂閱和觀察者模式
- 簡單 -- 了解響應式模型(一)
- 簡單 -- 了解響應式模型(二)
- 簡單 --了解虛擬DOM(一)
- 簡單 --了解虛擬DOM(二)
- 簡單 --了解diff算法
- 簡單 --了解nextick
- Snabbdom -- 理解虛擬dom和diff算法
- Snabbdom -- h函數
- Snabbdom - Vnode 函數
- Snabbdom -- init 函數
- Snabbdom -- patch 函數
- 手寫 -- 虛擬dom渲染
- Vue -- minVue
- vue3.x -- 源碼分析
- 分析 -- reactivity
- 好文
- grpc -- 瀏覽器使用gRPC
- grcp-web -- 案例
- 待續