新一代的编译工具 SWC,97年小哥写的~
大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。
最近前端圈掀起了一陣 rust 風,凡是能用 rust 重寫的前端工具就用 rust 重寫,今天介紹的工具就是通過 rust 實現的 bable:swc,一個將 ES6 轉化為 ES5 的工具。
而且在 swc 的官網,很直白說自己和 babel 對標,swc 和 babel 命令可以相互替換,并且大部分的 babel 插件也已經實現。
使用 rust 的一個優勢就是快,比如我們之前的一個項目,將 babel 替換成 swc 后,編譯速度從原來的 7 秒提升到了 1 秒,效率直接爆炸。
上手
swc 與 babel 一樣,將命令行工具、編譯核心模塊分化為兩個包。
@swc/cli 類似于 @babel/cli;
@swc/core 類似于 @babel/core;
通過如下命令,可以將一個 ES6 的 JS 文件轉化為 ES5。
npx?swc?source.js?-o?dist.js下面是 source.js 的代碼:
const?start?=?()?=>?{console.log('app?started') }代碼中囊括了 ES6 的兩個特性,const 聲明 和 箭頭函數。經過 swc 轉化后,這兩個特性分別被轉化成了 var 聲明 和 function 匿名函數。
配置文件
swc 與 babel 一樣,支持類似于 .babelrc 的配置文件:.swcrc,配置的格式為 JSON。
{"jsc":?{?//?編譯規則"target":?"es5",?//?輸出js的規范"parser":?{//?除了?ecmascript,還支持?typescript"syntax":?"ecmascript",//?是否解析jsx,對應插件?@babel/plugin-transform-react-jsx"jsx":?false,//?是否支持裝飾器,對應插件?@babel/plugin-syntax-decorators"decorators":?false,//?是否支持動態導入,對應插件?@babel/plugin-syntax-dynamic-import"dynamicImport":?false,//?……//?babel?的大部分插件都能在這里找到對應配置},"minify":?{},?//?壓縮相關配置,需要先開啟壓縮},"env":?{?//?編譯結果相關配置"targets":?{?//?編譯結果需要適配的瀏覽器"ie":?"11"?//?只兼容到?ie?11},"corejs":?"3"?//?corejs?的版本},"minify":?true?//?是否開啟壓縮 }babel 的插件系統被 swc 整合成了 jsc.parser 內的配置,基本上大部分插件都能照顧到。而且,swc 還繼承了壓縮的能力,通過 minify 屬性開啟,jsc.minify 用于配置壓縮相關的規則,更詳細的配置可查看文檔。
Node APIs
通過在 node.js 代碼中,導入 @swc/core 模塊,可以在 node.js 中調用 api 直接進行代碼的編譯,這對 CLI 工具的開發來說是常規操作。
//?swc.mjs import?{?readFileSync?}?from?'fs' import?{?transform?}?from?'@swc/core'const?run?=?async?()?=>?{const?code?=?readFileSync('./source.js',?'utf-8')const?result?=?await?transform(code,?{filename:?"source.js",})//?輸出編譯后代碼console.log(result.code) }run()打包代碼
除了將代碼轉義,swc 還提供了一個簡易的打包能力。我們新建一個 src 文件夾,在里面新建兩個文件:index.js、utils.js。
//?src/index.js import?{?log?}?from?'./utils.js' const?start?=?()?=>?log('app?started') start()//?src/utils.js export?const?log?=?function?()?{console.log(...arguments) } export?const?errorLog?=?function?()?{console.error(...arguments) }可以看到 index.js 導入了 utils.js 中的一個方法,然后我們新建一個 spack.config.js 文件,該文件是 swc 打包的配置文件。
//?spack.config.js module.exports?=?{entry:?{//?打包的入口web:?__dirname?+?"/src/index.js",},output:?{//?打包后輸出的文件夾path:?__dirname?+?"/dist",}, };然后在命令行運行:
$?npx?spack打包成功后,會在 dist 目錄輸出一個 web.js 文件。
可以看到,不僅將 index.js、utils.js 打包成了一個文件,還進行了 tree shaking,將 utils.js 中沒有使用的 errorLog 方法刪掉了。
能不能用?
babel 畢竟經過了這么多年的發展,不管是 bug 輸了,還是社區活躍度都遠遠優于 swc。所以,如果是小產品試水還是可以試一下 swc 的,舊項目如果已經使用了 babel 還是不建議進行遷移。
在使用的過程,還是發現了一些小問題。比如,如果我使用了 async function,swc 會自動導入 regenerator-runtime 模塊。
//?編譯前,有個?async?方法 const?start?=?async?()?=>?{console.log('app?started') }調用 swc 編譯后,代碼如下:
這個結果看起來是沒問題的,但是 swc 與 babel 類似,也有 helpers(@swc/helpers),同時提供了 externalHelpers 開關, 如果把 externalHelpers 設置為 true,swc 會將一些工具類,通過模塊的形式導入。
//?.swcrc {"jsc":?{"externalHelpers":?true} }而 externalHelpers 的默認值是 false,那這個時候,regenerator-runtime ,到底是通過模塊的形式導入,還是把整個代碼寫入到文件?
swc 正好有個 issue [https://github.com/swc-project/swc/issues/1461] 在討論這個問題。
除了上面說的這個問題,其實還有一點,就是作者覺得之前的架構有問題,正在加緊重寫 2.0 版本,感覺可以期待一下,另外提一句,swc 的作者是一個 97 年的韓國小哥,目前大學都還沒畢業,最后我也只能說一句:牛逼!
- END -·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。分享、收藏、點贊、在看我的文章就是對我最大的支持~
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的新一代的编译工具 SWC,97年小哥写的~的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lisp6 暖通cad_这些高效插件,学
- 下一篇: 前端学习(2954):vue文件的三大组