javascript の class でプライベート関数、変数を使う & Webpack でのビルドエラー

javascript で private な関数(メソッド)、変数(プロパティ)を利用したい時、
その昔 _ (アンダーバー) などを先頭につけて属人的に管理していた。
アンダーバーつけても実体はパブリックなのでクラスの外から利用できた。

ES2022の新機能

ES2022の新機能でついにプライベートを定義できるようになった。
単純に先頭に # (シャープ)つければいいらしい。

class Sample {

	// プライベートプロパティ
	// #hello
	#hello = 'hello'

	constructor() {
		// this.#hello = 'hello'
	}

	get say() {
		return this.#hello
	}

	hey() {
		return `hey! ${this.#yo()}`
	}

	// プライベートメソッド
	#yo() {
		return 'yo!'
	}

}

sample = new Sample()

console.log(sample.#hello) // SyntaxError
console.log(sample.#yo()) // SyntaxError

console.log(sample.say) // "hello"
console.log(sample.hey()) // "hey! yo!"

詳しくは下記参考。

Webpack でのビルドエラー

次に問題になったのは、
Webpack などでビルドする時にエラーが出るようになったこと。

$ npm run build
ERROR in ./js/xxxxxx/Xxxxxx.js xx:xx
Module parse failed: Unexpected character '#' (xx:xx)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

下記プラグインを使えば解決する。

$ npm install babel-loader --save-dev

# 下記インストール
$ npm install @babel/preset-env --save-dev
$ npm install @babel/plugin-proposal-private-methods --save-dev

webpack.config.js

関係あるとこのみ抜粋。
presets と plugins どちらも追加する。

@babel/plugin-proposal-private-methods はプライベートな変数や関数を定義するために必要。
@babel/preset-env はクラス内に変数を定義する時に必要っぽい。

module.exports = {
	...
	module: {
		rules: [
			{
				test: /\.js/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-env'],
						plugins: ['@babel/plugin-proposal-private-methods']
					}
				}],
			},
		],
	},
	...
}

関連記事