RACCOON TECH BLOG

株式会社ラクーンホールディングスのエンジニア/デザイナーから技術情報をはじめ、世の中のためになることや社内のことなどを発信してます。

Visual Studio CodeがRSSリーダになる?VS Codeの拡張機能を作れば作業が捗る

こんにちは。開発チームの阿部です。

プログラムを開発する際に必要となるテキストエディターはSublime Text、Atom、VS Code など、
高性能・高機能を持つものが増えてきました。
今回はその内の1つVS Codeの拡張機能(extension)を使用してRssを取得する機能を作成してみたいと思います。
※記事中盤あたりにRssの取得の具体的な方法を載せています。

またVS Codeの公式ページ・概要をリンクして置きました。
良かったら一度見てみてください。
Visual Studio Code 日本語
Visual Studio Code doc 英語
Visual Studio Code wikipedia

必要な環境と執筆時の環境

extensionを作成する上でVS Codeの本体と、Node jsのインストールが必要になります。
インストールはこちらから
Visual Studio Code
Node js

下記はこの記事の執筆時の開発環境です。

  1. Windows10 Pro
  2. Visual Studio Code 1.23.1
  3. Node js(current) v9.5.0

VS CodeとNode jsのインストールが完了したら環境変数が設定されている事を確認します。
Windowsではコマンドプロンプト(windowsキー + R -> cmdと入力)から下記コマンドを実行し確認します。

code -v

1.23.1

node -v

v9.5.0

各Version番号が返却される事を確認してみてください。

extensionを作成する為のセットアップ

まず初めにextensionのひな型を作成する為のツールをインストールします。
このツールはextensionの開発に必要なファイルを作成してくれるジェネレータです。
先ほどのVersion確認をしたコマンドプロンプトに入力します。

npm install -g yo generator-code

インストールが完了したらコマンドプロンプトに入力してVS Code extensionのひな型を作成します。

yo code

と入力すると対話式に質問が返ってきます。
必要に応じて最適な選択を行ってください。

全ての入力が完了するとセットアップが始まり完了時に
下記のアナウンスが返ってきます。
Your extension rssfeedreader has been created!
To start editing with Visual Studio Code, use the following commands:

cd rssfeedreader
code .

コマンドプロンプトにコマンドを実行します。

cd ※What's the name of your extension?で入力した拡張機能名
code .

VS codeでextension開発用のウィンドウが新しく開く事を確認してみてください。
img10_vs_code_2

デフォルトで用意されているextensionを実行する

開発用ウィンドウでF5キーを押すと今度は別のデバッグ用ウィンドウが開きます。
img2_vs_code_2
デバッグ用ウィンドウ上で、ショートカット(Shif + Ctrl + P) または、表示->コマンドパレット を押してhello worldと入力しenterを押します。
img4_vs_code_2

画像の様にメッセージが表示されたかと思います。
※VS CodeのVersionによっては別の位置に表示される可能性があります。
img5_vs_code_2

これらは\src\extension.ts にデフォルトで記述されている処理内容になります。

実際にextensionを作成する

作成するRssFeedReader extensionについて

下記は今回extensionで実現したい事です。

  1. 登録URLからRssデータを取得
  2. 取得したデータをmdファイル形式にして保存する。
  3. 保存したmdファイルを自動で開き、そのファイルを自動でVS Codeのmdビューワーでも開く

これらを実装する手順を説明していきます。

呼び出し関数作成

VS Code上で機能するRssFeedReaderを作成して行きます。初めに呼び出し関数を定義していきます。
vscode.commands.registerCommandでコマンドを定義し、1つ目の引数'extension.rssFeedReader'が定義するコマンドの名前、2つ目の引数に渡してるfunctionが呼び出される関数になります。

extensionの実行部分は\src\extension.ts になりますので、こちらを編集して実装を進めて行きます。
img3_vs_code_2

既に存在するactivate関数の中を編集していきます。
下記のブロックを探して、呼び出ししたい関数を追記していきます。

export function activate(context: vscode.ExtensionContext) {
}

上記のコード(既に存在しているactivate関数)の内部に下記のコード(呼び出ししたい関数)を追記して呼び出しの関数を作成します。

let rssfeedreader = vscode.commands.registerCommand('extension.rssFeedReader', () => {
    console.log("Rss コマンド登録確認テスト");
});
context.subscriptions.push(rssfeedreader);

追記すると、このようになります。

