Closed Yuisei-Maruyama closed 2 years ago
README の複製を行うスクリプトの作成を行う中で、
npx ts-node XXX
を実行して、スクリプトを実行するのだが
下記のエラーに遭遇した。
MyPortfolio yuisei_rock$ npx ts-node duplicateReadme.ts
(node:61783) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/yuisei_rock/Desktop/aaa/MyPortfolio/duplicateReadme.ts:1
import { readFileSync } from 'fs';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:1001:16)
at Module._compile (internal/modules/cjs/loader.js:1049:27)
at Module.m._compile (/Users/yuisei_rock/Desktop/aaa/MyPortfolio/node_modules/ts-node/src/index.ts:1459:23)
at Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Object.require.extensions.<computed> [as .ts] (/Users/yuisei_rock/Desktop/aaa/MyPortfolio/node_modules/ts-node/src/index.ts:1462:12)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
at main (/Users/yuisei_rock/Desktop/aaa/MyPortfolio/node_modules/ts-node/src/bin.ts:389:12)
at Object.<anonymous> (/Users/yuisei_rock/Desktop/aaa/MyPortfolio/node_modules/ts-node/src/bin.ts:539:3)
上記を解決するためには、package.jsonに "type": "modules"
を記述しなければならない。
しかし、package.jsonに "type": "modules"
を記述すると、 npm run start
が動かなくなる。
MyPortfolio yuisei_rock$ npm run start
npm run start
> @scope/my-portfolio-client@0.0.1 start
> react-app-rewired start
internal/modules/cjs/loader.js:1102
throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/yuisei_rock/Desktop/aaa/MyPortfolio/config-overrides.js
require() of ES modules is not supported.
require() of /Users/yuisei_rock/Desktop/aaa/MyPortfolio/config-overrides.js from /Users/yuisei_rock/Desktop/aaa/MyPortfolio/node_modules/react-app-rewired/config-overrides.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename /Users/yuisei_rock/Desktop/aaa/MyPortfolio/config-overrides.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/yuisei_rock/Desktop/aaa/MyPortfolio/package.json.
そこで、root直下に tools
ディレクトリを作成し、その配下に package.json
を新たに作成し、
その中に { "type": "modules" } とだけ記述することで解決した。
(tools/package.json)
{ "type": "modules" }
(ディレクトリ構成)
./
+- package.json (書き換えたくない)
`- tools/
+- index.ts (npx実行対象のファイル)
`- package.json (これを追加する)
`- tsconfig.json (これを追加する)
readFileSync
を使用したファイル読み込みについて下記のような状態であった場合に root 直下の README.md
を読み込みたいとする。
├── tools
│ ├── duplicateReadme.ts <- このファイルでREADME.md を読み込みたい
│ ├── loadPackage.ts
│ ├── package.json
│ └── tsconfig.json
├── README.md
そのような場合、作業ディレクトリからのパスではなく、fsはパスを作業ディレクトリ から辿る!!!
上記の作業ディレクトリとは、 nodeを実行したファイルがあるディレクトリ のことを指す。
例えば、MyPortfolio
の階層で node を実行しようとする。
── MyPortfolio <- ここで node を実行している
├── README.md
├── src
├── tools
│ ├── duplicateReadme.ts
│ ├── loadPackage.ts
│ ├── package.json
│ └── tsconfig.json
上記の例であれば、readFileSync
のパスは
(duplicateReadme.ts)
const readme = readFileSync('README.md', 'utf8') // 正しく読み込める
const readme = readFileSync('../README.md', 'utf8') // no such file or directory, open になる
になる。
現在、 README は
README.md
documents/README.md
の 2箇所 に存在する。
上記 の
documents/README.md
を記載している理由としては、tsx
ファイルから root 直下のREADMEファイルのパスを読み込む良い手段が見つからないためにやむを得ず作成した。
しかし、上記の2ファイルをメンテナンスするのはコストが高く、片方を記述し忘れることも多々ある。
なので、
コミットが走ったタイミングで root 直下の
README.md
の内容をdocuments/README.md
に複製する形を考える。