0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloud Run functions × TypeScript 開発をしよう!【開発環境:TypeScript環境 ─ tsconfig.jsonの設定】

Last updated at Posted at 2024-12-06

はじめに

この章では以下の内容について説明します。

  • typscript実行環境の作り方
  • tsconfig.jsonの記述方法

Cloud Run functionsでのTypeScript環境の作り方は人によってバラバラで「コレ!」という方法が今のところ見つかっていない感じがあります。
しかし僕的には本記事(と次の記事)で紹介する方法が一番シンプルでスマートだと思います。

想定ディレクトリ

├── package.json
├── package-lock.json
└── src
    └── index.ts

前回と異なる点は、ソースファイルを格納するsrcディレクトリを作成し、そこにソースコードをぶち込むようにしています。

TypeScript実行環境の構築

typescriptパッケージのインストール

npm install --save-dev typescript

これによってtscコマンドが使えるようになり、index.tsindex.js にトランスパイル(簡単にいうと変換)できるようになります。

tsconfig.jsonの作成

実は tsconfig.json は別に作らなくてもtypescirpt使えます。がだと言って作らないでおくと色々面倒なので作っておきましょう。
tsc --inittsconfig.jsonが作成されます。

...が、使いづらいので使いません。試しに実行してみましょう。

試しにtsconfig.jsonを作成するコマンドを実行
npx tsc --init
結果
Created a new tsconfig.json with:                                                                                       
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true


You can learn more at https://aka.ms/tsconfig
出力されるtsconfig.json
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Projects */
    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */

    /* Language and Environment */
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
    // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
    
    // ...

...ほとんどコメントアウト...😅
見にくいし、全くあんまり使えません。

2024年現在、Cloud Run functions用にスクラッチから作るなら以下のようになると思います。

Cloud Run functions用のシンプルなtsconfig.json
{
  "compilerOptions": {
    "target": "es2022",
    "module": "node16",
    "moduleResolution": "node16",
    "baseUrl": "./src",
    "paths": {
      "@/*": ["./*"]
    },
    "rootDirs": ["./src"],
    "outDir": "./dist",
    "sourceMap": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
  },
  "include": ["src/**/*"],
  "exclude": ["dist", "node_modules"]
}

特に説明した方がよさそうな項目について説明していきます。

target

TS → JSへのトランスパイル時にどのバージョンのJavaScriptで出力するかを記載します。
es2023以下に設定するのが適切そうですが、es2022 にしておきます。理由は後述します。

module

トランスパイスしたJSを動かす環境が期待しているモジュール形式です。

Node.jsの設定値で正しいのは node16nodenext です。 commonjsesnext を設定するのは誤りのようです。

Node.js’s rules for module format detection and interoperability make it incorrect to specify module as esnext or commonjs for projects that run in Node.js, even if all files emitted by tsc are ESM or CJS, respectively.

nodenextではバージョンが動的に変わってしまうため、node16に設定します。

そして node16 に設定すると暗示的に targetes2022 に、moduleResolutionnode16 に変わるみたいです。targetes2023 にしなかったのはこの理由からです。
設定する意味ないぢゃん!

Moduleの話は公式リファレンスでも詳しく説明されていますので、参考ください。

baseUrl

どこを起点にモジュール解決するかの設定。
例えば、以下のようなディレクトリ構成でbaseUrl./srcとした場合、

project_root
    └─ src
        ├── services
        │   ├── product.ts
        │   └── order.ts
        ├── lib
        │   └── time.ts
        └── index.ts

src/service/product.ts から src/lib/time.ts相対パスを使わないで参照する場合、以下の記述でファイル参照ができます。

src/service/product.ts
import time from 'lib/time';

もちろん、相対パスは通常通り使えます。

src/service/product.ts
import time from '../lib/time';

ただ、以下はNGです。

src/service/product.ts
import time from 'order'; // ./src/order.ts が参照される

rootDirs

どのディレクトリ階層以降をコンパイル対象にするかの設定。
./src より前のディレクトリ階層を指定しようとするとエラーになる。

project_root
    ├── src
    │   ├── services
    │   │   ├── product.ts
    │   │   └── order.ts
    │   ├── lib
    │   │   └── time.ts
    │   └── index.ts
    └── sample.ts

以下の呼び出しはNGになります。

src/service/product.ts
import sample from '../../sample'; // NG

paths

モジュール解決の際にエイリアスを設定できるオプション。
baseUrlを指定するとその位置を基準にとしてエイリアスが設定される。

paths
// ...
    "paths": {
      "@/*": ["./*"] // @/xxx で src/xxx を指定したのと同じ
    }, 

例えば以下のようにできる。

src/service/product.ts
// import time from '../lib/time' がスッキリする
import time from '@/lib/time';

ただし注意ですが、tscによるトランスパイル後のJSファイルを実行しようとするとエラーになります。

あれ?
src/index.ts:2:24 - error TS2307: Cannot find module '@/xxx' or its corresponding type declarations.

トランスパイル後のJSファイルを見てみるとわかるのですが、エイリアスがそのまま出力されており、パス解決ができない状態になっています。

./dist/index.js
var sample_1 = require("@/test/sample"); // エイリアスがそのまま出力されてしまっている

大事なことなのですが、トランスパイルしただけではimportのパス解決はできません。 別途ビルドツールを使ってモジュール解決できるよう変換する必要があります(違っていたら教えてください)。
次章以降でこの解決方法を紹介していきます。

おわりに

こうして構築した環境を利用して、次の記事ではTypeScript上でCloud Run functions関数を実行する方法を紹介していきます。

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?