webpack の入門書では、webpack.config.js
にファイルの出力先として以下の記述をよく見る。
output: { path: `${__dirname}/dist`, filename: 'main.js' },
これは、「ビルドした後のファイル出力先(output)は、ルートディレクトリ/dist
ディレクトリにmain.js
というファイル名で設置してね」という意味。
しかし、次の記述もよく見る。
const path = require('path') module.exports = { ~ output: { path: path.resolve(__dirname, 'public/js') } ~ }
さきほどは ${__dirname}/dist
と書いていたのに、今度はpath.resolve()
メソッドを使ってパスを指定している。また、Node.js モジュールの path も require
している。
path.resolve(__dirname, 'public/js')
と書くことで、ルートディレクトリ/public/js
という絶対パスが返る。ビルド後のファイルはこのディレクトリ下に設置される。
「絶対パスを指定している」という点では、両方とも同じだ。
ではなぜ、path.resolve
を使っているのか?
結論からいうと、OSの違いによって思わぬ挙動が起こらないように、安全のためこういった書き方をしているようだ。
まず、そもそもpath.resolve()
が何をしているのかを調べてみた。
path.resolve()
は絶対パスを返す
これについては挙動を見てみたほうがわかりやすい。
#REPLを起動する $ node #pathをrequireして使えるようにする const path = require('path') #今はこのパスにいる :~/dev/webpack-jissen-nyumon
ためしに、path.resolve('index.js')
をしてみるとどうなるか?
> path.resolve('index.js') '/Users/kotakanazawa/dev/webpack-jissen-nyumon/index.js'
プロジェクト直下にindex.js
を設置した絶対パスが返ってきた。
次に、path.resolve('src', 'index.js')
をやってみるとどうなるか?
> path.resolve('src', 'index.js') '/Users/kotakanazawa/dev/webpack-jissen-nyumon/src/index.js'
第一引数には src 、第二引数には index.js を指定すると、プロジェクト直下にsrc/index.js
を設定した絶対パスが返ってくる。
これでなんとなくの動きはわかってくると思う。
path.resolve('src/js', 'index.js')
をやってみると…
> path.resolve('src/js', 'index.js') '/Users/kotakanazawa/dev/webpack-jissen-nyumon/src/js/index.js'
src/js/index.js
になって返ってきた。
path.resolve('src/js', 'public/index.js')
をやってみると…
> path.resolve('src/js', 'public/index.js') '/Users/kotakanazawa/dev/webpack-jissen-nyumon/src/js/public/index.js'
src/js/public/index.js
になって返ってきた。
つまり、path.resolve()
は、引数があればそれらを結合して絶対パスを返してくれる。
webpack の設定:出力先は絶対パスを指定する
webpack の設定において、output の path には絶対パスを指定しないとエラーが出てしまう。
output: { // 絶対パスを指定する path: path.resolve(__dirname, 'public/js') }
Macであれば、${__dirname}/dist
といった書き方でも問題はない。
output: { path: `${__dirname}/dist`, filename: 'main.js' },
しかし、OSによってはパスの書き方が/
じゃないことがあり、${__dirname}/dist
だと変になってしまって動かない可能性が出てくる。
だから、絶対パスを確実に設定するため、path.resolve()
を使っているというわけ。
path ライブラリの基本
こちらはおまけ。
「そもそも path ライブラリってなにをしてくれるもんなの?」という疑問があったので、他のメソッドも調べてみた。ざっと見るだけで「あ〜 path ライブラリってこんな感じのことをしてくれるやつなのね〜」と知ることができるかも。
path.dirname()
path.dirname()
は名前から想像できるとおり、ディレクトリパスを取得する。
ターミナルでREPLを起動して挙動を確かめてみる。
$ node # pathをrequireして使えるようにする > const path = require('path') #適当にパスを定義する > const path_name1 = '/foo/bar/baz' # dirnameメソッドを使う > path.dirname(path_name1) '/foo/bar' #もう一つ適当にパスを定義する > const path_name2 = '/foo/bar/baz/hoge/bbb' # dirnameメソッドを使う > path.dirname(path_name2) '/foo/bar/baz/hoge'
/foo/bar/baz
と定義したパスをpath.dirname()
で読み取ると、'/foo/bar'
が返ってくる。
/foo/bar/baz/hoge/bbb
と定義したパスをpath.dirname()
で読み取ると、'/foo/bar/baz/hoge'
が返ってくる。
path.dirname()
path.basename()
はファイル名を返す。
> const path_name1 = '/foo/bar/baz' > path.basename(path_name1) 'baz' > const path_name2 = '/foo/bar/baz/hoge/bbb' > path.basename(path_name2) 'bbb'
たとえば、/foo/bar/index.html
だったらindex.html
を返す。