export function activate(context: vscode.ExtensionContext) {
    let rssfeedreader = vscode.commands.registerCommand('extension.rssFeedReader', () => {
        console.log("Rss コマンド登録確認テスト");
    });
    context.subscriptions.push(rssfeedreader);
}

コマンドを登録

続いてコマンドの登録を行います。
先ほど書いたextension.rssFeedReaderを\package.json に登録します。

activationEvents、contributesをこの様にしています。

    "activationEvents": [
        "onCommand:extension.rssFeedReader"
    ]
    "contributes": {
        "commands": [
            {
                "command": "extension.rssFeedReader",
                "title": "Rss Feed Reader"
            }
        ]
    }

登録確認

登録したコマンドが実際に実行できるかを試してみます。
開発ウィンドウでF5キーを押してデバックウィンドウを開きます。デバックウィンドウでcontributes.commandsに登録したコマンド「Rss Feed Reader」を入力してみます。
デバッグコンソールに内容を出力するconsole.logを使用しているため、開発ウィンドウにデバッグコンソールが開いてあるか確認します。開発ウィンドウにデバックコンソールが開いていない場合は、上部メニューから表示->デバックコンソール、または Ctrl+Shift+Y で表示できます。
デバッグコンソールに「Rss コマンド登録確認テスト」と表示されていれば登録・呼び出し、実行に成功しています。

※デバックウィンドウが既に開いている場合はリロードボタンを押すか一旦閉じて開きなおしてください。
以降も同じ手順が必要になります。

登録・呼び出しと実行については、確認して頂けたと思うので、次は具体的なRssFeedReaderの作成していきます。

Rss取得処理

初めにRssの取得部分を作成します。
Rssを取得するには、feedparser・requestという2つのNodeモジュールを使用します。これらはRssを取得し、取得した内容を扱いやすい内容に変換してくれるモジュールです。
以下のコマンドを実行し、インストールを行います。

npm install feedparser
npm install request

feedparserモジュールの使用方法については、こちら(feedparser)を参考にして組み立てていきます。

feedparser・requestを使用したRssの取得ロジックを追加します。

export function activate(context: vscode.ExtensionContext) {
    let rssfeedreader = vscode.commands.registerCommand('extension.rssFeedReader', () => {
        const FeedParser = require('feedparser');
        const request = require('request');
        let req = request('https://news.yahoo.co.jp/pickup/computer/rss.xml')
        let feedparser = new FeedParser([]);
        req.on('error', function(error: any) {
            console.log("rss取得エラー:" + error);
        });
        req.on('response', function(res: any) {
            if (res.statusCode !== 200) {
                console.log("Bad status code");
            } else {
                req.pipe(feedparser);
            }
        });
        feedparser.on('error', function (error: any) {
            console.log("feedparserエラー:" + error);
        });
        feedparser.on('readable', function (error: any) {
            let item;
            while (item = feedparser.read()) {
                console.log(item);
            }
        });
    });
    context.subscriptions.push(rssfeedreader);
}

feedparser・requestの動作確認

再度デバックウィンドウからコマンド入力し、実際にRssが取得できる事を確認します。
デバックコンソールに取得内容が表示されていれば成功です。
img7_vs_code_2

取得データ保存処理

次に取得したRssの保存する処理を実装していきます。
保存する処理には、fs Nodeモジュールを使用するのでインストールをします。

npm install fs

mdファイルへの保存処理を追加すると、以下のようになります。

const fs = require('fs');
let mdText: string = "";
feedparser.on('meta', function (error: any) {
    mdText += `====${feedparser.meta.title}====\n`;
});
feedparser.on('readable', function (error: any) {
    let item;
    while(item = feedparser.read()) {
        mdText += `- [${item.title}](${item.link})\n`;
    }
});
feedparser.on('end', function (error: any) {
    fs.writeFile('C:/Users/ユーザー名/rssfeedreader.md', mdText, (error: any) => {
        if(error) {
            console.log("エラーが発生しました。" + error)
        } else {
            console.log("ファイルが正常に書き出しされました");
        }
    });
});

設定ファイルを追加

ファイルを保存する処理までの実装を行いましたが、RssのUrlとファイルの保存名がソースコード上にそのまま書かれてしまっていますので、設定から読み込むように修正します。configurationの追記方法は、\package.json のcontributesにconfigurationを追記して、取得するRssのUrlとファイルの保存先を追記します。

