Node.jsで実行できるスクリプトをTypescriptで作る【備忘】
Typescript
はまだまだ初心者ですが備忘録として残しておこうかと思った次第。
● 完成系のイメージ
チームメンバーのスキル的にnpm
でインストールは無い方が無難かなと思いまして、node
でjsファイルを指定して実行する方針にしました。
なので bin
ではなく main
で 出力先の./dist/index.js
としています。
※ 実際のスキル感次第で変更してもいいかなと思ってます。
実行時
$ node cli-tool opt1
// 実行結果
-> Hello, opt1!
TS→JS
# package.jsonのbuildを実行
$ yarn build
自機の実行環境
# macOS
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.7
BuildVersion: 19H2
# node.js
$ node -v
v14.7.0
# yarn
$ yarn --version
1.22.5
● 開発環境
ディレクトリ
ディレクトリ構成
cli-tool
├── dist/
│ └── index.js
├── node_modules/
├── src/
│ ├── main.ts
│ └── component.ts # いい感じにファイルを分割する
├── package.json
├── tsconfig.json
└── yarn.lock
コンフィグ
# 作業ディレクトリ確認
$ pwd
// -> cli-tool/
# モジュールインストール
$ yarn add --dev @vercel/ncc typescript
# tsconfig作成
$ ./node_modules/.bin/tsc --init
型定義なんかも入れて、package.jsonはこんな感じです。
package.json
{
"name": "cli-tool",
"version": "1.0.0",
"license": "UNLICENSED",
"main": "./dist/index.js",
"scripts": {
"build": "ncc build src/main.ts --minify",
"watch": "ncc build src/main.ts --watch",
},
"dependencies": {
"cli-color": "^2.0.0",
"command-line-args": "^5.1.1",
"command-line-usage": "^6.1.0",
"source-map-support": "^0.5.19"
},
"devDependencies": {
"@types/cli-color": "^2.0.0",
"@types/command-line-args": "^5.0.0",
"@types/command-line-usage": "^5.0.1",
"@types/node": "^14.14.5",
"@types/source-map-support": "^0.5.3",
"@vercel/ncc": "^0.24.1",
"typescript": "^4.0.5"
}
}
tsconfig.jsonは参考記事から変わらず
tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
"target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"declaration": false, /* Generates corresponding '.d.ts' file. */
"declarationMap": false, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
outDir. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
/* Additional Checks */
"noUnusedLocals": true, /* Report errors on unused locals. */
"noUnusedParameters": true, /* Report errors on unused parameters. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": ["src/**/*"]
}
main.ts
#!/usr/bin/env node
"use strict";
// ------------
// メイン処理
// ------------
const optionArg = { argv: process.argv };
const test = () => {
const argv = optionArg.argv;
const name = argv[2];
if (name) {
console.log(`Hello, ${name}!`);
} else {
console.log(`alert:require argv.`);
}
};
const main = () => {
test();
};
if (require.main === module) {
main();
}