LoginSignup
1
0

More than 1 year has passed since last update.

AWS CDKをDenoで動かす4 CDK CLIも編

Last updated at Posted at 2022-06-03

の続きでDenoでCDKを動かしていきます

要約

  • CDK CLIをDenoで動かすのはダメでした
  • 問題を回避しても非対応なNode APIが使われているため現状Denoでは動かなそう
  • 以下書いてあるのは試行錯誤のメモです

CDK CLIもDenoにしたい

現状の構成ではCDKコード(なんと言うのが正しいのか不明)はDenoでしたが、
CDK CLIはNodeで動作しています。
CDK CLIもCDKコードの移行と同じノリで動かせないか試してみます。

トライアンドエラーの記録

素朴なインポート

確認のため単純に https://esm.sh/aws-cdk@2.26.0 をブラウザで開いてみます

/* esm.sh - error */
throw new Error("[esm.sh] " + "Could not resolve \"aws-cdk\"");
export default null;

うーんエラーですね。
ライブラリじゃないからindex.jsとかがないからですかね?

cdkコマンドをたどってみる

では実体のcdkコマンドの中身はどうなっているのか。

#!/usr/bin/env node
require('./cdk.js');

cdk.jsをrequireしているだけでした。
では https://esm.sh/aws-cdk@2.26.0/bin/cdk.js ではどうでしょうか

/* esm.sh - error */
throw new Error("[esm.sh] " + "esbuild: Do not know how to load path: esm-build-6d6e3a2749ffb4e9ef8c71f2514eb00cdd2b9cf3-8f306217/node_modules/aws-cdk/bin/cdk");
export default null;

内容が変わりましたがエラーのままですね。
bin/の下は取れないとかあるのでしょうか。

実装をたどる

うーんじゃぁ aws-cdk/bin/cdk.jsの中身は?

import { cli } from '../lib';

cli();

カンタンな実装で安心しました。
ここでimportしている https://esm.sh/aws-cdk@2.26.0/lib はどうでしょう?

/* esm.sh - aws-cdk@2.26.0/lib */
export * from "https://esm.sh/v85/aws-cdk@2.26.0/es2022/lib.js";
export { default } from "https://esm.sh/v85/aws-cdk@2.26.0/es2022/lib.js";

おっ、いけました。じゃぁこれを使うよう作れば行けるかも?

// cdk.ts (自前)
import lib from "https://esm.sh/aws-cdk@2.26.0/lib";
lib.cli();

import以外ほぼ同じコードを書いて実行します。

$ deno run --allow-all cdk.ts
<略>
error: Import 'https://esm.sh/v85/fsevents@2.3.2/deno/fsevents.js' failed: 500 Internal Server Error
    at https://esm.sh/v85/aws-cdk@2.26.0/deno/lib.js:2:1763

エラーですね…
fseventsってOptional DependencyでLinuxで必要なくなかったですか?
(試している環境はGitHub CodespacesのDevcontainer上のLinuxです)

Optional Dependencyを除外できるといいんだけどな…
esm.shのIssueに上がっていましたので既知の問題のようです。

fseventsをダマす

通常Linuxでは必要ないんだからimportが満足したらなんとかなるのでは?
うまく騙せる方法はないでしょうか。

調べてみたところDenoにはImport mapsという機能があり、import参照先を差し替えられるようです。
これは使えそうなので試してみます。

まず、差し替え先となるfsevents-stub.jsを空ファイルで作ります。

// fsevents-stub.js

そして、それに差し替えるimport mapファイルを作成します。
(バージョンベタ書きですぐ壊れそう…)

// importmap.json
{
  "imports": {
    "https://esm.sh/v85/fsevents@2.3.2/deno/fsevents.js": "./fsevents-stub.js"
  }
}

import mapオプションを渡して実行します。

$ deno run --allow-all --import-map=importmap.json cdk.ts
<略>
Check file:///workspaces/cdk-deno/cdk.ts
error: TS2300 [ERROR]: Duplicate identifier 'URLSearchParams'.
declare class URLSearchParams {
              ~~~~~~~~~~~~~~~
    at asset:///lib.deno.url.d.ts:8:15

    'URLSearchParams' was also declared here.
            interface URLSearchParams extends _URLSearchParams {}
                      ~~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v85/@types/node@16.11.33/url.d.ts:822:19    and here.
            var URLSearchParams:
                ~~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v85/@types/node@16.11.33/url.d.ts:843:13

TS2300 [ERROR]: Duplicate identifier 'URL'.
declare class URL {
              ~~~
    at asset:///lib.deno.url.d.ts:155:15

    'URL' was also declared here.
            interface URL extends _URL {}
                      ~~~
        at https://cdn.esm.sh/v85/@types/node@16.11.33/url.d.ts:823:19    and here.
            var URL:
                ~~~
        at https://cdn.esm.sh/v85/@types/node@16.11.33/url.d.ts:833:13

Found 2 errors.

おっ進んだ!!
でもTypeScriptのエラーですね…

そもそも@types/node@16.11.33にエラーがあるのかビミョウですが、
これなら型チェックすっ飛ばせばなんとかなるのでは…

そもそもCLIは型チェックしなくていいと思うし。

型チェックを省略

TypeScriptの型チェックを省略する--no-checkオプションをつけて実行してみます。

$ deno run --allow-all --import-map=importmap.json --no-check cdk.ts
error: Uncaught SyntaxError: The requested module '/v85/fsevents@2.3.2/deno/fsevents.js' does not provide an export named 'default'
    at <anonymous> (https://esm.sh/v85/aws-cdk@2.26.0/deno/lib/index.js:2:332)

また進んだ!
今度は差し替えたニセモノのfseventsの問題のようです。
エラーからするとdefault exportしたなにかしらがあれば通りそう…
さすがに空じゃマズかったか…

fseventsをダマす その2

ということで修正。

// fsevents-stub.js
export default class A {}

そして実行。

$ deno run --allow-all --import-map=importmap.json --no-check cdk.ts
error: Uncaught Error: Not implemented: See https://github.com/denoland/deno_std/issues/1436
  throw new Error(message);
        ^
    at <anonymous> (https://deno.land/std@0.141.0/node/_utils.ts:22:9)

おーまた進んだ!
けど今度はdenoが明示的に投げてるエラーです…

DenoのNode互換はまだまだ

エラーメッセージで出てきたIssueはnodeのos APIがまだ実装されていないものがある、というものでした。

CDK CLIはDenoがサポートしていないNode APIを呼び出してしまったのでしょう。

コールスタックが出ていないのでどこでなんのAPIの呼び出しでエラーになったのかわからないですね…
AWSのクレデンシャル取るためのホームディレクトリの取得あたりが怪しいか?

まぁ今回はここらで諦めます…

感想

今までさっくり動いて来たけど、流石にそうカンタンに全部は動きませんよね。
むしろこうでなくっちゃ(?)

メモリ消費量がハンパなく試してる途中もOOM Killerに(?)Denoが殺されたり
動いたとしてもいいことがほぼなさそうです。
(aws-sdkとかの依存が重すぎる?)

当面はnodeをインストールするくらいの手間は受け入れましょう…

Nodeの互換性が改善された日にはまた試してみます。

1
0
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
1
0