vscode 任務(wù)配置參數(shù)及任務(wù)結(jié)果分析

2022-07-11 10:43 更新

任務(wù)系統(tǒng)的知識(shí)體系相對(duì)復(fù)雜,今天繼續(xù)介紹任務(wù)系統(tǒng)的內(nèi)容:任務(wù)配置的更多參數(shù)以及任務(wù)結(jié)果的分析功能。

Command相關(guān)屬性和特殊處理

在自定義的任務(wù)里可以使用 command 屬性,并在這個(gè)屬性里指定我們想要運(yùn)行的腳本或者程序。但是有的時(shí)候我們運(yùn)行這個(gè)腳本的時(shí)候需要傳入一些參數(shù),這時(shí)候就可以簡單地把這些參數(shù)全部寫在 command 里,比如說在運(yùn)行 echo ‘Hello World’ 這樣的腳本時(shí),我們可以把它直接放入 command 這個(gè)屬性的值中:

{
  "label": "echo",
  "type": "shell",
  "command": "echo 'Hello World'"
}

JSON

我們也可以使用一個(gè)新的屬性,叫做args。它是一個(gè)字符串的數(shù)組,在運(yùn)行指定 command 的時(shí)候,args 里的每個(gè)值都會(huì)被當(dāng)作其參數(shù)傳入,所以就上面的例子,我們還可以寫為:

{
 "label": "echo",
 "type": "shell",
 "command": "echo",
 "args": [
  "hello world"
 ]
}

JSON

但這里要注意的是,因?yàn)槲覀兪褂玫氖?JSON 來存儲(chǔ)這些參數(shù),而 JSON 的數(shù)據(jù)格式并不一定能夠滿足 shell 的要求,比如不同的 shell 對(duì)空白符、$ 符之類的都有不同的解析方式,這時(shí)候就需要對(duì)這些符號(hào)進(jìn)行轉(zhuǎn)義。我們可以將參數(shù)調(diào)整為下面的格式:

"args": [
        {
            "value": "Hello World",
            "quoting": "escape"
        }
]

JSON

我們可以看到,args 里的值,從一個(gè)字符串,變成一個(gè)對(duì)象。它的第一個(gè)鍵是 value 值,也就是原先的字符串,而第二個(gè)鍵 quoting 則決定了該如何處理這段字符串。

quoting在默認(rèn)情況下是使用escape轉(zhuǎn)義,也就是說任務(wù)系統(tǒng)會(huì)根據(jù)我們所使用的 shell 的要求,對(duì)這段字符串進(jìn)行轉(zhuǎn)義。比如說,bash 下我們使用\來轉(zhuǎn)義特殊字符,那么當(dāng)我們執(zhí)行這個(gè)任務(wù)時(shí),真正運(yùn)行的腳本如下:

echo Hello\ World

Shell

從上面的代碼示例里,你可以看到空格被轉(zhuǎn)義成了 \ 。

除此之外,quoting 這個(gè)參數(shù)還有另外兩個(gè)值。第一個(gè)是 strong,那么在 bash里, 我們將會(huì)使用單引號(hào)包裹這段字符串,然后傳給腳本,那么最終執(zhí)行的腳本是:

echo 'Hello World'

Shell

另一個(gè)值是 weak,在 bash 里我們則會(huì)使用雙引號(hào)來包裹這段字符串。如:

echo "Hello World"

Shell

strong 和 weak 分別對(duì)應(yīng)了 shell 不同的使用引號(hào)的策略,而bash、cmd、powershell 也都有各自的策略。如果你不熟悉,可以搜索 “quoting mechanism” 來查找,當(dāng)然我們?cè)?a rel="external nofollow" target="_blank" target="_blank">VS Code關(guān)于 Task 參數(shù)轉(zhuǎn)義部分的文檔也有涉及。

對(duì)了,當(dāng)你在 VS Code 里編輯這個(gè) tasks.json 文件的時(shí)候是提供了自動(dòng)補(bǔ)全和提示的,所以你可以看看它還支持什么別的屬性,也可以試著根據(jù)提示進(jìn)行修改。我們?cè)谖恼碌淖詈?,還會(huì)介紹幾個(gè)其他重要的屬性的。

結(jié)果分析

