VSCode拡張機能のパッケージ化に関する補足

# VSCode拡張機能のパッケージ化に関する補足

VSCodeの拡張機能を作成し、vsceコマンドでパッケージ化(vsix化)すると、「node_modules」配下のライブラリがvsixに含まれず、そのvsixをインストールしても結局動作しないことがわかった。
いろいろと調査した結果、webpackで実行ファイルを1つのファイルに結合することで、うまく動作したので、備忘のために方法をメモします。

(参考)[VSCode拡張機能をパッケージ化する](https://qiita.com/keiji-kataoka/items/e39916329d47856bb230)
(参考)[Bundling Extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension)

# 開発環境
||バージョン|
|---|---|
|OS|Windows 10|
|VSCode|1.39.2|
|node.js|v12.6.0|
|npm|6.9.0|

# 準備
webpackをインストールする。

```console:
npm i --save-dev webpack webpack-cli
```

# webpackの設定
webpack.config.jsファイルを拡張機能ワークスペースのルートディレクトリに作成し、以下のようにする。

entryは「extension.js」としてますが、TypeScriptだったり、違うファイル名にしているときは、適宜修正してください。

また、outputのpathとfilenameは、それぞれ「dist」「exetension.js」となっていますので、webpackされたファイルは、distフォルダにextension.jsというファイル名で出力されます。
適宜修正してください。

```javascript:webpack.config.js
//@ts-check

'use strict';

const path = require('path');

/**@type {import('webpack').Configuration}*/
const config = {
  target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/

  entry: './extension.js', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
  output: {
    // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
    path: path.resolve(__dirname, 'dist'),
    filename: 'extension.js',
    libraryTarget: 'commonjs2',
    devtoolModuleFilenameTemplate: '../[resource-path]'
  },
  devtool: 'source-map',
  externals: {
    vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
  },
  resolve: {
    // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
    extensions: ['.ts', '.js']
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'ts-loader'
          }
        ]
      }
    ]
  }
};
module.exports = config;
```

# 実行ファイルの修正
packge.jsonを修正し、実行ファイルのパスを修正します。
webpack前のファイルが実行される設定になっているはずなので、
webpackされたjsファイルを実行してもらうための修正です。

mainを「./dist/extension.js」に修正します。
(webpack.config.jsで設定した、出力先ディレクトリとファイル名に合わせてください)

```javascript:package.json
{
	...
	"main": "./dist/extension.js",
```

# webpackを実行する
webpackを実行します。
コマンドプロンプトで拡張機能のワークスペースディレクトリに移動後、以下のコマンドを実行します。

```console:
npx webpack --mode development
```

これでwebpackされたexetension.jsが生成されます。
/dist/extension.jsを開いて確認すると、必要なjsファイルが結合され、めっちゃでかいファイルが生成されてるはずです。

また、webpackのモードを「production」にすると、出力されるファイルがminimizeされます。

```console:
npx webpack --mode production
```
# 拡張機能の開発(デバッグ実行)のための設定
package.jsonで実行ファイルを「webpack後のファイル」に設定してますので、面倒なことが発生します。

- 拡張機能をデバッグ実行する前に、必ずwebpackをしないといけない
- 開発中にブレークポイントを貼ってデバッグしたい場合、とのファイルにブレークポイントを設定するのか？

これらの手間を最小限にするための設定として、以下を設定しました。

- package.jsonに、webpackのコマンドを定義する
- launch.jsonの「outFiles」「preLaunchTask」を設定する


```javascript:package.json
{
	...
	"scripts": {
		"vscode:prepublish": "webpack --mode production",
		"webpack": "webpack --mode development",
		"webpack-dev": "webpack --mode development --watch",
		"test-compile": "tsc -p ./",
		"test": "node ./test/runTest.js"
	},
	...
```

```javascript:.vscode/launch.json
{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "Run Extension",
			"type": "extensionHost",
			"request": "launch",
			"runtimeExecutable": "${execPath}",
			"args": [
				"--extensionDevelopmentPath=${workspaceFolder}"
			],
            "outFiles": [
                "${workspaceFolder}/dist/**/*.js"
            ],
            "preLaunchTask": "npm: webpack"
		},

    ...

```
これらの設定により、
デバッグ実行すると自動的にwebpackが走ります。いちいち実行するたびにwebpackが走るので、起動に若干時間がかかりますが。。。
また、ブレークポイントに関してですが、launch.jsonの「outFiles」の設定と、webpack実行時に生成されるmapファイル(distに出力される)のおかげで、webpack前のjsファイルたちに、ブレークポイントを貼ると、きちんと止まってくれます。

# vsceの実行
以上の設定をすることにより、「vsce package」でのvsix作成時に、自動的にwebpackが走ります。

# 次回予定
ついに、code serverで拡張機能を動作させることになりそう。