LoginSignup
5
2

More than 3 years have passed since last update.

webpack+React+Sassの環境構築

Posted at

webpack+React+Sassの環境構築

package.jsonの準備

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の記述

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']
    }
});

ファイル管理

webpack.config.js
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:出力ファイル名を指定します。

ファイル監視機能

webpack.config.js
devServer: {
        contentBase: path.join(__dirname, 'dist'),
        watchContentBase: true,
    }

webpack-dev-serverは、ファイルの変更を監視出来るモジュールです。
contentBaseoutputのパスと同じにします。
watchContentBaseはファイル監視をするかです。デフォルト値はfalseです。

JSファイルのトランスパイル

webpack.config.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のバンドル

webpack.config.js
//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:にて出力ファイル名を指定します。

webpack.config.json
plugins: [
            new MiniCssExtractPlugin({
            filename: 'style.css'
        }),
    ],
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2