LoginSignup
7
1

More than 5 years have passed since last update.

Macでbrowserifyで結合しているとcase-insensitiveなファイル名指定をしても、Macでコケなくて、Linuxに持って行った時にコケる現象が、たまに起きる。これをカジュアルにチェックしたい

Last updated at Posted at 2017-08-14

状況説明

実行するbrowserifyコマンドです。

browserify src/js/client.js -o public/js/client.js

ソースファイルはsrc/js/client.jsです。出力先はpublic/js/配下です。

例えば

const viewModel = require('./view-model')

と書くべきところを

const viewModel = require('./view-Model')

とtypoしてしまった時に、browserifyを実行してもエラーは起きません。
macOSのファイルシステムではview-model.jsview-Model.jsは同一のファイルです。

Linuxでは違うファイルとして扱われます。
Linux上でbrowserifyを実行すると./view-Modelモジュールは見つかりません。失敗します。

実行環境

  • Node.js v8.3.0
  • browserify 14.4.0
  • eslint 4.3.0
  • eslint-plugin-import 2.7.0
  • Docker version 17.06.0-ce, build 02c1d87
  • node/alpine 8.3.0

作戦1 ESLint

ESLintでチェックできれば、Linuxに持っていく前に見つからないモジュールを検出できます。
eslint-plugin-import/no-unresolved.md at master · benmosher/eslint-plugin-importというESLintプラグインを使います。

eslint-plugin-importにはno-unresolvedというルールがあります。
このプラグインはimport構文用のプラグインですが、オプションでrequire関数にも対応します。

npm i -D eslint-plugin-importを実行してプラグインをインストールし、.eslintrc

"import/no-unresolved": [
  2,
  { commonjs: true }
]

な、ルール定義と

"plugins": ["import"]

な、plugin定義を足してください。

npx eslint src/js を実行すれば、解決不能なモジュール名が含まれていないかチェックできます。

エディタがESLintに対応していれば、編集時点でエラーを検出できます。
Atomの場合は、AtomLinter/linter-eslint: ESLint plugin for Atom Linterを使います。

注意点: 定数以外のrequire関数の引数

次のように書いた場合は、エラーは検出されません。

const path = './view-Model'
const viewModel = require(path)

require関数の引数に式や変数を入れるのはやめましょう。

ESLintで、require関数の引数が定数でないことを検出するには、import/no-dynamic-requireを使います。

"import/no-dynamic-require": [2]

の、ルール定義を追加してください。

作戦2 Docker

ESLintの実行環境がない場合でも、Dockerを使えば、開発OS上にcase-sensitiveな環境を構築できます。

この例では、package.jsonの以下の設定がしてあります。

  • devDependenciesブロックでbrowserifyが指定
  • scpritsブロックでbrowserify src/js/client.js -o public/js/client.jsが指定
FROM node:alpine

RUN mkdir -p /app

COPY ./package.json /app/
WORKDIR /app
RUN npm install

COPY src /app/src
RUN mkdir -p ./public/js
RUN npm start

時間のかかる、依存npmパッケージのインストールと、npm startを分離するためにCOPYを2つに分けています。
実行頻度が低い時は、1つにした方がイメージサイズが小さくなると思います。

docker build .

で実行します。
成功すれば、正しくモジュール解決できています。

ハマりやすい罠:Volume mountsではcase-sensitiveな環境は作れない

Volume mountsが使えれば、次のコマンドでビルドするより早く実行できるはすです。

docker run -it -v (PWD):/app node:alpine -c `cd app && npm start`

残念ながらVolume mountsを使うと、ファイルシステムはホストOSのままなのでcase-insensitiveになってしまいます。

Volume mounts case insensitive - Docker for Mac - Docker Forums

「ハマりやすい罠」というか、一番最初に試してハマりました。

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