用 gogocode 輕鬆寫 webpack、vite 等打包插件

引言

gogocode 是一個精緻小巧、功能強大的代碼處理工具,單獨使用能夠輕鬆地批量處理本地代碼。若是和 webpack、babel、rollup 甚至還有 vite! 等打包工具結合,就能使得編譯後的結果更加靈活,達到事半功倍的效果!javascript

本文來自 QQ 羣(735216094)裏用戶「墨明棋妙」的建議:java

image.png

做爲百依百順的項目組,那如今咱們就經過一個簡單的用例,帶你們研究在這些打包工具中如何完美融入 gogocode!node

測試用例

// input1.js
import increaser from './input2'
var num = 1
var str = 'foo'
var boo = false
var fn = () => {
    console.log(boo)
}
var b = window.localStorage.getItem(str)
var num2 = increaser(num)

fn()
console.log(num2, boo)
alert(b)

// input2.js
var increaser = function (x) {
    return x + 1
}
export default increaser
複製代碼

在本例中,咱們將設計的一個簡單的插件,將代碼中的 var 通過打包所有改成 let。webpack

本文做者:冰塊git

babel

完整代碼:github.com/thx/gogocod…github

安裝依賴

npm i babel-cli			// 依賴babel-cli運行babel插件
npm i gogocode			// 依賴gogocode完成代碼轉換
複製代碼

配置.babelrc

{
  "plugins": [ "./plugin" ]			// plugin爲你編寫的插件的文件名
}
複製代碼

編寫插件

babel插件經過 visitor 能夠取到各類類型的 ast 節點。 咱們在visitor中定義Program(path) {},能夠拿到完整代碼對應的 ast,也就是path.node,使用$()實例化path.node,便可經過 gogocode 進行豐富的操做。web

const $ = require('gogocode')
module.exports = function () {
  return {
    name: "transform-var-to-let",
    visitor: {
      Program(path) {
        $(path.node).replace('var $_$1 = $_$2;', 'let $_$1 = $_$2;')
      }
    }
  };
};
複製代碼

命令行運行

當前目錄下執行:npm

npx babel --plugins ./plugin.js ./input1.js
複製代碼

附目錄結構:bash

image.png

webpack

完整代碼:github.com/thx/gogocod…babel

安裝依賴

npm i webpack webpack-cli -D 	 // 安裝 webpack 腳手架
npm i gogocode -D 		 // 安裝 gogocode
複製代碼

編寫插件

編寫一個 var 轉爲 let 的插件,僅須要咱們用到 webpack 插件中最基礎的知識。 您只須要知道,webpack 的插件是一個類,在 webpack 的最初階段,會初始化全部的插件並註冊他們。在那以後,webpack 會在編譯的不一樣的階段,調用其鉤子上註冊的全部插件,以實現文件的代碼轉換和編譯流程控制。

(參考下面的例子閱讀效果更佳)

插件必須實現 apply 實例方法,供 webpack 在初始化階段時調用,它接受一個 compiler 參數,該參數經過調用 compiler.hooks.<hooksName>.<tapMethod> 容許您訪問編譯階段的鉤子並進行掛載。掛載方式(tapMethod)分紅 tap tapAsync tapPromise 等多種,經過它來告訴 webpack 使用同步 / 異步的方式訪問這些鉤子,這是由工具 tapable 提供的。在不一樣的鉤子下會有不一樣的上下文供您調用,容許您對傳入的數據作改動。

在本例中僅需讓 compiler 調用 emit 鉤子,並使用同步方式 tap 訪問便可。

// transform-var-to-let-plugin.js

const $ = require('gogocode')

const pluginName = 'TransformVarToLetPlugin'

class TransformVarToLetPlugin {
    apply (compiler) {
        compiler.hooks.emit.tap(pluginName, compilation => {
            Object.keys(compilation.assets).forEach(item => {
                // .source() 是獲取構建產物的文本
                // .assets 中包含構建產物的文件名
                let content = compilation.assets[item].source()
                let ast = $(content).replace('var $_$1 = $_$2', 'let $_$1 = $_$2')
                content = ast.generate()
                // 更新構建產物對象
                compilation.assets[item] = {
                    source: () => content,
                    size: () => content.length,
                }
            })
        })
    }
}

