webpack時に許されない dynamic import (require) の書き方
概要
次のように、動的インポートを含むコードをWebpackでコンパイルしようとすると、エラーが発生します。
const _ = require(`@/${variable}`)
具体的なエラー全文は長くなるので末尾に記載しますが、だいたいこんな感じの出力になります。
パースしてはだめなものまでパースしようとして失敗しているような表記なので紛らわしいですね。
ERROR in ./Dockerfile 1:5 Module parse failed: Unexpected token (1:5) ERROR in ./tsconfig.json Module parse failed: Unexpected token / in JSON at position 110 while parsing near '...le": "esnext", ERROR in ./yarn.lock 1:1 Module parse failed: Unexpected character ' ' (1:1)
解決
Webpackで静的にコンパイルする時点で対象ファイルのパスが分からなくなっているようです。 次のようにすれば解消されます。
const _ = require(`@/path/${variable}`)
ref
ちなみにこのリンクを見るとエイリアス @
を使用しない場合も症状が発生するようですが、
再現しませんでした。
エラー全文(一部)
asset server.js 320 KiB [emitted] (name: main) runtime modules 937 bytes 4 modules modules by path ./ 700 KiB modules by path ./src/ 187 KiB 61 modules modules by path ./config/ 8.98 KiB 9 modules modules by path ./__tests__/ 7.98 KiB 7 modules modules with errors 477 KiB [errors] 6 modules modules by path ./data/abis/*.js 7.7 KiB 3 modules ./app.ts 1.7 KiB [built] [code generated] .// sync ^\.\/.*$ 6.06 KiB [built] [code generated] ./package.json 3.17 KiB [optional] [built] [code generated] modules by path external "@google-cloud/ 84 bytes external "@google-cloud/firestore" 42 bytes [built] [code generated] external "@google-cloud/storage" 42 bytes [built] [code generated] 28 modules ERROR in ./Dockerfile 1:5 Module parse failed: Unexpected token (1:5) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders > FROM node:14-alpine | WORKDIR /usr/src/app | # ENV DOCKERIZE_VERSION v0.6.1 @ .// sync ^\.\/.*$ ./Dockerfile @ ./src/v1/helpers/session.ts 36:27-72 @ ./src/v1/helpers/index.ts 5:0-32 22:18-25 @ ./src/v1/index.ts 22:0-32 61:40-47 69:96-103 @ ./src/index.ts 2:0-22 5:17-19 @ ./app.ts 9:0-24 18:16-19 ERROR in ./tsconfig.json Module parse failed: Unexpected token / in JSON at position 110 while parsing near '...le": "esnext", You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders SyntaxError: Unexpected token / in JSON at position 110 while parsing near '...le": "esnext", @ .// sync ^\.\/.*$ ./tsconfig.json ./tsconfig @ ./src/v1/helpers/session.ts 36:27-72 @ ./src/v1/helpers/index.ts 5:0-32 22:18-25 @ ./src/v1/index.ts 22:0-32 61:40-47 69:96-103 @ ./src/index.ts 2:0-22 5:17-19 @ ./app.ts 9:0-24 18:16-19 ERROR in ./yarn.lock 1:1 Module parse failed: Unexpected character ' ' (1:1) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders > # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | # yarn lockfile v1 | @ .// sync ^\.\/.*$ ./yarn.lock @ ./src/v1/helpers/session.ts 36:27-72 @ ./src/v1/helpers/index.ts 5:0-32 22:18-25 @ ./src/v1/index.ts 22:0-32 61:40-47 69:96-103 @ ./src/index.ts 2:0-22 5:17-19 @ ./app.ts 9:0-24 18:16-19
gcloud系インスタンスをkeyFilenameを使わないで初期化する
前提
GCP のプロジェクト(cloud storage や firestore, firebase)を初期化するときに、大抵は次のようにファイルパスを指定するようになっています。
const Firestore = require('@google-cloud/firestore') const firebaseConfig = { projectId: 'YOUR_PROJECT_ID', keyFilename: '/path/to/keyfile.json', } const db = new Firestore(firebaseConfig)
ファイルの取り回しは面倒です。
- クラウドやdockerなど実行環境でパスが変わる
- webpackでパスが変わる
require(`@/config/keyfile.json`)
みたいにテンプレートリテラルが使いたい- 意図的に非同期処理しないといけない
解決
以下のように credentials: {private_key, client_email}
が指定できます。
const serviceAccount = require(`@/keyfile.json`) const firebaseConfig = { credentials: { private_key: serviceAccount.private_key, client_email: serviceAccount.client_email, }, projectId: serviceAccount.project_id } const db = new Firestore(firebaseConfig)
ソース
ここで議論されていました。 github.com
また、このソースはここです。