フロントエンドをガッツリやるようになると避けられないのが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します。
終わり。