整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          “改造”VS Code 編輯器,一起寫個插件吧

          者:HelloGitHub-小夏

          作為一個靠代碼作為“生計”的開發者,bug 寫得好不好,編輯器真的很重要!那么 Visual Studio Code 這個大名你肯定不會陌生。作為一個老厲害的編輯器,它的過人之處簡單講講來說有這么幾點:

          • 首先,它的設計者是一個很有名的工程師:Eric Gamma。20年前,他是《設計模式:可復用面向對象軟件的基礎》的作者之一,這本書在開發社區的地位被視為面向對象軟件開發的指路明燈(瞻望大佬)。
          • 其次,對于寫 JavaScript 的人來說,雖然市面上有很多大大小小不同的編輯器,比如 sublime、atom、webstorm 等等,VS Code 與他們區別在于他比 sublime 開源,比 atom 更快,比 webstorm 更輕。

          一、介紹

          VS Code 全名 Visual Studio Code 是微軟開源的一款編輯器,GitHub 上標星 115k(11 萬)。它是基于 TypeScript 編寫,總計代碼數量在 30 萬以上,大型知名開源項目。

          我們先來簡單看一下它的產品定位吧~可以看到,項目作者對它的定位屬于輕量級的編輯器,所以要求它輕量、響應速度快,適用于多種語言等等。VS Code 的編輯能力來自于一款同樣來自微軟叫做 monaco 的開源 Web 編輯器,同時為了實現跨平臺的需求又引入了 Electron:一個使用 JavaScript,HTML 和 CSS 構建跨平臺的桌面應用程序。

          正因為有了清楚的定位和方向,才會有了更加清晰的邊界。或許你很疑惑,他是怎么支持多種語言的又做到輕量級的?那我們不得不來看一下它的多進程架構。

          • VS Code 有一個主進程入口,負責一些窗口管理、進程間通信、自動更新等全局任務;
          • 渲染進程,顧名思義負責一個 Web 頁面的渲染;
          • 插件宿主進程,每個插件的代碼都運行在一個獨立且隔離的 Node 環境的宿主進程中,插件無法訪問 UI;
          • Debug 進程,用于調試;
          • 語言服務,是一種重要的特殊拓展,可以為許多編程語言提供編輯體驗,還可以實現 VS Code 支持的自動補充,錯誤檢查(診斷),跳轉到定義以及許多其他的語言功能。

          最核心的部分就是它的插件系統,為編輯器的拓展帶來了更加個性化的開源定制。只要你能找到強大的 VS Code 插件組合在一起,那你的編輯器一定是一個高級且高效率的工作好幫手。

          先來看一下,VS Code 大致有哪些可供我們拓展的能力。

          有沒有心癢癢地想自己動手搞一個 VS Code 插件?下面就帶大家做一個入門級的 VS Code 插件。

          二、環境準備

          首先你搞個 Node.js 和 Git。

          其次「全局(-g)」安裝 Yeoman(現代 Web 應用程序腳手架工具)和 VS Code Extension Generator 這兩個官方指定的工具腳手架(生成 VS Code 插件項目的工具)。

          npm install -g yo generator-code

          當你看到下面的信息就說明安裝成功了:

          三、初始化項目結構

          依賴環境搞好了,接下來就要用到 Yeoman 這個工具來幫我們快速創建項目結構啦!可能有很多人對這個腳手架不熟悉,簡單的說,Yeoman 是一個通用的腳手架系統,它允許創建任何類型的應用程序。你可以用它快速開始新項目。所以不僅僅是 JavaScript 這個語言,Java,Python,C#等都可以用它來生成項目,只要有對應的生成器就可以。那我們進行下一步,在命令行中輸入 yo code

          讓我們來分析一下這幾個選項的意思,其實和字面意思一樣,從上到下:

          • 新的插件(Typescript)
          • 新的插件(JavaScript)
          • 新的主題顏色
          • 新的語言支持
          • 新的代碼片段
          • 新的鍵值綁定
          • 新的插件包
          • 新的語言包(本土化)

          你可以看到這個工具支持創建多種類型的項目,我們今天先從插件(Extension)入手,所以第一個和第二個的區別就是,你要是會用 TypeScript 就選第一個,也是官方推薦的一個;要是不想寫各種麻煩的類型定義和類型校驗,就選第二個 JavaScript。 這一次我們選 JavaScript 來做一個簡單的入門, 隨后你會需要填寫一系列初始化的信息如下:

          注釋如下:

          • What type of extension do you want to create?(創建哪一種類型的擴展?)
          • What's the name of your extension?(擴展的名稱?應該全部為小寫字母,沒有空格)
          • What's the identifier of your extension?(擴展的標示?)
          • What's the description of your extension?(擴展的描述是什么?)
          • Initialize a git repository?(是否初始化 git 倉庫?)
          • Which package manager to use? (因為我們裝的是 npm,所以選 npm 就行了,如果你有 yarn,你也可以選 yarn)
          • 使用哪一種包管理器(來下載各種 npm 包)

          四、搞一個簡單的 VS Code 插件

          前面的準備得差不多啦!那我們就要開始開「綠皮小火車」啦。

          進入剛創建的文件目錄 cd test-extension,文件目錄:

          或許你覺得文件目錄嘛,一看就知道了,不就是幾個配置信息或者項目說明嘛,但是這里面的配置信息「非常重要」x3,重要到你可能少一個配置或者配置的不對,功能就出不來。所以我們還是稍微花點筆墨聊聊這里的信息。

          首先你可以在 package.json 文件里面,看到自己在前一個步驟里面設置的各個值,配置內的各個主要的含義如下,這里有個小點注意一下,如果你的 VS Code 比較舊,且更新不了最新的,你就把下面的 engines 設置的版本低一點,比如我就改成了 ^1.52.0 確保一定能兼容目前的 VS Code 編輯器就可以 :

          {
            "name": "test-extension", // 插件的名字
            "displayName": "test-extension", // 在插件市場展示的名字
            "description": "vscode extension sample", // 插件描述
            "version": "0.0.1", // 插件版本
            "engines": { // 最低支持 vscode 的版本
              "vscode": "^1.52.0"
            },
            "categories": [ // 插件的類別,用于在插件市場做區分
              "Other"
            ],
            "activationEvents": [ // 插件激活的事件列表,可以有多個觸發機制,所以是數組形式
              "onCommand:test-extension.helloWorld"
            ],
            "main": "./extension.js", // 插件主入口
            "contributes": { // 貢獻點,用于拓展插件功能的配置項,這里不會細講,先用 command 舉例
              "commands": [
                {
                  "command": "test-extension.helloWorld",
                  "title": "Hello World"
                }
              ]
            },
            "scripts": {
              "lint": "eslint .",
              "pretest": "npm run lint",
              "test": "node ./test/runTest.js"
            },
            "devDependencies": {
              "@types/vscode": "^1.55.0",
              "@types/glob": "^7.1.3",
              "@types/mocha": "^8.0.4",
              "@types/node": "^12.11.7",
              "eslint": "^7.19.0",
              "glob": "^7.1.6",
              "mocha": "^8.2.1",
              "typescript": "^4.1.3",
              "vscode-test": "^1.5.0"
            }
          }

          熟悉了配置之后,我們再來看一下插件的入口文件 extsnsion.js ,里面主要有兩個主要的函數,一個是 activate 表示激活插件時的處理,一般是注冊命令等一些初始化的操作;另一個是 deactivate ,表示插件失活的時候做的處理,其實聽名字你也應該有體感,這就是插件的生命周期里的兩個鉤子函數嘛。

          // 引了 vscode 這個模塊,這樣你就可以用它里面的很多很多功能啦
          const vscode = require('vscode');
          
          /**
           * @param {vscode.ExtensionContext} context
           */
          function activate(context) {
          
            console.log('Congratulations, your extension "test-extension" is now active!');
          
            let disposable = vscode.commands.registerCommand('test-extension.helloWorld', function () {
              vscode.window.showInformationMessage('Hello World from test-extension!');
            });
          
            context.subscriptions.push(disposable);
          }
          
          function deactivate() {}
          
          module.exports = {
            activate,
            deactivate
          }

          我們來分析一下上面這段代碼,你可以看到里面 registerComman 了一個命令,是不是有種似曾相識的感覺?沒錯,就是上面在 package.json 里面有提到的那個 command,讓我們摘出來一起看看:

          ...,
           // package.json
           "contributes": { // 貢獻點,用于拓展插件功能的配置項,這里不會細講,先用 command 舉例
              "commands": [
                {
                  "command": "test-extension.helloWorld",
                  "title": "Hello World"
                }
              ]
            },
          ...
          ...
          // extension.js
          function activate(context) {
            console.log('Congratulations, your extension "test-extension" is now active!');
          
            let disposable = vscode.commands.registerCommand('test-extension.helloWorld', function () {
              vscode.window.showInformationMessage('Hello World from test-extension!');
            });
          
            context.subscriptions.push(disposable);
          }
          ...

          這樣看起來是不是很直觀了?在 package.json 里面設置的 command 的值,就是 extension.js 里面 registerCommand 的值。那這幾行命令是什么意思呢?讓我們一起來運行看看:

          他會幫你打開一個新的 VS Code 編輯器,插件只會加載到這個編輯器中。現在我們使用調用快捷鍵(MacOS) command+p ,輸入 >Hello World (不區分大小寫):

          回車一下,你會發現在右下角一個不起眼的角落里輸出了這么一個提示:

          我相信聰明的你們結合代碼一定已經恍然大悟了對不對!不知道你們有沒有這個疑問,上面那個 console.log 去哪里看?別急,我們回到插件代碼的那個編輯器中,仔細看下面這邊,他會在我們輸入上面的命令之后才出現,因為在 package.json 里面我們配置插件的激活時機就是 onCommand:test-extension.helloWorld

          那我們現在抱著「刻意學習」的思路,改一下上面的代碼,比如把 test-extension 改成 test

          ...,
          // package.json
          "activationEvents": [
              "onCommand:test.helloWorld"
          ],
          ...,
          "contributes": {
            "commands": [
              {
                "command": "test.helloWorld",
                "title": "Hello World"
              }
            ]
          },
          ...
          // extension.js
          ...
          function activate(context) {
          
            console.log('我在這里!!');
          
            let disposable = vscode.commands.registerCommand('test.helloWorld', function () {
              vscode.window.showInformationMessage('我改變了 command 的名字!');
            });
          
            context.subscriptions.push(disposable);
          }
          ...

          再按照上面說的觸發方法再來一遍,發現依舊是可以的!所以這里的名字只是一個命名空間,你可以改成你想要的任何名字,來適用于比較復雜的插件體系。既然是個命名空間,那其實不要這個前綴也可以。

          五、實現一個屬于自己的插件

          前面介紹了那么多,大家有沒有發現其實這個體系也不難,有大佬在前面鋪路,其實我們只要按照規則“填空”就好了,那現在我們就來實現一個小小的功能——加一個按鈕和他的點擊事件。

          修改我們的 package.json 如下,因為當前我希望插件加載的時候就已經訂閱了按鈕的點擊事件,所以這里我們可以把 activationEvents 改成 *,這樣的話我們的插件在一開始就可以激活并注冊事件了:

          ...,
          "activationEvents": [
                  "*",
          ],
          "contributes": {
            "commands": [
              {
                "command": "test.helloWorld",
                "title": "Hello World"
              },
              // 注冊一下按鈕點擊的事件,再配一個小圖標
              {
                "command": "test.button",
                "title": "按鈕",
                "icon": {
                  "light": "./media/light/preview.svg",
                  "dark": "./media/dark/preview.svg"
                }
              }
            ],
            // 在這里加一下下面這個配置
            "menus": {
              "editor/title": [
                {
                  "command": "test.button",
                  "group": "navigation"
                }
              ]
            }
          },
          ...

          然后回到我們的 extension.js 里面增加一個簡單的消息提醒:

          function activate(context) {
            console.log('我在這里!!');
            let disposable = vscode.commands.registerCommand('test.helloWorld', function () {
              vscode.window.showInformationMessage('我改變了 command 的名字!');
            });
            // 新增一個按鈕的點擊命令操作內容
            let button = vscode.commands.registerCommand('test.button', function () {
              vscode.window.showInformationMessage('按鈕點擊');
            });
            // 記得這個新的命令也要放進去訂閱一下
            context.subscriptions.push(disposable, button);
          }

          看一下效果:

          是不是很簡單的就自定義了 VS Code 的樣式?那我們現在就來分析一下我們上面做的事情。首先,我們修改了 package.json 里的配置,增加了一個 menus ,這個 menus 是什么呢?答案是菜單。菜單項定義包含選擇時應調用的命令以及該項應顯示的條件(when),所以你也可以給這個菜單項顯示加個顯示的邏輯,比如我們規定在打開 javascript 文件時才顯示這個按鈕:

          {
            "contributes": {
              "menus": {
                "editor/title": [
                  {
                    "when": "resourceLangId == javascript",
                    "command": "test.button",
                    "group": "navigation"
                  }
                ]
              }
            }
          }

          group 的含義呢,是用來定義菜單項的排序和分組的。來自官網的一個圖,表示不同的 group 之間存在的順序關系,當然這個菜單不是上面我們寫的那個,而是 editor/context ,所以不同的菜單之間的 group 其實是有細微差別的,但是大體都差不多,而 navigation 的顯示優先級是最高的:

          我們也可以加一個這個看看:

          "menus": {
            "editor/title": [
              {
                "command": "test.button",
                "group": "navigation",
                "when": "resourceLangId == javascript"
              }
            ],
              "editor/context": [
                {
                  "command": "test.button",
                  "group": "navigation",
                  "when": "resourceLangId == javascript"
                }
              ]
          }

          效果是一樣的:

          如果你好奇還有哪些菜單,我在這里簡單整理「翻譯」了一下官網的內容(僅常見菜單非全部):

          六、做個總結

          從上面的簡單例子可以看出,VS Code 不僅可以支持我們自定義想要的命令,也允許我們在「限定范圍內」對編輯器進行個性化的拓展。為什么說是限定范圍呢?因為按官網的話來說,目前插件體系有下面這些局限性:

          插件不具備訪問 VS Code UI 的 DOM 的能力。所以不能將自定義的 CSS 應用于 VS Code 或將 HTML 元素添加到 VS Code UI 的擴展中去。這樣的限制在于:

          • 確保用戶的操作在可控范圍內,保證操作的一致性
          • 防止因為底層 Web 技術的更迭導致對一些已存在的插件會有影響
          • 保證開發人員可以繼續在原有插件基礎上進行一如往常的迭代,而不用再去打破原有的規則重新學習

          其實我們今天的內容只是工作區拓展很小一部分內容,要學習這個龐大的體系,還是要不斷地努力學習呀!下一次,我們來走進「聲明類語言特性」,想知道編輯器里的自動提示和補全是怎么做到的嘛?


          關注我收到第一時間的更新。

          還有更多開源項目的介紹和寶藏項目等待你的發掘。

          、安裝nodeJS和npm

          訪問nodejs中文網http://nodejs.cn/download/,下載對應自己系統的版本,我們把當前的目錄加入到系統環境變量的path里面。然后打開cmd命令行,輸入npm -v,如果出現如下圖的顯示,說明已經安裝正確。 就可以使用npm命令了。


          2、進入Webstorm的官方網站下載webstorm的最新版本.

          安裝成功后把vue component的模版加入到模版庫中。在File->New->Edit File Templates,在彈出的對話框中點擊左上角的綠色加號,然后按照如圖顯示填寫Name和Extension填入代碼 http://www.jetbrains.com/webstorm/

          <template>

          <div>

          </div>

          </template>

          <script type="text/ecmascript-6">

          export default {

          data(){

          return {

          }

          }

          }

          </script>

          點擊File->Settings設置jsES6支持

          3、創建ElementUI工程

          從ElementUI的官網里找到通用的項目模版。地址在ElementUI的GitHub https://github.com/ElementUI/element-starter,我們只要下載這個工程即可。下載解壓之后,在webstorm中點擊File->Open,打開剛才下載的工程。打開之后可以看到工程結構如下圖:

          可以看到里面已經集成了bable、webpack等插件。不需要我們自己去配置。我們導入這個工程之后,需要做的一件事就是將npm模塊安裝到這個目錄下。我們打開命令行,進入當前工程的根目錄,然后輸入

          npm install --registry=http://registry.npm.taobao.org安裝結束后我們可以看到工程目錄下多了一個node_modules的文件夾,該文件夾就是工程的依賴包所在。以后我們如果想添加依賴包,就可以繼續用上文的指令,例如如果想加入vue-router,那么需要輸入npm install vue-routersave,npm會自動尋找最新版本的依賴包進行安裝

          4. 打包運行

          安裝好之后, 進入當前工程的目錄,并輸入npm run dev, 在工程根目錄的webpack.config.js中可以修改本地服務配置。最后會出現webpack: Compiled successfully的字樣,代表代碼編譯成功。這時我們打開瀏覽器,輸入localhost:8010,出現如圖所示的網頁,表示我們的第一個Vuejs2.0 +ElementUI工程已經成功運行。

          建設網頁時,為了快速、高效地完成任務,通常會使用一些具有代碼高亮顯示、語法提示等便捷功能的網站開發工具。常見的網站建設工具有Sublime、Visual Studio Code、webstorm、Dreamweaver、Hbuilder等,具體介紹如下。

          1、 Sublime

          Sublime全稱為Sublime Text,是一個代碼編輯器,最早由程序員Jon Skinner于2008年1月開發出來。Sublime Text具有漂亮的用戶界面和強大的功能,例如代碼縮略圖、功能插件等。Sublime text還是一個跨平臺的編輯器,支Windows、linux、Mac等操作系統。

          2、 Visual Studio Code

          Visual Studio Code(簡稱“VS Code”)是Microsoft在2015年4月30日Build開發者大會上正式宣布一個運行于 Mac OS X、Windows和 Linux 之上的,針對于編寫現代Web和云應用的跨平臺源代碼編輯器, 可在桌面上運行,并且可用于Windows,macOS和Linux。它具有對JavaScript,TypeScript和Node.js的內置支持,并具有豐富的其他語言(例如C++,C#,Java,Python,PHP,Go)和運行時(例如.NET和Unity)擴展的生態系統。

          3、 Webstorm

          WebStorm 是JetBrains公司旗下一款JavaScript 開發工具。已經被廣大中國JS開發者譽為“Web前端開發神器”、“最強大的HTML5編輯器”、“最智能的JavaScript IDE”等。與IntelliJ IDEA同源,繼承了IntelliJ IDEA強大的JS部分的功能。

          4、 Dreamweaver

          Dreamweaver簡稱DW(中文譯為“夢想編織者”),是美國MACROMEDIA公司開發的集網頁制作和網站管理于一身的“所見即所得”網頁編輯器,2005年被Adobe公司收購。DW是第一套針對非專業網站建設人員的視覺化網頁開發工具,利用它可以輕而易舉地制作網頁。

          5、 Hbuilder

          HBUilder是DCloud推出的一款支持HTML5的Web開發軟件。“快”是BUilder的最大優勢,通過完整的語法提示、代碼輸入法以及代碼塊等,HBuilder可以大幅提升HTML、JavaScript的開發效率。


          主站蜘蛛池模板: 国产亚洲一区二区三区在线| 亚洲欧美日韩中文字幕在线一区| 亚洲制服中文字幕第一区| 亚洲一区中文字幕在线观看| 在线视频一区二区| 国产MD视频一区二区三区| 亚洲色无码一区二区三区| 四虎精品亚洲一区二区三区 | 成人精品一区二区三区不卡免费看 | 中文无码AV一区二区三区| 亚洲欧美国产国产综合一区| 久久精品一区二区三区日韩| 丰满爆乳一区二区三区| 日本一区午夜艳熟免费| 无码人妻一区二区三区精品视频 | 无码国产精品一区二区免费16| 亚洲AⅤ无码一区二区三区在线 | 国产成人久久一区二区三区 | 99精品国产一区二区三区| 日本免费一区二区三区最新| AA区一区二区三无码精片| 午夜影院一区二区| 国产精品一区视频| 日韩精品电影一区| 一区五十路在线中出| 91精品一区国产高清在线| 高清一区二区三区日本久| 日韩人妻一区二区三区蜜桃视频 | 日韩一区二区三区电影在线观看| 亚洲国产欧美一区二区三区 | 男插女高潮一区二区| 精品国产一区二区三区AV | 性色av无码免费一区二区三区| 精品一区二区三区在线播放视频| 中文字幕av一区| 国产SUV精品一区二区88| 一区二区免费国产在线观看| 日韩精品无码一区二区三区四区| 无码国产精品一区二区免费vr| 亚洲电影唐人社一区二区| 久久青青草原一区二区|