到這里我已經(jīng)基本把任務(wù)系統(tǒng)是如何設(shè)置的、如何運(yùn)行的跟你簡單地介紹了一遍,相信你已經(jīng)可以將一些簡單的腳本用任務(wù)系統(tǒng)來執(zhí)行了。但是如果說任務(wù)系統(tǒng)只是提供一種新的運(yùn)行腳本的方式,或者說幾個(gè)快捷鍵進(jìn)行一鍵的腳本運(yùn)行的話,那跟集成終端比只能說是往前邁了小小的一步。

不過,任務(wù)系統(tǒng)還有一個(gè)真正的威力,就是我們可以自動(dòng)地去分析任務(wù)運(yùn)行的結(jié)果。

任務(wù)運(yùn)行的結(jié)果是由 tasks.json 里任務(wù)的一個(gè)屬性 problemMatcher 來控制的。我們可以選擇 VS Code 內(nèi)置的,或者其他插件提供的結(jié)果分析器,甚至可以自己書寫結(jié)果分析器來分析任務(wù)運(yùn)行結(jié)果,然后將其中出現(xiàn)的錯(cuò)誤或者警告,顯示在問題面板中。

比如說我們跑一個(gè)構(gòu)建腳本,有的時(shí)候代碼寫的不對(duì)了,構(gòu)建腳本就會(huì)打印出在哪個(gè)文件的第幾行有一個(gè)什么類型的錯(cuò)誤,然后我們?cè)俳柚线m的結(jié)果分析器,去解析相對(duì)冗余的結(jié)果日志,最后把它們?nèi)雴栴}面板中。這樣我們?cè)跁鴮懙倪^程當(dāng)中,就不需要到結(jié)果日志里去找錯(cuò)誤和警告了,只需要查看問題面板,點(diǎn)擊錯(cuò)誤跳轉(zhuǎn)到代碼處,直接進(jìn)行修改就可以了。

另外,如果我們?cè)谶\(yùn)行一些腳本的時(shí)候使用了觀察模式 (watch mode),那么每次代碼有更新,就會(huì)重新運(yùn)行腳本輸出日志,這時(shí)一個(gè)實(shí)時(shí)分析日志并提供反饋的結(jié)果分析器就大大提升效率了。

VS Code 現(xiàn)在已經(jīng)自帶了以下幾種問題分析器:

  • $tsc,用于分析 TypeScript 編譯的結(jié)果,$tsc-watch 則是用于分析運(yùn)行在觀察模式下的 TypeScript 編譯器的結(jié)果;
  • $jshint用于分析 JSHint 的結(jié)果,$jshint-stylish 用于分析JSHint Stylish的運(yùn)行結(jié)果;
  • $eslint-compact 和 $eslint-stylish 分別用于分析 ESLint Compact 和 ESLint Stylish;
  • $go 是 Go 編譯器的分析器;
  • $mscompile 用于分析 CSharp 和 VB 的編譯結(jié)果;
  • $lessc 是用于分析 Lessc 的運(yùn)行結(jié)果的;
  • $node-sass 用于分析 Node Sass 編譯結(jié)果。

如果這些還不適用于你的項(xiàng)目,那你可以看看插件市場上有沒有問題分析器相關(guān)的插件Search results – problem matcher | Visual Studio Code , Visual Studio Marketplace,或者看看你使用的語言插件是否已經(jīng)支持了相對(duì)應(yīng)的結(jié)果分析。

自定義問題分析器

VS Code 還支持我們自己書寫結(jié)果分析器,不過這個(gè)涉及一定的正則表達(dá)式的知識(shí),如果你已經(jīng)有所了解,那么可以繼續(xù)看下去。如果還未有涉及,還請(qǐng)學(xué)習(xí)正則表達(dá)式,然后閱讀下面的示例。

首先我們將下面的配置,放入任務(wù)配置文件 tasks.json。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo",
            "args": [
                {
                    "value": "index.js:5:3: warning: unused variable",
                    "quoting": "escape"
                }
            ],
            "problemMatcher": {
                "owner": "echo",
                "fileLocation": ["relative", "${workspaceFolder}"],
                "pattern": {
                    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5
                }
            }
        }
    ]
}

JSON

這個(gè)示例,較之前我們介紹的示例,多一個(gè) problemMatcher,其他都是一樣的。但是這個(gè) problemMatcher 不再是一個(gè)字符串,而是一個(gè)對(duì)象;我們?cè)谶@個(gè)對(duì)象里,自定義了如何去分析任務(wù)運(yùn)行的結(jié)果。

這個(gè)任務(wù)執(zhí)行的腳本是:

echo index.js:5:3:\ warning:\ unused\ variable