module.exports = TransformVarToLetPlugin

複製代碼

配置 webpack.config.js

引入咱們剛剛編寫好的 transform-var-to-let-plugin,在 plugins 配置項中建立它的實例便可。爲了更好的展現打包以後的效果,咱們將 mode 設置爲 development

const Plugin = require('./plugin')

const path = require('path')

module.exports = {
    mode: 'development',
    entry: './input1.js',
    output: {
        path: path.resolve(__dirname, './dist'),
    },
    plugins: [
        new Plugin()
    ],
}
複製代碼

命令行運行

當前目錄下執行,便可在 dist 文件夾中看到編譯後的內容

npx webpack
複製代碼

附目錄結構:

image.png

rollup

完整代碼:github.com/thx/gogocod…

安裝依賴

npm i rollup -D 	// 安裝 rollup
npm i gogocode -D       // 安裝 gogocode
複製代碼

編寫插件

與 webpack 不一樣的是,rollup 的 compiler 相對比較簡單。rollup 的插件是一個函數,返回一個對象,對象中僅需實現 rollup 規定的生命週期鉤子便可。 在本例中咱們僅需實現 transform 函數,返回處理後的新代碼:

const $ = require('gogocode')

const transformVarToLetRollupPlugin = () => {
    return {
        name: 'transformVarToLetRollupPlugin',
        transform(code) {
            return {
                code: $(code).replace('var $_$1 = $_$2', 'let $_$1 = $_$2').generate()
            }
        },
    }
}
module.exports = transformVarToLetRollupPlugin
複製代碼

rollup 的插件必須以 rollup-plugin- 前綴爲開頭。但本例的情形相對簡單,故未如此作。

配置 rollup.config.js

const plugin = require('./plugin')

module.exports = {    
    input:'input1.js',
    output: {
        file: './dist/bundle.js',
        format: 'cjs',
    },
    plugins: [
        plugin(),
    ],
}

複製代碼

命令行運行

當前目錄下執行

npx rollup -c rollup.config.js
複製代碼

附目錄結構:

image.png

vite

完整代碼:github.com/thx/gogocod…

安裝依賴

npm i vite -D				// 安裝 vite
npm i gogocode -D		// 安裝 gogocode
複製代碼

編寫插件

vite 插件系統向後兼容 rollup 插件,僅比 rollup 多幾個生命週期。所以咱們直接複用以前寫好的 rollup 插件。

vite 的插件必須以 vite-plugin- 前綴爲開頭。以和 rollup-plugin 做區分。

配置 vite.config.js

vite 和 webpack 同樣是開箱即用的,所以爲了看清打包後的內容,咱們針對性地更換掉一些配置。

import { defineConfig } from 'vite'
import plugin from './plugin'

export default defineConfig({
    build: {
        minify: false,	// 關閉混淆
        rollupOptions: {
            input: './input1.js',	//改變 input 目錄
        },
    },
    plugins: [plugin()]
})
複製代碼

命令行運行

npx vite build
複製代碼

附目錄結構:

image.png


經過這幾個示例,咱們瞭解瞭如何在這些現代使用 gogocode。 如今 vite 上還有不少基礎插件沒有被覆蓋。歡迎你們使用 gogocode 開發 vite 插件~!

GoGoCode 相關連接

GoGoCode的Github倉庫(新項目求star ^_^) github.com/thx/gogocod…

GoGoCode的官網 gogocode.io/

能夠來 playground 快速體驗一下 play.gogocode.io/


阿里媽媽出的新工具,給批量修改項目代碼減輕了痛苦
「GoGoCode 實戰」一口氣學會 30 個 AST 代碼替換小訣竅
0成本上手AST,用GoGoCode解決Vue2遷移Vue3難題
GoGoCode協助清理代碼中的「垃圾」

相關文章
相關標籤/搜索