Webpack 5 設定の基礎を下記動画を参考にして学びました。
Windows環境のせいなのか、環境変数の扱いについてはちょっと悩み、動画とは違うやり方になっています。
設定なしで実行可能
webpack は特に設定しなくとも複数の JavaScript をまとめてくれます。いわゆるゼロコンフィグというやつですね。
- Windows の Git Bash にて次のコマンドを実行します。
$ mkdir webpack-setup
$ cd webpack-setup
$ npm init -y
$ touch index.js
$ touch index.html
これで、VSCodeが開きます。
- index.html で ! を入力して2行編集、1行追加。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpackのテスト</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
- index.js を編集。
console.log('index.jsから実行');
これをブラウザで表示し、コンソールを見れば上記が表示されます。
- index.js を編集。
import { greeting } from './greeting';
import { present } from './present';
console.log('index.jsから実行');
console.log(greeting);
console.log(present);
- greeting.js を追加。
export const greeting = 'どうもこんばんは。ピータンです。';
- present.js を追加。
export const present= '東京都いなか市在住の56歳です。';
これは次のエラーとなることがブラウザで確認できます。
Uncaught SyntaxError: Cannot use import statement outside a module
- webpack 及び webpack cliをインストールします。
$ npm i -D webpack webpack-cli
- 試しに以下のコマンドを打つと色々エラーや警告が出ます。
$ npx webpack
:
ERROR in main
Module not found: Error: Can't resolve './src' in 'C:\\
:
- ここで、src フォルダを作って、3つの jsファイルを移動します。 もう一回以下のコマンドを実行すると、警告は出るがエラーは消えていて dist フォルダができていて、main.js ができていることがわかります。
$ npx webpack
- dist\main.js をフォーマット(Shift + Alt + F)すると次の内容です。
(() => {
'use strict';
console.log('index.jsから実行'),
console.log('どうもこんばんは。ピータンです。'),
console.log('東京都いなか市在住の56歳です。');
})();
- index.html も dist フォルダに移動し、次のように変更します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpackのテスト</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
- dist\index.html をブラウザで開きコンソールを見ると、期待通り動いていることがわかります。 ここまでsrcフォルダを作っただけで、特に何も設定していないことに注目です。
package.jsonでのスクリプトの設定とwebpackのスマートなバンドル
ここでは、webpack.config.js を使って npm run build でWebpackを使用するようにすることと、webpack が単にモジュールを寄せ集めているだけでないことを示します。
- src\introduce.js を追加します。
import { greeting } from './greeting';
import { present } from './present';
function introduce() {
console.log(greeting);
console.log(present);
}
export default introduce;
- src\index.js を次のように変更します。
import introduce from './introduce';
console.log('index.jsから実行');
introduce();
- package.json に build スクリプトを追加します。
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1",
"build": "webpack"
},
- 次のコマンドを実行します。
$ npm run build
- ブラウザのコンソールを確認すると先程と結果は同じです。しかし、驚くべきことに dist\main.js の内容も先程と同じです。
(() => {
'use strict';
console.log('index.jsから実行'),
console.log('どうもこんばんは。ピータンです。'),
console.log('東京都いなか市在住の56歳です。');
})();
Babelによるトランスパイリング
ここでは古いブラウザが解釈できる JavaScript への変換をおこないます。@babel/preset-env は最新の JavaScript を余計な手間を使うことなくどのブラウザで使用可能にします。
- src\index.js を変更します。
import introduce from './introduce';
console.log('index.jsから実行');
introduce();
const info = { age: 56, sports: 'VRボクシング' };
const newInfo = { ...info, address: '東京都いなか市' };
console.table(newInfo);
- npm run build を実行し dist\main.js をフォーマットして確認すると次の状況です。
(() => {
'use strict';
console.log('index.jsから実行'),
console.log('どうもこんばんは。ピータンです。'),
console.log('東京都いなか市在住の56歳です。');
console.table({ age: 56, sports: 'VRボクシング', address: '東京都いなか市' });
})();
なおブラウザのコンソールログへの実行結果は次のとおりです。
- 次のコマンドで Babel 等をインストールします。
$ npm i @babel/core @babel/preset-env babel-loader
- webpack.config.js ファイルをルートフォルダに作成します。
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\\.js$/,
exclude: /node_modules/,
use: {
// 追加設定は .babelrc
loader: 'babel-loader',
},
},
],
},
};
- .babelrc ファイルをルートフォルダに作成します。
{
"presets":["@babel/preset-env"]
}
- ここで改めて、npm run build を実行し dist\main.js をフォーマットして確認すると次のように、古いブラウザでも動作するコードになっています。
(() => {
'use strict';
function e(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r &&
(o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})),
t.push.apply(t, o);
}
return t;
}
function r(r) {
for (var o = 1; o < arguments.length; o++) {
var n = null != arguments[o] ? arguments[o] : {};
o % 2
? e(Object(n), !0).forEach(function (e) {
t(r, e, n[e]);
})
: Object.getOwnPropertyDescriptors
? Object.defineProperties(r, Object.getOwnPropertyDescriptors(n))
: e(Object(n)).forEach(function (e) {
Object.defineProperty(r, e, Object.getOwnPropertyDescriptor(n, e));
});
}
return r;
}
function t(e, r, t) {
return (
r in e
? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0,
})
: (e[r] = t),
e
);
}
console.log('index.jsから実行'),
console.log('どうもこんばんは。ピータンです。'),
console.log('東京都いなか市在住の56歳です。');
var o = r(
r({}, { age: 56, sports: 'VRボクシング' }),
{},
{ address: '東京都いなか市' }
);
console.table(o);
})();
- webpack.confi.gjs で mode: ‘production‘というのを設定することによって、以下の警告が消えました。設定しなくても設定したのと同じ動作はしていました。
モード
- ここで、mode: ‘development’ にするとフォーマット後の dist\main.js が52行から116行と増大します。
ソースマップ
- ブラウザの DevTools のコンソールで行番号をクリックすると、 dist フォルダにあるトランスパイルされたコードが表示されます。
- これをトランスパイルする前のコードで表示できるとデバッグが楽になります。これをおこなうには、以下の1行を webpackconfig.js に追加します。
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\\.js$/,
exclude: /node_modules/,
use: {
// 追加設定は .babelrc
loader: 'babel-loader',
},
},
],
}, // カンマ追加する
devtool: 'source-map', // ★ここ
};
watch モード
- package.json の build スクリプトに —watch を追加して、npm run build を実行した場合、ファイルを監視し続けて、変更があると、dist フォルダの変換結果をリアルタイムに更新してくれます。
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1",
"build": "webpack --watch"
},
dev-server
- VSCode の拡張機能に Live Server というのがあり、それを使うのもよいのですが、Webpack には、ライブリロードにより開発を迅速化するための webpack-dev-server (通称:dev-server)というものがあります。
- これは開発専用であり、次でインストールします。
$ npm i -D webpack-dev-server
- webpackconfig.js に以下を追加します。
devServer: {
contentBase: './dist',
},
- package.json に start スクリプトを追加します。
"scripts": {
"start": "webpack serve",
"test": "echo \\"Error: no test specified\\" && exit 1",
"build": "webpack --watch"
},
- これで npm start を実行すると dev-server が起動します。
出力先の変更
- 現在は、バンドルされたファイルが dist\main.js に出力されていますが、これを変更したい場合は webpack.config.js を次のようにします。
const path = require('path');
module.exports = {
:
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public')
},
:
devServer: {
contentBase: './public',
},
};
- この例では出力先を public/bundle.js に変更しています。
modeの切り替え
現在、webpackconfig.js に mode: ‘development’, などと設定されていますが、デバッグ中と、リリース時で、いちいちここを手で書き換えるのは不便です。そのようにしない方法を説明します。
- package.json を次のように書き換えます。
"scripts": {
"start": "webpack serve",
"test": "echo \\"Error: no test specified\\" && exit 1",
"build": "webpack --watch"
},
↓
"scripts": {
"start": "webpack serve",
"test": "echo \\"Error: no test specified\\" && exit 1",
"build": "set NODE_ENV=production&&giwebpack",
"build-dev": "webpack --watch"
},
- webpackconfig.js を次に変更します。
module.exports = {
mode: 'development',
↓
const mode =
process.env.NODE_ENV === 'production' ? 'production' : 'development';
module.exports = {
mode: mode,
出力先の変更はしていないものをGitHubに格納しました。
- Post Tagswebpack