目的
キャンペーンのランディングページのような簡単なHTMLを作成したいです。Javascriptフレームワークのような大きなライブラリはいらないけど、TailwindCSS、TypeScriptは使いたいです。
TailwindCSS
多くのユーティリティクラスを提供してくれるCSSライブラリです。HTMLの見栄えをこうしたいと思ったときに素直にクラスを選択できるのが良いと思っています。ただしビルド環境が必要なるので始めるのには準備が必要です。この記事はまさにその準備に焦点をあてています。
TypeScript
せっかくビルド環境があるので、TypeScriptも導入します。ちいさなWebを書くのにもTypeScriptが無いとつらいです。
Webpack5
最新のWebpackとWebpackDevServerを利用します。ぐぐっても昔の記事しかでなくて苦労します。この記事も1年くらいの賞味期限でしょうか。
コード
必要なライブラリをインストール
yarn add --dev autoprefixer css-loader postcss postcss-loader style-loader tailwindcss ts-loader typescript webpack webpack-cli webpack-dev-server
ディレクトリ構成
node-modules
public
|-index.html
|-js
|-main.js(wabpackにより生成)
src
|-index.ts
|-style.css
package.json
postcss.config.js
tailwind.config.js
tsconfig.json
webpack.config.js
yarn.lock
各種設定ファイル
package.json
{
"devDependencies": {
"@webpack-cli/generators": "^2.3.0",
"autoprefixer": "^10.3.5",
"css-loader": "^6.3.0",
"postcss": "^8.3.7",
"postcss-loader": "^6.1.1",
"style-loader": "^3.3.0",
"tailwindcss": "^2.2.15",
"ts-loader": "^9.2.6",
"typescript": "^4.4.3",
"webpack": "^5.53.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.2.1"
},
"scripts": {
"dev": "webpack serve",
"build": "webpack"
}
}
webpack.config.js
const webpack = require('webpack');
module.exports = {
// モード値を production に設定すると最適化された状態で、
// development に設定するとソースマップ有効でJSファイルが出力される
mode: 'development',
target: 'web',
// メインとなるJavaScriptファイル(エントリーポイント)
entry: './src/index.ts',
output: {
// バンドルしてmain.jsとして出力
filename: 'main.js',
path: `${__dirname}/public/js`,
// webpack-dev-serverに書き換わるファイルを教える
publicPath: '/js/'
},
module: {
rules: [
{
// 拡張子 .ts の場合
test: /\.ts$/,
// TypeScript をコンパイルする
use: 'ts-loader',
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader', 'postcss-loader'],
},
],
},
// import 文で .ts ファイルを解決するため
// これを定義しないと import 文で拡張子を書く必要が生まれる。
// フロントエンドの開発では拡張子を省略することが多いので、
// 記載したほうがトラブルに巻き込まれにくい。
resolve: {
// 拡張子を配列で指定
extensions: [
'.ts', '.js',
],
fallback: {
fs: false,
path: false,
http: false,
https: false,
zlib: false,
util: false,
stream: false,
assert: false,
process: false,
events: false,
querystring: false,
url: false
}
},
devServer: {
static: {
directory: `${__dirname}/public`
},
// 変更時リロードする
hot: true,
// 監視するファイルを指定する
watchFiles: ['src/**/*.ts', 'public/**/*'],
},
// 変更時にコンパイルする指定
watch: true,
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
]
};
tsconfig.json
{
"include": ["src/**/*"],
"compilerOptions": {
"sourceMap": false,
"target": "es5",
"module": "commonjs",
"lib": ["es2017", "dom"],
"moduleResolution": "node",
"esModuleInterop": true
}
}
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
ソース
index.ts
import "./style.css"
var callback = function(){
console.log("ready");
};
if (
document.readyState === "complete" || document.readyState !== "loading"
) {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
style.css
@tailwind base;
@tailwind utilities;
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap');
/* フォント */
html, body {
font-family: 'Noto Sans CJK JP', sans-serif;
}
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
<script src="./js/main.js"></script>
</head>
<body>
<p class="bg-red-300">あいうえお</p>
</body>
</html>