Node.jsでreplaceAllを使用するとv14.21.2以下はエラーになる

replaceAllとは

replaceAll() メソッドはマッチしたすべての文字列を指定した文字列に置き換えて返します。

以前はすべてのfooをbarに置換する場合、replace(/foo/g, 'bar') のように書かなければならなかったが、replaceAllなら replaceAll('foo', 'bar') のようにシンプルに記述できます。

const str = 'foo bar foo'
const result = str.replaceAll('foo', 'baz')
console.log(result)
// => baz bar baz

IE11だとreplaceAllが使用できなかったので以前は使用されるケースが少なかったが、2022年6月にIE11のサポートが終了したため、2022年から使用されるケースが多くなっている。

Node.jsではバージョンが古いとエラーになる

最近Node.jsでreplaceAllを使用してエラーになるというケースをGitHubやQAサイトなどで見かけることが多くなってきました。

これはreplaceAllはバージョンが15以上でないと使用不可のためです。

試しにnode -vがv15.0.0の環境でreplaceAllを使用すると問題なく実行できますが、v14.21.2以下で実行するとエラーになります。

$ nodebrew use v15.0.0
use v15.0.0
$ node -v
v15.0.0
$ node replaceAll.js
baz bar baz

$ nodebrew use v14.21.2
use v14.21.2
$ node -v
v14.21.2
$ node replaceAll.js
file:///Users/iwbjp/replaceAll.js:2
const result = str.replaceAll('foo', 'baz')
                   ^

TypeError: str.replaceAll is not a function
    at file:///Users/iwbjp/replaceAll.js:2:20
    at ModuleJob.run (internal/modules/esm/module_job.js:183:25)
    at async Loader.import (internal/modules/esm/loader.js:178:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)
    at async handleMainPromise (internal/modules/run_main.js:59:12)

対策としては以下の3つの解決方法があります。

  1. nodeのバージョンアップを行う
  2. replaceAllをreplace(/ /g, 〜に変える
  3. String.prototypeにreplaceAllを追加する

3.のコードは以下の通り。

if (!String.prototype.replaceAll) {
	String.prototype.replaceAll = function(str, replaceStr) {
		return this.replace(new RegExp(str, 'g'), replaceStr)
	}
}

const str = 'foo bar foo'
const result = str.replaceAll('foo', 'baz')
console.log(result)
// => baz bar baz

上記のいずれかの対策すればreplaceAllでエラーが表示されなくなります。