#webpack+React+Sassの環境構築
##package.jsonの準備
{
"name": "portforio",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"build": "webpack --mode=production",
"build:dev": "webpack --mode=development",
"watch": "webpack-dev-server --mode=development"
},
"author": "",
"license": "ISC",
"dependencies": {
"node-sass": "^4.12.0",
"nodemon": "^1.19.0",
"jquery": "",
"react": "",
"react-dom": ""
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel": "",
"babel-loader": "",
"browserify": "^16.2.3",
"css-loader": "^3.0.0",
"mini-css-extract-plugin": "^0.7.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"vinyl-source-stream": "^2.0.0",
"webpack": "",
"webpack-cli": "^3.3.4",
"webpack-dev-server": "^3.7.1",
"webpack-stream": ""
}
}
試行錯誤しながら作っていたので、不要なものもあるかもしれません。
webpackを利用するときは、mode
を指定しないと怒られるので、実行する際に
--mode=production
や--mode=development
で指定をします。
##webpack.config.jsの記述
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports =(env, argv) => ({
entry: path.join(__dirname, 'src/app.js'),
output: {
path: path.join(__dirname, 'dist/js'),
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
watchContentBase: true,
},
module: {
rules: [
//babel-loader
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react', '@babel/preset-env']
}
}
],
exclude: /node_modules/,
},
//css/sass-loader
{
test: /\.scss$/,
use: [
'style-loader',
/*
MiniCssExtractPlugin.loader,
*/
{
loader: 'css-loader',
options: {
url: false
}
},
'sass-loader'
],
},
]
},
/*
plugins: [
new MiniCssExtractPlugin({
filename: 'style.css'
}),
],
*/
resolve: {
modules: [path.join(__dirname, 'src'), 'node_modules'],
extensions: ['.js', '.jsx']
}
});
###ファイル管理
module.exports =(env, argv) => ({
entry: path.join(__dirname, 'src/app.js'),
output: {
path: path.join(__dirname, 'dist/js'),
filename: 'bundle.js'
}
(env, argv) =>
と記述することで、mode
を取得することができます。
(ここの仕組みは、まだイマイチわかってないです。)
entry:
で入力元のファイルを指定します。
path.join()
でパスを結合、第1引数に__dirname
でファイルのあるディレクトリまでのパスを取得、第2引数に以降のパスを記述します。
似てる関数にpath.resolve()
があります。
join
は単純に / でパス名をくっ付けるのに対して、resolve
は絶対パスに変換して処理をします。
例えば、
path.join('/a', 'b'); //return /a/b
path.resolve('/a', 'b'); //return /a/b
path.join('/a', '/b'); //return /a/b
path.resolve('/a', '/b'); return /b
resolve
の場合、第2引数以降に絶対パスを入れると、パスが上書きされるので注意です。
output:
で出力先の指定、filename:
出力ファイル名を指定します。
###ファイル監視機能
devServer: {
contentBase: path.join(__dirname, 'dist'),
watchContentBase: true,
}
webpack-dev-server
は、ファイルの変更を監視出来るモジュールです。
contentBase
はoutput
のパスと同じにします。
watchContentBase
はファイル監視をするかです。デフォルト値はfalseです。
###JSファイルのトランスパイル
module: {
rules: [
//babel-loader
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react', '@babel/preset-env']
}
}
],
exclude: /node_modules/,
},
test:
で対象のファイルを指定します。
use:
で使用するローダーを指定します。
loader:
今回はbabel-loader
を使用します。ES6をES5へ変換するローダーです。
options:
presets:
プリセットを使用します。今回はreact
(react関連の記述を変換)とenv
(ES5へ変換)を使用します。
exclude:
で除外するディレクトリを指定できます。node-modulesは忘れずに除外します。
###sassのバンドル
//css/sass-loader
{
test: /\.scss$/,
use: [
'style-loader',
/*
MiniCssExtractPlugin.loader,
*/
{
loader: 'css-loader',
options: {
url: false
}
},
'sass-loader'
],
},
モジュールの使用順は下から上になるため、
sass-loader
(sassをcssへ変換)
css-loader
(cssをJSへバンドル)
style-loader
(htmlへcssを適用させる)
の順で使用されます。
この場合、CSSはbundle.js内にバンドルされます。
CSSファイルを別に取り出したい場合は、mini-css-extract-plugin
を使用します。
その場合、plugins:
にて出力ファイル名を指定します。
plugins: [
new MiniCssExtractPlugin({
filename: 'style.css'
}),
],