Shell

在 bash 下執(zhí)行的結(jié)果如下:

index.js:5:3: warning: unused variable

這是我們通常能夠看到的構(gòu)建或者測試腳本報(bào)錯(cuò)時(shí)的輸出結(jié)果,我們需要從中把以下幾個(gè)信息提取出來:

  • 文件地址
  • 行號(hào)
  • 列號(hào)
  • 錯(cuò)誤的重要級(jí)別
  • 錯(cuò)誤信息

通過文件的地址、行號(hào)和列號(hào),我們能夠快速定位到錯(cuò)誤的位置,而錯(cuò)誤的級(jí)別和信息則能夠幫助我們了解錯(cuò)誤的具體情況。為了把這個(gè)信息提取出來,我們將會(huì)使用正則表達(dá)式的捕獲組(group capture)。比如在我們的例子里,我們提供了一個(gè)正則表達(dá)式:

"^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$"

當(dāng)我們拿這個(gè)正則表達(dá)式去匹配下面的字符串時(shí),

index.js:5:3: warning: unused variable

捕獲組 1 對(duì)應(yīng)的是文件的名字,捕獲組 2 則是行號(hào),以此類推。然后我們通過給這個(gè)任務(wù)的 problemMatcher 設(shè)置 pattern 來告訴 VS Code,我們想使用什么樣的正則表達(dá)式去匹配,以及文件名 file、行號(hào) line 、列 column 等該從第幾個(gè)捕獲組讀取出來。

"pattern": {
    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
    "file": 1,
    "line": 2,
    "column": 3,
    "severity": 4,
    "message": 5
}

JSON

除了 pattern 這個(gè)屬性,我們還需要 fileLocation 文件位置來告訴 VS Code,如何在當(dāng)前文件夾下定位這個(gè)文件。比如我們從錯(cuò)誤信息里得到 index.js 是一個(gè)相對(duì)的地址,然后我們通過把 fileLocation 設(shè)置為 [“relative”, “${workspaceFolder}”] 來提示 VS Code,請(qǐng)把 index.js當(dāng)作相對(duì)地址,然后在當(dāng)前文件夾下定位。

最后,當(dāng)我們運(yùn)行了這個(gè)任務(wù),我們就能夠在問題面板里看到這個(gè)錯(cuò)誤信息,而當(dāng)我們點(diǎn)擊這個(gè)錯(cuò)誤時(shí),則能夠在編輯器里打開 index.js 這個(gè)文件并跳轉(zhuǎn)到第五行。

上面就是一個(gè)非?;A(chǔ)的問題分析器 problemMatcher 了。它能夠逐行使用正則表達(dá)式分析任務(wù)執(zhí)行的結(jié)果,并輸出給問題面板。但是如果你的任務(wù)執(zhí)行的結(jié)果里,錯(cuò)誤信息橫跨多行,那么這個(gè)分析器就不起作用了。這時(shí)候你就需要一個(gè)更強(qiáng)大的多行結(jié)果分析器,這個(gè)我會(huì)在后面的 VS Code 高級(jí)定制章節(jié)里進(jìn)一步介紹,如果你非常感興趣現(xiàn)在就想動(dòng)手試一試的話,也可以閱讀Tasks in Visual Studio Code 自行學(xué)習(xí)。

多任務(wù)

很多時(shí)候,我們的項(xiàng)目并不只包含一種語言、一個(gè)框架,這導(dǎo)致我們需要同時(shí)使用多種不同的構(gòu)建或者測試工具,并需要額外寫一些腳本把它們同時(shí)運(yùn)行起來。不過不用擔(dān)心,VS Code 的任務(wù)系統(tǒng)也為這種情況提供了便捷的任務(wù)定制方案。比如說我們的項(xiàng)目里有前端和后端兩種代碼,然后我們希望同時(shí)把它們運(yùn)行起來,這時(shí)我們就要首先為前、后端分別定義好各自的任務(wù),這里我們將它們稱為 “frontend”“backend”。我們可以新建一個(gè)任務(wù),內(nèi)容如下:

{
 "taskName": "compile",
 "dependsOn": [
  "frontend",
  "backend"
 ],
 "group": {
  "kind": "build",
  "isDefault": true
 }
}

JSON

