<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          新一代的編譯工具 SWC

          共 3249字,需瀏覽 7分鐘

           ·

          2022-02-09 23:50

          最近前端圈掀起了一陣 rust 風(fēng),凡是能用 rust 重寫的前端工具就用 rust 重寫,今天介紹的工具就是通過 rust 實(shí)現(xiàn)的 bable:swc,一個將 ES6 轉(zhuǎn)化為 ES5 的工具。

          而且在 swc 的官網(wǎng),很直白說自己和 babel 對標(biāo),swcbabel 命令可以相互替換,并且大部分的 babel 插件也已經(jīng)實(shí)現(xiàn)。

          使用 rust 的一個優(yōu)勢就是快,比如我們之前的一個項目,將 babel 替換成 swc 后,編譯速度從原來的 7 秒提升到了 1 秒,效率直接爆炸。

          上手

          swc 與 babel 一樣,將命令行工具、編譯核心模塊分化為兩個包。

          • @swc/cli 類似于 @babel/cli;
          • @swc/core 類似于 @babel/core;
          npm?i?-D?@swc/cli?@swc/core

          通過如下命令,可以將一個 ES6 的 JS 文件轉(zhuǎn)化為 ES5。

          npx?swc?source.js?-o?dist.js

          下面是 source.js 的代碼:

          const?start?=?()?=>?{
          ??console.log('app?started')
          }

          代碼中囊括了 ES6 的兩個特性,const 聲明箭頭函數(shù)。經(jīng)過 swc 轉(zhuǎn)化后,這兩個特性分別被轉(zhuǎn)化成了 var 聲明function 匿名函數(shù)。

          配置文件

          swc 與 babel 一樣,支持類似于 .babelrc 的配置文件:.swcrc,配置的格式為 JSON。

          {
          ??"jsc":?{?//?編譯規(guī)則
          ????"target":?"es5",?//?輸出js的規(guī)范
          ????"parser":?{
          ??????//?除了?ecmascript,還支持?typescript
          ??????"syntax":?"ecmascript",
          ??????//?是否解析jsx,對應(yīng)插件?@babel/plugin-transform-react-jsx
          ??????"jsx":?false,
          ??????//?是否支持裝飾器,對應(yīng)插件?@babel/plugin-syntax-decorators
          ??????"decorators":?false,
          ??????//?是否支持動態(tài)導(dǎo)入,對應(yīng)插件?@babel/plugin-syntax-dynamic-import
          ??????"dynamicImport":?false,
          ??????//?……
          ??????//?babel?的大部分插件都能在這里找到對應(yīng)配置
          ????},
          ????"minify":?{},?//?壓縮相關(guān)配置,需要先開啟壓縮
          ??},
          ??"env":?{?//?編譯結(jié)果相關(guān)配置
          ????"targets":?{?//?編譯結(jié)果需要適配的瀏覽器
          ??????"ie":?"11"?//?只兼容到?ie?11
          ????},
          ????"corejs":?"3"?//?corejs?的版本
          ??},
          ??"minify":?true?//?是否開啟壓縮
          }

          babel 的插件系統(tǒng)被 swc 整合成了 jsc.parser 內(nèi)的配置,基本上大部分插件都能照顧到。而且,swc 還繼承了壓縮的能力,通過 minify 屬性開啟,jsc.minify 用于配置壓縮相關(guān)的規(guī)則,更詳細(xì)的配置可查看文檔。

          Node APIs

          通過在 node.js 代碼中,導(dǎo)入 @swc/core 模塊,可以在 node.js 中調(diào)用 api 直接進(jìn)行代碼的編譯,這對 CLI 工具的開發(fā)來說是常規(guī)操作。

          //?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()

          打包代碼

          除了將代碼轉(zhuǎn)義,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 導(dǎo)入了 utils.js 中的一個方法,然后我們新建一個 spack.config.js 文件,該文件是 swc 打包的配置文件。

          //?spack.config.js
          module.exports?=?{
          ??entry:?{
          ????//?打包的入口
          ????web:?__dirname?+?"/src/index.js",
          ??},
          ??output:?{
          ????//?打包后輸出的文件夾
          ????path:?__dirname?+?"/dist",
          ??},
          };

          然后在命令行運(yùn)行:

          $?npx?spack

          打包成功后,會在 dist 目錄輸出一個 web.js 文件。

          可以看到,不僅將 index.js、utils.js 打包成了一個文件,還進(jìn)行了 tree shaking,將 utils.js 中沒有使用的 errorLog 方法刪掉了。

          能不能用?

          babel 畢竟經(jīng)過了這么多年的發(fā)展,不管是 bug 輸了,還是社區(qū)活躍度都遠(yuǎn)遠(yuǎn)優(yōu)于 swc。所以,如果是小產(chǎn)品試水還是可以試一下 swc 的,舊項目如果已經(jīng)使用了 babel 還是不建議進(jìn)行遷移。

          在使用的過程,還是發(fā)現(xiàn)了一些小問題。比如,如果我使用了 async function,swc 會自動導(dǎo)入 regenerator-runtime 模塊。

          //?編譯前,有個?async?方法
          const?start?=?async?()?=>?{
          ??console.log('app?started')
          }

          調(diào)用 swc 編譯后,代碼如下:

          這個結(jié)果看起來是沒問題的,但是 swc 與 babel 類似,也有 helpers(@swc/helpers),同時提供了 externalHelpers 開關(guān), 如果把 externalHelpers 設(shè)置為 true,swc 會將一些工具類,通過模塊的形式導(dǎo)入。

          //?.swcrc
          {
          ??"jsc":?{
          ????"externalHelpers":?true
          ??}
          }

          externalHelpers 的默認(rèn)值是 false,那這個時候,regenerator-runtime ,到底是通過模塊的形式導(dǎo)入,還是把整個代碼寫入到文件?

          swc 正好有個 issue [https://github.com/swc-project/swc/issues/1461] 在討論這個問題。

          除了上面說的這個問題,其實(shí)還有一點(diǎn),就是作者覺得之前的架構(gòu)有問題,正在加緊重寫 2.0 版本,感覺可以期待一下,另外提一句,swc 的作者是一個 97 年的韓國小哥,目前大學(xué)都還沒畢業(yè),最后我也只能說一句:牛逼!

          - END -


          瀏覽 80
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91影院成人| 第14色网站 | 操我综合| 水多多视频| 91n成人久久 |