BOM 付き UTF-8 のファイルから BOM を取り除く Node.js スクリプト

BOM 付き UTF-8 のテキストファイルを指定して、BOM を取り除いて同ファイルに上書き保存する Node.js スクリプトを書いた。

経緯

node-sass を利用してファイルを生成すると BOM 付き UTF-8 になってしまう、という話は以前した。

これを解消したく、BOM を削るコマンドやスクリプトを調査していた次第。

BOM を削る npm パッケージは、今回使用した strip-bom の他、strip-bom-clistrip-bom-stream などの派生系もあったのだが、「元のファイルに上書き保存する」というのが上手くできず (0バイトのファイルになってしまう)、諦めた。

ワンライナーでやれたら良かったが、オリジナルのファイルと別名でファイルを作って、オリジナルのファイルを消して…とやるのもキツイので、Node.js スクリプトを書いた。

スクリプト・導入に際して

まずは Node.js スクリプトを紹介。

const fs = require('fs');
const stripBom = require('strip-bom');

// 引数がなければ中止する
if(process.argv.length < 3) {
  console.log('Invalid arguments, abort.');
  return;
}

// 引数から指定されたファイル一覧を取得する
const files = process.argv.slice(2, process.argv.length);

// ファイルごとに BOM を除去して上書きする
files.forEach((file) => {
  const text = fs.readFileSync(file, 'utf-8');
  const stripped = stripBom(text);
  fs.writeFileSync(file, stripped);
});

このスクリプトを使用するには strip-bom パッケージが必要なので、グローバルなりローカルなりにインストールしておく。

# グローバルインストール
$ npm i -g strip-bom

# ローカルインストール
$ npm i --save-dev strip-bom

使い方

この Node.js スクリプトを strip-bom.js といった名前で保存したとして、以下のように利用する。

$ node strip-bom.js ./some-file.txt

こうすると、some-file.txt を UTF-8 形式のファイルとして読み込み、BOM があれば BOM を削除して上書き保存する。

第3引数以降に複数ファイルを渡せば全て処理するし、アスタリスク * を使っても良い。

$ node strip-bom.js ./some-files/*

こうすると、./some-files/ 配下の全ファイルを操作できる。

ただ、自分が試した限りだと、package.json に npm-scripts として引数まで書いてしまうと、引数のファイルパスをそのまま文字列として受け取ってしまうようなので、指定方法には注意が必要。

{
  "name": "【package.json】",
  "scripts": {
    "strip-bom": "node strip-bom.js ./some-files/*"
  }
}

こんな風に書くと、第3引数に './some-files/*' という文字列が渡されてしまうのだ。


その他、対象のファイルのエンコーディングが正しいかとか、バイナリファイルでないか、などはチェックしていないので、余計なファイルを選択してしまわないよう注意。

本来 readFileSyncwriteFileSync などもお行儀が良くないとされているが、自分の用途ではこれで十分なので、コレで運用する。