"contributes": {
    "commands": [
        {
            "command": "extension.rssFeedReader",
            "title": "Rss Feed Reader"
        }
    ],
    "configuration": {
        "type": "object",
        "title": "RssFeedReader configration",
        "properties": {
            "rssfeedreader.general": {
                "type": "object",
                "default": {
                    "saveFileName": "C:/Users/ユーザー名/rssfeedreader.md",
                    "rssUrl": "https://news.yahoo.co.jp/pickup/computer/rss.xml"
                },
                "description": "RssFeedReader extension"
            }
        }
    }
}

VS Code自動テスト機能

ここで自動テスト機能を使用して、先ほど追記したconfigurationの値が正しいかをテストします。テストファイルは \src\test\extension.test.ts です。
※ファイル上部のimport * as ~はテスト内容の必要に応じて、追加・削除してください。

suite("Extension Tests", () => {
    test("config test", () => {
        const config = vscode.workspace.getConfiguration('rssfeedreader');
        assert.notEqual(null, config);
        assert.equal("C:/Users/ユーザー名/rssfeedreader.md", config.general.saveFileName);
        assert.equal("https://news.yahoo.co.jp/pickup/computer/rss.xml", config.general.rssUrl);
    });
});

テストを実行するにはデバックタブを開き、Extention Tests を選択し実行します。
img9_vs_code_2

テストに成功
img8_vs_code_2

自動でファイルを開く処理

最後に保存したmdファイルを自動で開き、そのファイルを自動でVS Codeのmdビューワーでも開く処理を追加して完成です。
ここでは、VS Codeに元々用意されている機能を使用する為、新しいNodeモジュールの追加はありません。

configurationからRssのUrlとファイルの保存先を取得して、自動で開く処理を追記しました。
完成したコードはこちらです。

export function activate(context: vscode.ExtensionContext) {
    let rssfeedreader = vscode.commands.registerCommand('extension.rssFeedReader', () => {
        const config = vscode.workspace.getConfiguration('rssfeedreader');
        const saveFileName = config.general.saveFileName;
        const rssUrl = config.general.rssUrl;
        const FeedParser = require('feedparser');
        const request = require('request');
        const fs = require('fs');
        let req = request(rssUrl);
        let feedparser = new FeedParser([]);
        let mdText: string = "";
        req.on('error', function(error: any) {
            console.log("rss取得エラー:" + error);
        });
        req.on('response', function(res: any) {
            if (res.statusCode !== 200) {
                console.log("Bad status code");
            } else {
                req.pipe(feedparser);
            }
        });
        feedparser.on('error', function (error: any) {
            console.log("feedparserエラー:" + error);
        });
        feedparser.on('meta', function (error: any) {
            mdText += `====${feedparser.meta.title}====\n`;
        });
        feedparser.on('readable', function (error: any) {
            let item;
            while(item = feedparser.read()) {
                mdText += `- [${item.title}](${item.link})\n`;
            }
        });
        feedparser.on('end', function (error: any) {
            fs.writeFile(saveFileName, mdText, (error: any) => {
                if(error) {
                    console.log("エラーが発生しました。" + error)
                } else {
                    console.log("ファイルが正常に書き出しされました");
                    vscode.workspace.openTextDocument(saveFileName).then((doc) => {
                        vscode.window.showTextDocument(doc).then(() => {
                            vscode.commands.executeCommand("markdown.showPreview");
                        });
                    });
                }
            });
        });
    });
    context.subscriptions.push(rssfeedreader);
}

再度F5キーを押し、コマンドを入力して、mdファイルが保存されている事と自動でファイルが開かれ、mdビューワーでも開く事を確認したら完了です。

extensionをVS Codeに取り込む

今回作成したextensionを実際にデバックではないVS Codeで自分だけで使用する方法は、Windowsであれば最初にextensionを作成した場所(筆者の環境だとC:\Users\ユーザー名\rssfeedreader)がextensionファイル一式になります。
これらをC:\Users\ユーザー名.vscode\extensionsにまるごとコピーしその後、VS Codeを再起動してください。起動後から使用出来ます。また別の方法ではVS CodeのMarketPlaceに公開し、インストールする方法もありますが、今回は実施はしませんので、もしもMarketPlaceに公開したい時はこちら(拡張機能の公開
)などを参考にしてみてください。

最後に

公開されているNode モジュールは沢山あり、それらを使用する事で、比較的簡単に色々な事が実現出来ると思います。自分のやりたい事を色々と試して、面白い・便利なextensionを作ってみてはいかがでしょうか?

一緒にラクーンのサービスを作りませんか? 採用情報を詳しく見る

関連記事

運営会社:株式会社ラクーンホールディングス(c)2000 RACCOON HOLDINGS, Inc