這個(gè)任務(wù)有個(gè)新的屬性,叫做 dependsOn。它指定了“compile”這個(gè)任務(wù)依賴于 “frontend” 和 “backend” 這兩個(gè)腳本,而這個(gè)任務(wù)本身并沒有制定任何的命令 (command),同時(shí)我們還制定了這個(gè)任務(wù)為默認(rèn)的生成任務(wù)(build),所以當(dāng)我們按下 Cmd + Shift + B,我們就能夠看到“frontend” 和 “backend” 這兩個(gè)任務(wù)都被觸發(fā)執(zhí)行了。

通過多任務(wù)的設(shè)置,我們就真正做到一鍵運(yùn)行了。不過要注意,這個(gè)功能在 VS Code 里叫做 Compound tasks ,這可能并不是一個(gè)特別好記的英文名字。

總結(jié)

以上就是我們今天的全部內(nèi)容了。VS Code 的任務(wù)系統(tǒng),在我看來,精髓全在這個(gè) tasks.json 的書寫,也就是說一個(gè) JSON 對(duì)象,控制了任務(wù)的方方面面。而我只是根據(jù)我的理解和學(xué)習(xí)方式,為你做了一次梳理:

  • VS Code 和一些語言相關(guān)的插件,能夠自動(dòng)檢測我們本地已經(jīng)有的任務(wù)腳本配置,這樣我們就能夠直接使用任務(wù)系統(tǒng)去直接執(zhí)行它們了。你不妨看看,你的項(xiàng)目里正在使用的任務(wù)腳本,是否能夠被 VS Code 檢測出來?如果不能,那有沒有插件能夠做到這點(diǎn)呢?
  • 我們可以將自動(dòng)檢測出來的任務(wù),以 tasks.json 的形式儲(chǔ)存在 .vscode 文件夾中,成為項(xiàng)目的一部分。同時(shí),我們也可以在 tasks.json 中,對(duì)它們進(jìn)行修改定制。
  • 除了自動(dòng)檢測,我們還能夠自己書寫自定義的任務(wù),在書寫自定義任務(wù)配置時(shí),有以下幾個(gè)要點(diǎn):在處理腳本或者文件地址的時(shí)候,我們要非常小心。比如說在指定 command 的時(shí)候,我們使用了絕對(duì)地址,那這個(gè)地址在其他同事的機(jī)器上就不一定存在了;而如果我們使用了當(dāng)前文件夾下的相對(duì)地址,或者說使用預(yù)定義變量 ${workspaceFolder},就能很好地避免了這樣的問題。我們要考慮不同操作系統(tǒng)可能對(duì)格式有不同的要求。如果遇到了類似的問題,我們可以為某個(gè)特定的操作系統(tǒng)指定配置。我們可以指定默認(rèn)的 Build 或者 Test 任務(wù),以及使用多任務(wù),爭取做到一鍵執(zhí)行。
  • 任務(wù)結(jié)果的分析也很重要,雖然我們能夠去閱讀任務(wù)腳本的全部輸出結(jié)果,自己去查找錯(cuò)誤,但是如果我們使用了合適的錯(cuò)誤分析器,就能夠?qū)㈠e(cuò)誤和警告自動(dòng)放入到問題面板中。

對(duì)一個(gè)個(gè)體而言,任務(wù)系統(tǒng)的優(yōu)勢可能還不明顯。但是如果你通過設(shè)置任務(wù)系統(tǒng)、添加錯(cuò)誤分析器,把工作流程針對(duì) VS Code 進(jìn)行一次優(yōu)化,這樣你的同事在使用 VS Code 的時(shí)候,也就可以直接使用 VS Code 的任務(wù)系統(tǒng)和問題面板了,而無需為命令行腳本工具而煩惱了。

當(dāng)然,你熟悉完我上面所講的那些知識(shí)點(diǎn)后,可能還會(huì)有更多的問題提出來,我們可以在討論區(qū)里交流。另外,我也鼓勵(lì)你自己動(dòng)手調(diào)試這個(gè)文件,VS Code 為這個(gè)文件做了專門的自動(dòng)補(bǔ)全,所以你可以通過提示來研究學(xué)習(xí)。由于篇幅所限,我可能無法將任務(wù)系統(tǒng)的每個(gè)知識(shí)點(diǎn)都覆蓋到,比如說任務(wù)系統(tǒng)的配置支持預(yù)定義參數(shù),但是這個(gè)知識(shí)點(diǎn)我們?cè)诮榻B代碼片段里涉及到了,如果你對(duì)代碼片段的預(yù)定義參數(shù)很熟悉,這個(gè)也就不陌生了。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)