【メモ】webpack設定ファイルの書き方
24709 ワード
試行錯誤しながらwebpackが動くところまで実装したので、備忘録として残して。
実装のゴール
resources配下のjs,scssファイルを、ファイル構成を保ったままpublic配下のjs,cssファイルに出力したい。
例えば、resources/js/post/index.js
はpublic/js/post/index.js
に出力する。
ファイル構成
ブラウザ側で読み込まれるのは、public配下のjs,cssファイル。
そのためresources配下のjs,scssファイルをコンパイル・圧縮したものをpublic配下のjs,cssファイルへ出力している。
sample_app
├─ public
│ ├─ js
│ │ └─ post
│ │ ├─ index.js
│ │ └─ show.js
│ └─ css
│ └─ post
│ ├─ index.css
│ └─ show.css
│
├─ resources
│ ├─ js
│ │ ├─ _share
│ │ │ └─ utility.js
│ │ │
│ │ └─ post
│ │ ├─ index.js
│ │ └─ show.js
│ └─ scss
│ └─ post
│ ├─ index.scss
│ └─ show.scss
│
└─ webpack.config.js
各ファイルの記述内容
例としてresources/js/post/index.js
にて下記ファイルを読み込む
resources/scss/post/index.scss
resources/js/_share/utility.js
resources/js/post/index.js
// scssのimport
import '@scss/post/index.scss';
// jsのimport
import * as $util from '@js/_share/utility';
$util.introduction();
const msg = 'This is post/index';
console.log(msg);
resources/scss/post/index.scss
h1 {
font-size: 20px;
color: skyblue;
}
resources/js/_share/utility.js
export const introduction = () => {
const msg = 'This is utility file';
console.log(msg);
};
本題のwebpack.config.js
webpack.config.js
// Node.jsに組み込まれているモジュール。出力先などの指定を手軽に絶対パスで記述できる。
const path = require('path');
// scssのcompileに使用。個別のcssファイルへの出力を可能にする。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// eslintを導入するならこれ
// eslint-loaderは非推奨になる & failOnErrorが機能しないので、こちらを使用
// ref:https://github.com/webpack-contrib/eslint-loader/issues/334
const EslintWebpackPlugin = require('eslint-webpack-plugin');
// 複数entryを実装するのに便利なパッケージ
const glob = require('glob');
const srcDir = './resources/js';
const entries = {};
// globを使用して任意のjsファイルを取得し、複数entry用のobjectを生成
glob.sync('**/*.js', {
// compileから除外するパターンを指定(importされる前提の共通ファイルなど)
// 複数パターンを指定する場合は配列で記述
ignore: '**/_*/*.js',
// ルートとなるディレクトリを指定
// 下記jsFileNameに入るのはこのディレクトリ以降のパスになる
cwd: srcDir,
// cwdの指定により、./resources/js/post/index.jsの場合、 jsFileNameにはpost/index.jsとが入る
}).forEach(jsFileName => {
// outputの[name]に対応するため、entriesのkeyからは.js拡張子を除く
const fileNameExceptExt = jsFileName.replace(/\.js$/, '');
// path.resolveにより、絶対パスが入る
// { 'post/index': 'sample_app/resources/js/post/index.js', ... } のようになる
entries[fileNameExceptExt] = path.resolve(srcDir, jsFileName);
});
module.exports = {
// modeによって処理を分岐したければ process.env.NODE_ENV にmodeが格納されているので、それを使う
mode: 'development',
// developer toolで見れるソースマップの種類のオプション
devtool: 'eval-cheap-module-source-map',
// 上で複数entry用にglobを使用して作ったやつ
entry: entries,
output: {
// 出力先はsample_app/publicディレクトリ
path: path.resolve(__dirname, 'public'),
// [name]にはentriesのkeyに指定したパスが入る
// [name]がpost/indexなら、sample_app/public/post/index.jsに出力される
filename: 'js/[name].js',
},
resolve: {
alias: {
// import時の起点となるディレクトリを指定できる。
// これにより、resources/js/post/index.js では
// import * as $form from '../_share/form.js' と書かずに
// import * as $form from '@js/_share/form' と書ける
'@scss': path.resolve(__dirname, 'resources/scss'),
'@js': path.resolve(__dirname, 'resources/js'),
},
},
module: {
// loaderを使用する際のルールを記述
rules: [
{
// include配下のtestに合致するファイルだけ、useで指定したloaderを使用
test: /\.js$/,
// excludeで指定も可能
include: path.resolve(__dirname, 'resources/js'),
// useに記述したloaderは、記述と逆順に実行されるので複数指定時は注意
use: ['babel-loader'],
},
{
test: /\.scss$/,
include: path.resolve(__dirname, 'resources/scss'),
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
// [name]にはentryで指定したkeyが入る
// post/index.jsで読み込んでいるscssはpublic/css/post/index.cssに出力される
filename: 'css/[name].css',
}),
new EslintWebpackPlugin({
fix: false,
// eslintエラー時、compileを中断するか
failOnError: false,
}),
],
};
package.jsonはこんな感じ
package.json
"scripts": {
"watch": "webpack --watch",
"dev": "webpack",
"prod": "webpack --mode production --no-devtool"
},
"devDependencies": {
"@babel/core": "^7.13.10",
"@babel/preset-env": "^7.13.12",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.0",
"mini-css-extract-plugin": "^1.4.0",
"sass": "^1.32.8",
"sass-loader": "^11.0.1",
"eslint": "7.7.0",
"eslint-config-airbnb": "18.2.0",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-jsx-a11y": "6.3.1",
"eslint-plugin-react": "7.20.6",
"eslint-webpack-plugin": "^3.1.1",
"glob": "^7.2.0",
"webpack": "^5.30.0",
"webpack-cli": "^4.6.0",
"webpack-merge": "^5.7.3"
}
npm run prod
を実行してみる
コンパイル・圧縮された記述がそれぞれjs,cssファイルに出力される
public/js/post/index.js
(()=>{"use strict";console.log("This is post/index"),console.log("This is utility file")})();
public/css/post/index.css
h1{font-size:20px;color:skyblue}
参考書籍・サイト
- webpack 実践入門 第2版
- 速習 webpack 第2版
- glob:https://qiita.com/masato_makino/items/7130bbe408ca929e7f0d
- entryに階層構造を指定する:http://webdesign-dackel.com/2015/09/10/webpack-multiple-output/
- resolve.alias:https://qiita.com/kazuooooo/items/b0ca9bd74a093824403e
- sourcemap:https://webpack.js.org/configuration/devtool/
Author And Source
この問題について(【メモ】webpack設定ファイルの書き方), 我々は、より多くの情報をここで見つけました https://zenn.dev/syamozipc/articles/webpack_note著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol