Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

環境変数として BUCKET_NAME を設定していないと npm start で動作しない #78

Open
dynamis opened this issue Mar 8, 2022 · 14 comments · Fixed by #115

Comments

@dynamis
Copy link
Contributor

dynamis commented Mar 8, 2022

環境変数ではなく .env にて BUCKET_NAME を設定するように指示されているが、npm run dev はそれで問題ないが npm start する場合には s3 のライブラリが .env を読みにいかずに環境変数 (や ~/.aws/config) などだけを見に行くようで、環境変数として BUCKET_NAME を設定していなければ Bucket 指定がされておらず Empty value provided for input HTTP label: Bucket. エラーになる

/ へのアクセス時のサーバログ

Empty value provided for input HTTP label: Bucket.
  at Object.serializeAws_restXmlListObjectsCommand (./.output/server/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:2399:19)
  at processTicksAndRejections (internal/process/task_queues.js:93:5)
  at async ./.output/server/node_modules/@aws-sdk/middleware-serde/dist-cjs/serializerMiddleware.js:5:21
  at async ./.output/server/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
  at async findTrainers (file://./.output/server/chunks/middleware/index.mjs:21:19)
  at async file://./.output/server/chunks/middleware/index.mjs:69:22
Empty value provided for input HTTP label: Bucket.
  at Object.serializeAws_restXmlListObjectsCommand (./.output/server/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:2399:19)
  at processTicksAndRejections (internal/process/task_queues.js:93:5)
  at async ./.output/server/node_modules/@aws-sdk/middleware-serde/dist-cjs/serializerMiddleware.js:5:21
  at async ./.output/server/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
  at async findTrainers (file://./.output/server/chunks/middleware/index.mjs:21:19)
  at async file://./.output/server/chunks/middleware/index.mjs:69:22
Cannot read property 'length' of null
  at file://./.output/server/chunks/app/server.mjs:3995:29
  at renderFnWithContext (file://./.output/server/chunks/index.mjs:2348:21)
  at Object.ssrRenderSlot (file://./.output/server/chunks/index.mjs:10284:21)
  at _sfc_ssrRender$8 (file://./.output/server/chunks/app/server.mjs:3941:26)
  at renderComponentSubTree (file://./.output/server/chunks/index.mjs:9912:13)
  at renderComponentVNode (file://./.output/server/chunks/index.mjs:9857:16)
  at Object.ssrRenderComponent (file://./.output/server/chunks/index.mjs:10272:12)
  at _sfc_ssrRender$6 (file://./.output/server/chunks/app/server.mjs:3992:32)
  at renderComponentSubTree (file://./.output/server/chunks/index.mjs:9912:13)
  at file://./.output/server/chunks/index.mjs:9854:29

/api/trainers へのアクセス時のサーバログ:

Listening on http://localhost:3000/
[HPM] Proxy created: /  -> https://pokeapi.co
[HPM] Proxy rewrite rule created: "^/api/pokeapi" ~> "/api/v2"
Empty value provided for input HTTP label: Bucket.
  at Object.serializeAws_restXmlListObjectsCommand (./.output/server/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:2399:19)
  at async ./.output/server/node_modules/@aws-sdk/middleware-serde/dist-cjs/serializerMiddleware.js:5:21
  at async ./.output/server/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
  at async findTrainers (file://./.output/server/chunks/middleware/index.mjs:21:19)
  at async file://./.output/server/chunks/middleware/index.mjs:69:22

.output/server/chunks/middleware/index.mjs の冒頭部分:

import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { S3Client, ListObjectsCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
import fetch from 'node-fetch';

var _a, _b;
const REGION = (_a = process.env.REGION) != null ? _a : "ap-northeast-1";
const BUCKET_NAME = (_b = process.env.BUCKET_NAME) != null ? _b : "";

const s3Client = new S3Client({ region: REGION });
const s3Client$1 = s3Client;

const streamToString = (stream) => new Promise((resolve, reject) => {
  const chunks = [];
  stream.on("data", (chunk) => chunks.push(chunk));
  stream.on("error", reject);
  stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
});
const findTrainers = async () => {
  var _a;
  const objects = await s3Client$1.send(new ListObjectsCommand({ Bucket: BUCKET_NAME }));
  return (_a = objects.Contents) != null ? _a : [];
};

process.env.BUCKET_NAME を参照してますね。こちらのコードを webpack した結果っぽい:
https://github.com/webdino/lyceum-pokemon/blob/42d644afffc2c4cfc7cf5b71ba0156fd28c0d24a/express/utils/env.js

vite で .env をロードする といってるが vite がビルドした後の node .output/... を実行するときに読み込んでくれるケアまではしてくれないと言うことか。

@knokmki612
Copy link
Contributor

process.env.BUCKET_NAME を参照してますね

ビルド前のソースコードも process.env を参照しています
nitro server側はなぜか import.meta.env が参照できませんでした(気のせいかもしれませんが)

@knokmki612
Copy link
Contributor

import.meta.env を使っていないためにプロダクションビルド時に vite が置換してくれず、実行時に BUCKET_NAME を引き続き環境変数として渡す必要があるということかなと思いました

@kou029w
Copy link

kou029w commented Mar 9, 2022

環境変数が誤ってクライアントに漏れてしまうことを防ぐために、VITE_ から始まる変数のみが Vite で処理されたコードに公開されます。

とあるとおり、環境変数を展開してバンドルするには VITE_ からはじまる名前にする必要があるかと思います。

@knokmki612
Copy link
Contributor

knokmki612 commented Mar 9, 2022

環境変数が誤ってクライアントに漏れてしまうことを防ぐために、VITE_ から始まる変数のみが Vite で処理されたコードに公開されます。

こちらはクライアント(Nuxt /pages 下など)での環境変数の参照が可能か否かに影響がある話だと思っていました

プロダクションでは、これらの環境変数は、静的に置換されます。

https://ja.vitejs.dev/guide/env-and-mode.html#production-replacement

上記引用によると VITE_ から始まるかに関わらず環境変数はバンドルに含まれるのではないでしょうか


VITE_BUCKET_NAME に環境変数名を変更してプロダクションビルドの動作検証をしてみました

diff --git a/express/utils/env.js b/express/utils/env.js
index b3ae588..d12cf19 100644
--- a/express/utils/env.js
+++ b/express/utils/env.js
@@ -1,2 +1,2 @@
 export const REGION = process.env.REGION ?? "ap-northeast-1";
-export const BUCKET_NAME = process.env.BUCKET_NAME ?? "";
+export const BUCKET_NAME = process.env.VITE_BUCKET_NAME ?? ""
  1. 上記のように変更
  2. .env の値を適切に変更
  3. yarn build && yarn start を実行
  4. http://localhost:3000/ にブラウザでアクセス

しましたが Empty value provided for input HTTP label: Bucket. が表示されました

実行結果
$ yarn start
yarn run v1.22.15
$ node .output/server/index.mjs
Listening on http://localhost:3000/
[HPM] Proxy created: /  -> https://pokeapi.co
[HPM] Proxy rewrite rule created: "^/api/pokeapi" ~> "/api/v2"
Empty value provided for input HTTP label: Bucket.
  at Object.serializeAws_restXmlListObjectsCommand (./.output/server/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:2399:19)  
  at async ./.output/server/node_modules/@aws-sdk/middleware-serde/dist-cjs/serializerMiddleware.js:5:21  
  at async ./.output/server/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22  
  at async findTrainers (file://./.output/server/chunks/middleware/index.mjs:21:19)  
  at async file://./.output/server/chunks/middleware/index.mjs:69:22
Empty value provided for input HTTP label: Bucket.
  at Object.serializeAws_restXmlListObjectsCommand (./.output/server/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:2399:19)  
  at processTicksAndRejections (node:internal/process/task_queues:96:5)  
  at async ./.output/server/node_modules/@aws-sdk/middleware-serde/dist-cjs/serializerMiddleware.js:5:21  
  at async ./.output/server/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22  
  at async findTrainers (file://./.output/server/chunks/middleware/index.mjs:21:19)  
  at async file://./.output/server/chunks/middleware/index.mjs:69:22
Cannot read properties of null (reading 'length')
  at file://./.output/server/chunks/app/server.mjs:3994:29  
  at renderFnWithContext (file://./.output/server/chunks/index.mjs:2348:21)  
  at Object.ssrRenderSlot (file://./.output/server/chunks/index.mjs:10296:21)  
  at _sfc_ssrRender$8 (file://./.output/server/chunks/app/server.mjs:3940:26)  
  at renderComponentSubTree (file://./.output/server/chunks/index.mjs:9924:13)  
  at renderComponentVNode (file://./.output/server/chunks/index.mjs:9869:16)  
  at Object.ssrRenderComponent (file://./.output/server/chunks/index.mjs:10284:12)  
  at _sfc_ssrRender$6 (file://./.output/server/chunks/app/server.mjs:3991:32)  
  at renderComponentSubTree (file://./.output/server/chunks/index.mjs:9924:13)  
  at file://./.output/server/chunks/index.mjs:9866:29

@kou029w
Copy link

kou029w commented Mar 9, 2022

プロダクションでは、これらの環境変数は、静的に置換されます。

この「これらの環境変数」とは、その上の import.meta.env.MODE をはじめとするいくつかの特別な環境変数のことだと思います。(そういう意味では VITE_ からはじまる必要がある、という点は誤りですね。。。訂正します。)

@kou029w
Copy link

kou029w commented Mar 9, 2022

$ grep -nr VITE_BUCKET_ .output
.output/server/chunks/middleware/index.mjs:8:const BUCKET_NAME = (_b = process.env.VITE_BUCKET_NAME) != null ? _b : "";

これをみると確かにサーバーサイドの環境変数への参照は展開してバンドルされず、そのままのようですね。

@kou029w
Copy link

kou029w commented Mar 9, 2022

プロダクションビルド時に vite が置換してくれず、実行時に BUCKET_NAME を引き続き環境変数として渡す必要があるということかなと思いました

これは正しいです。

@dynamis
Copy link
Contributor Author

dynamis commented Mar 16, 2022

nitro server側はなぜか import.meta.env が参照できませんでした

結局ここが困りものなわけですよね。
すべて import.meta.env で統一したコードを書けて process.env 使わずに済めば全てビルド時の静的置き換えで済むのに...

@dynamis
Copy link
Contributor Author

dynamis commented Mar 16, 2022

念のため: process.env は BUCKET_NAME 以外に REGION の読み込みにも使っていた

こちらは初期値があるから問題が顕在化しないことも多いと思うが、東京リージョン以外を使う場合、REGION も環境変数設定しないと動かないという意味では同じ。

@knokmki612
Copy link
Contributor

26b6bbe で注意事項としてドキュメンテーションされたので、issueとしては対応完了になるでしょうか

@dynamis
Copy link
Contributor Author

dynamis commented Mar 16, 2022

nitro server側はなぜか import.meta.env が参照できませんでした

server middleware だから Node 標準ではないフレームワークやバンドル/ビルドツールである Nuxt/Vite のビルドによる変換処理は挟まらない。なので当然 import.meta.env 発変えないという話でしたね。

process.env があるか、.env ファイルを読むかという処理を明示的に書けそうな気もするけど取りあえず環境変数も Nuxt 側と Express 側で性質が違い、それぞれに何処でどのように設定すべきか違うというのは無理に解消しなくとも良いかと思いました。

issueとしては対応完了になるでしょうか

bug ではないしそういう仕様だと思えば何ら問題ないですが、使い勝手としては何とかしたい (.env 書くだけで良い形に express 側のコードを改善したい) という要望としては残ってても良いかも。(使い勝手を便利にするために必要以上にコードが複雑化するのは初心者向けの説明・サンプルコードとしては不適と考えることも出来るけど)

@knokmki612
Copy link
Contributor

#105 の変更により、Expressのコードはtsupでビルドするようにしましたので、定数置換可能になったかと思います
https://esbuild.github.io/api/#define

@knokmki612
Copy link
Contributor

#119 を取り込むと元の状態にもどる気がしますね

@dynamis
Copy link
Contributor Author

dynamis commented Mar 3, 2023

#119 (と #120) をマージしたので reopen します

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants