【VSCode拡張開発】依存しているnode-globのバージョンを8.1.0から10.3.10へ上げる
自作のVSCode拡張開発用リポジトリではmochaを用いた自動テストで、globというファイル探索ライブラリに依存している。
globを8.1.0から10.3.10に上げるとテスト実行時のコンパイルでエラーが発生するようになったので解決していく。
コンパイル時のエラーは以下
ERROR in /home/runner/work/vscode-gtl/vscode-gtl/src/test/suite/index.ts
15:2-6
[tsl] ERROR in /home/runner/work/vscode-gtl/vscode-gtl/src/test/suite/index.ts(15,3)
TS2349: This expression is not callable.
Type 'typeof import("/home/runner/work/vscode-gtl/vscode-gtl/node_modules/glob/dist/commonjs/index")' has no call signatures.
globが呼び出し不可能とのこと。なぜ。
ちなみに、mochaでテストするための設定は、VSCode拡張開発の公式ドキュメントを参考にしていた。
もともとのコード
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true
});
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
});
}
呼び出し不可能とのことなので
import * as glob from 'glob';
を
import { glob } from 'glob';
に書き換えてみてコンパイル。
src/test/suite/index.ts:15:45 - error TS2554: Expected 1-2 arguments, but got 3.
15 glob('**/**.test.js', { cwd: testsRoot }, (err: Error | null, files: string[]) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 if (err) {
~~~~~~~~~~~~~
...
35 }
~~~~
36 });
~~~
引数の個数が一致しないとのこと。globの仕様が変わってそう。
glob v10.3.10のREADMEを読んでみる。
glob(pattern: string | string[], options?: GlobOptions) => Promise<string[] | Path[]>
引数としてcallbackを渡せなくなっている模様。
ちなみにglob v8.1.0のREADMEでは
glob(pattern, [options], cb)
という形で、第三引数としてcallbackを渡すことができていた。
issueを漁ってみる。
Rewrite this library · Issue #405 · isaacs/node-glob
作者曰く「いまの仕様だとしんどいから、書き換えるね」ということらしい。
callbackの代わりにpromiseを使うようにするとのこと。
glob v9.0.0のchangelogを見ると、issueで言及されていた変更内容が記録されていた。
Promise API instead of callbacks.
ということで、callbackを渡すのではなく、promiseとして扱えばよさそう。
import * as path from 'path';
import * as Mocha from 'mocha';
import { glob } from 'glob';
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true
});
const testsRoot = path.resolve(__dirname, '..');
return new Promise(async (c, e) => {
const files: string[] = await glob('**/**.test.js', { cwd: testsRoot });
// Add files to the test suite
files.forEach((f: string) => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
}
解決!