フロントエンドをガッツリやるようになると避けられないのがwebpack
ということで、webpack
でレイアウト20ページ程度の静的サイトをつくる場合の方法をメモしておきます。
プロジェクトルートで
$ npm init -y (設定ファイルを生成)
$ npm install --save-dev webpack webpack-cli
--save-dev
オプションは、インストールするパッケージの情報をpackage.json
に記録するという意味です。
オプション
--save-dev
アプリ開発で利用するツールをインストールする場合に利用する--save
アプリそのものを実行する場合にインストールするwebpackのインストール
をインストールしたらpackage.json
にこのように記録されます。
{
"name": "e-learning-general",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
}
}
webpack
でもheader
やfooter
などを共通化して書き出すこともできるらしいのですが、どうも上手いやり方がわからなかったので、あきらめてpug
で組み立てて、公開するpublic
フォルダに書き出す方法にしました。
というわけで、ここでは一旦webpack
のことを忘れて、必要となるpug
とpug-cli
をインストールします。
$ npm install --save-dev pug pug-cli
次にプロジェクト直下に公開するpublic
フォルダとhtml
のlayoutを格納するsrc
フォルダを作成します。
$ mkdir public src
pug
ファイルを格納するlayout
フォルダをsrc
直下に作成します。
$ mkdir src/layout
ここまで、出来たらあとはpug
でゴリゴリ書いていけばいいのですが、pug
のIncludes
を使えばヘッダーやフッターなどを部品化できるので、僕の場合は、_common
フォルダの中に共通部品を入れ込んでいます。フォルダ構成はこんな感じ。
layout/_common
|- _partialsフォルダ ヘッダーとかフッターなどの共通ファイル
|- _baseof.pug 基盤となるpugファイル
/user
/money
次に基盤となる_baseof.pug
を作成します。
block pagedata
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")
link(href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet")
title #{pageTitle} | サンプル
body
include ./_partials/_header ← 共通部分
block main ← ここに各ページのコンテンツが入る
include ./_partials/_footer ← 共通部分
block pagejs ← 各ページのjs
ここまで、できたら後は共通の部分のpug
を作って、各ページを作るだけ。user画面を作成するとこんな感じ。まずbaseof.pug
ファイルを読み込んで、それから組み立ていく流れ、静的サイトのディレクトリのpath
変数を設定してあげると便利。
//- テンプレート読み込み
extend ../_common/_baseof
//-ページ独自の設定
append pagedata
- var pageTitle= "このサイトについて";
- var path = '../';
//- ページ独自のjs
append pagejs
script(src=`${path}main.js`)
//- ページのコンテンツ
block main ここにユーザーが表示されるよ
レイアウトをpug
で作成したらこれをpublic
フォルダに書き出すために、スクリプトを作成します。
場所はどこでもいいですが、とりあえずプロジェクト直下にsample.sh
を作成します。
$ touch sample.sh
sample.sh
にpug
をbuildするスクリプトを書きます。
#sample.sh
npx pug src/layout/user/*.pug --pretty --out public/terms
さて、ここまできたら試しにスクリプトを実行してみましょう。
% sh sample.sh
きちんとbuildされればpublic
フォルダにhtmlが書き出されていると思います。ここまでで、htmlは終わりです。
webpack-dev-server
を使えばファイルを更新すると即座に反映してくれるので、インストールしておきましょう。
$ npm install --save-dev webpack-dev-server
webpack-dev-server
を有効にするためにwebpack.config.js
を作成します。
$ touch webpack.config.js
webpack-dev-server
とエントリーポイントなどを含めてた基本の形はこんな感じ。
module.exports = {
entry: './src/index.js',
output: {
path: `${__dirname}/public`,
filename: 'main.js'
},
devServer: {
contentBase: `${__dirname}/public`,
},
};
webpack-dev-server
を簡単に起動できるようにpackage.json
にnpm scripts
編集します。
ついでにbuildコマンド
も追加しておきます。
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack --config webpack.config.js"
},
エントリーポイントとなるindex.js
をsrc
フォルダ直下に作成する。
$ touch src/index.js
エントリーポイント
とはバンドルをするときの開始するファイルのことです。
// index.js
console.log('ここはエントリーポイント')
ここまで、終わればwebpack-dev-server
を起動してみましょう。
まずは、buildして、main.js
を出力します。
$ npm run build
webpack-dev-server
を起動させる。
$ npm start
問題なく画面が表示されたらdeveloperツールでconsoleを確認してみましょう。
ここはエントリーポイントと表示されているはずです。
スタイルシートをバンドルするための、css-loader
,style-loader
,sass-loader
,とscss
をコンパイルするのに必要になるnode-sass
をインストールします。
$ npm install --save-dev webpack webpack-cli css-loader style-loader sass-loader node-sass
インストールが終わったら、webpack.config.js
のmodule-rulesパラメーター
にローダーを適用するtestファイルと適用するuseローダーを指定します。
ローダーは右から適用されます。ちょっと改行してるので、この場合は下から適用されます。まず、sass-loader
がnode-sass
を使ってsass
をcssにコンパイルして、css-loader
がそれをバンドルし、最後にjsファイルにcssを入れるのにstyle-loader
が適用されるとう流れです。
module: {
rules: [
{
test: /\.css|scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
],
},
],
}
試しに、style.scss
を以下のようにして。
body {
background-color: red;
}
このstyle.scss
をエントリーポイントのindex.js
にモジュールとしてimportします。
import './assets/scss/style.scss';
$ npm start
body
が赤になっていれば成功です。scss
を更新したらすぐさまに色が変わると思います。
$ npm install --save normalize.css
normalize.css
をインポート
import 'normalize.css'
normalize.css
はnpmが公式から公開されていますので、そのままインスールします。
buildするとmain.js
の中にnormalize.css
が追加されているのが確認できると思います。
$ npm run buiild
本番時はソースコードを圧縮したり、余計なconsole.log
を削除してbuildしたいかと思います。その時に利用するのがwebpack-merge
です。
プロジェクト直下に以下のファイルを作成しましょう。
$ touch webpack.base.js webpack.development.js webpack.production.js
webpack-merge
をインストールする。
$ npm install --save-dev webpack webpack-cli webpack-merge
まず、最初に共通の設定から行います。
// 共通設定: webpack.base.js
module.exports = {
entry: './src/index.js',
output: {
path: `${__dirname}/public`,
filename: 'main.js'
},
devServer: {
contentBase: `${__dirname}/public`,
},
module: {
rules: [
{
test: /\.css|scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
],
},
],
}
};
次にwebpack.development.js
の設定です。開発中ですのでsourcemapなどを確認できたほうがいいので、基本はこんな感じ。
const merge = require('webpack-merge');
const base = require('./webpack.base.js');
module.exports = merge(base, {
mode: 'development',
devtool: 'eval-source-map',
})
本番は圧縮の設定はwebpack
のmode
をproduction
にするだけ勝手によしなしにやってくれます。細かい設定が必要ならその都度、プラグインなどで設定します。以下は、console.logを出力しないようにterser-webpack-plugin
を使っています。
const merge = require('webpack-merge');
const base = require('./webpack.base.js');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = merge(base, {
mode: 'production',
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
compress: {drop_console: true}
}
})],
}
})
webpack-merge
を使って開発用と本番用設定を分割したので、今度はこの設定をpackage.json
に指定します。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open-page -config webpack.development.js",
"build": "webpack --config webpack.production.js && sh sample.sh"
},
これでnpm start
の時は開発用の設定で起動し、npm run build
の時は本番設定でbuildします。
終わり。