Windows版のNushellではドライブレターを意識した方がよい話

Windows版のNushellではドライブレターを意識した方がよい話

Clock Icon2025.02.02

しばたです。

私は普段からWindowsでNushellを常用しているのですが、今回かなり珍しい事象に遭遇したので本記事で共有したいと思います。

https://www.nushell.sh/

はじめに

遭遇した事象

最近業務でNode.js (Remix)の開発を手伝うことになり開発環境を整備していました。
マシンスペックの都合WSLではなくWindowsホスト側で環境をつくりnpm run devコマンドを実行して開発サーバー(Vite)を起動したところ、Nushellで実行したときだけ

Could not resolve module for file: <tsxファイル名>

といったエラーが発生する事象が起きました。
最低限のRemixアプリケーションでも再現可能だったので以下にその内容を記載しておきます。

Nushell
# Remixアプリケーションを作成
cd c:\temp\
npx create-remix@latest

# 作成したアプリケーションに対して npm run dev コマンドで開発サーバーを起動するとエラーが出る
cd c:\temp\my-remix-app\
npm run dev -- --host

windows-drive-letter-problem-on-nushell-01
Nushellでコマンドを実行したときだけエラーが発生する

一応package.jsonの内容も記載しておきます。

クリックして展開
package.json
{
  "name": "my-remix-app",
  "private": true,
  "sideEffects": false,
  "type": "module",
  "scripts": {
    "build": "remix vite:build",
    "dev": "remix vite:dev",
    "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
    "start": "remix-serve ./build/server/index.js",
    "typecheck": "tsc"
  },
  "dependencies": {
    "@remix-run/node": "^2.15.3",
    "@remix-run/react": "^2.15.3",
    "@remix-run/serve": "^2.15.3",
    "isbot": "^4.1.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@remix-run/dev": "^2.15.3",
    "@types/react": "^18.2.20",
    "@types/react-dom": "^18.2.7",
    "@typescript-eslint/eslint-plugin": "^6.7.4",
    "@typescript-eslint/parser": "^6.7.4",
    "autoprefixer": "^10.4.19",
    "eslint": "^8.38.0",
    "eslint-import-resolver-typescript": "^3.6.1",
    "eslint-plugin-import": "^2.28.1",
    "eslint-plugin-jsx-a11y": "^6.7.1",
    "eslint-plugin-react": "^7.33.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "postcss": "^8.4.38",
    "tailwindcss": "^3.4.4",
    "typescript": "^5.1.6",
    "vite": "^5.1.0",
    "vite-tsconfig-paths": "^4.2.1"
  },
  "engines": {
    "node": ">=20.0.0"
  }
}

これがPowerShell環境(PowerShell 5.1および7系両方)だと同じコマンドを実行してもエラーにはなりませんでした。

windows-drive-letter-problem-on-nushell-02
同じコマンドをPowerShellで起動するとエラーは出ない

windows-drive-letter-problem-on-nushell-03

はじめて遭遇した事象で、状況からNushell側に何らかの問題があるのは明白だったのですが、原因を突き止めるまでにかなりの時間を要しました。

原因と対処法

調査の結果エラーメッセージ自体はRemix側の次の部分で発生していることが分かりました。

https://github.com/remix-run/remix/blob/remix%402.15.3/packages/remix-dev/vite/styles.ts#L67-L89

細かい内容までは分からないものの、絶対パス指定のファイル名(normalizedPath)からモジュール情報を取得する様でした。
この部分がNushellで実行した時だけnode変数に値が設定されておらず、normalizedPathが期待したものでは無くなっていることがわかりました。

NushellとPowerShellそれぞれでコマンドを実行した際のnormalizedPathの値を比較すると次の様になり、ドライブレターの大文字(C:)と小文字(c:)に差異があることが分かりました。

normalizedPath変数の中身
# NG : Nushellの場合 - ドライブレターが小文字
c:/temp/my-remix-app/app/entry.client.tsx
c:/temp/my-remix-app/app/root.tsx
c:/temp/my-remix-app/app/routes/_index.tsx

# OK : PowerShellの場合 - ドライブレターが大文字
C:/temp/my-remix-app/app/entry.client.tsx
C:/temp/my-remix-app/app/root.tsx
C:/temp/my-remix-app/app/routes/_index.tsx

Remix(もしくはNode.js)側の処理において小文字のドライブレターではファイルを見つけられないのでしょう。
これで原因はわかったのでNushellのドライブレターをどうにかして大文字(C:)にしようと悩んでいたのですが、結局はディレクトリ移動する際に大文字でドライブレターを入力するだけで良いことが分かりました。

Nushell
# ドライブレターを大文字にしてディレクトリを移動するだけで問題は回避できる
cd C:\temp\my-remix-app\

# 余談だがNushellではcdコマンドを使わずディレクトリ名だけ入力しても移動できる
C:\temp\my-remix-app\

windows-drive-letter-problem-on-nushell-04
ドライブレターが大文字になるだけで問題を回避できた

原因が分かってしまえば大したことない話ですが、正直かなり悩みました...

現状Nushellでは小文字のドライブレターを許容してしまう

ここまでの通り、現状Windows版のNushellでは大文字・小文字両方のドライブレターを受け入れてしまいます。
その上カレントディレクトリも大文字・小文字が分かれた形で表現されてしまっています。

windows-drive-letter-problem-on-nushell-05
Nushellでは大文字・小文字どちらのドライブレターも受け入れてしまう

対してPowerShellではcd c:\temp\my-remix-app\といった小文字のドライブレター入力を許可するものの、内部的には常に大文字のドライブレターでディレクトリが表現されます。

windows-drive-letter-problem-on-nushell-06
PowerShellではドライブレターは常に大文字で扱われる

本来Windowsのドライブレターは大文字が正しい形なのでどうにかNushell側にフィードバックしたいものの、これ以外にもドライブレター周りの問題がいくつかある様でどう伝えるべきか悩ましい感じです。

最後に

以上となります。

本記事の様な問題に遭遇する方はそう多くないかもしれませんが、この内容が誰かの役に立てば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.