お知らせ

現在サイトのリニューアル作業中のため、表示が崩れているページが存在することがあります。
2024/01/22 16:08 Node.js::webpack

バンドル内容をHTMLに注入するの続き

Webpackには次の2つの開発モードがあるdevelopment, production

開発モードの設定

modeプロパティに'development', 'production', 'none'を設定する
これを設定するとprocess.env.NODE_ENVで値を取得できる様になる
それぞれの違いは mode-development にあるが、試してみた感じproductionは出力が最適化され、console系が消えるものと思われる
noneを設定するとminifyとかがされてない生のコードが出てくる

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
+  mode: 'development', 
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
  plugins: [
     new HtmlWebpackPlugin({
       title: 'Webpack',
       template: 'index.html'
     })
  ]
};
2024/01/22 16:07 Node.js::webpack

基本的なバンドルの続き

複数JSの個別バンドル

src/print.jsを追加して、関係するファイルも幾らか変更する

src/print.js

export const printMe = () => {
  console.log('I get called from print.js!');
}

src/index.js

import _ from 'lodash';
-import './index.css';
-import Icon from './icon.png';
+import { printMe } from './print';

function component() {
+  window.onload = printMe;
  
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');
-    div.classList.add('hello');
-
-    const img = document.createElement('img');
-    img.src = Icon;
-    div.appendChild(img);
  
  return div;
}

document.body.appendChild(component());

webpack.config.js

const path = require('path');

module.exports = {
-   entry: './src/index.js',
+  entry: {
+    index: './src/index.js',
+    print: './src/print.js',
+  },
   output: {
-    filename: 'bundle.js',
+    filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
-   module: {
-    rules: [
-      {
-        test: /\.css$/i,
-        use: ['style-loader', 'css-loader'],
-      },
-      {
-        test: /\.(png|svg|jpg|jpeg|gif)$/i,
-        type: 'asset/resource',
-      },
-    ],
-  },
};

この状態でバンドルするとindex.bundle.jsとprint.bundle.jsが生えてくるが、前回バンドルした残骸が残ってしまう

バンドル時に出力フォルダをクリーンアップする

webpack.config.js

const path = require('path');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
+     clean: true,
   },
};

バンドルした内容をHTMLに反映する

この時点のindex.htmlはdist/bundle.jsを参照しているので、今回の結果が反映されていません
これが反映されるように修正します

npm i -D html-webpack-plugin

webpack.config.js

const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
+   plugins: [
+      new HtmlWebpackPlugin({
+        title: 'Webpack',
+      })
+   ]
};

これで設定したバンドルファイルがindex.htmlに反映されるようになりました

HTMLのテンプレートを用意する

しかし先程の設定では出力されるHTMLにどうしても限界があります
HtmlWebpackPlugin のリファレンスを見ることである程度なんとかなりますが、テンプレートに差し込むこともできます

次のように変えることでテンプレートHTMLにバンドルを差し込むことが確認できます

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
   plugins: [
      new HtmlWebpackPlugin({
        title: 'Webpack',
+        template: 'index.html'
      })
   ]
};

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
-    <title>Getting Started</title>
  </head>
  <body>
    <script src="dist/bundle.js"></script>
+    <h1>Webpack</h1>
  </body>
</html>
2024/01/22 16:05 Node.js::webpack

webpackとはなんぞやというところで軽く調べてみたメモ
ほぼ公式のチュートリアル
やれることが非常に多いので公式ドキュメントを読むのが一番良い

確認環境

Env ver
webpack 5.41.0
webpack-cli 4.7.2

webpackとは

JavaScriptのモジュールバンドラで次の機能を持つ

  • JSやCSS、画像ファイルやデータファイルなどの各種静的ファイルを出力フォルダにまとめて吐く
  • ブラウザのキャッシュの影響を回避するために、出力ファイル名を毎回変える
  • index.htmlに必要なファイル参照を自動で埋め込む
  • 出力フォルダのクリーンアップ
  • HMR用のサーバーを起動する
  • Sourcemapを吐く
  • 次の構成を利用したビルドパイプラインを構成する
    • TypeScript, CoffeeScript, Babel and JSX
  • その他色々
    • 豊富なAPIと設定が存在するのでいろんな事ができる!

webpackを試してみる

取り敢えずこんな感じのプロジェクトを作る

  1. npm init
  2. npm i -D webpack webpack-cli lodash
|- package.json
|- /dist
|- index.html
|- /src
  |- index.js

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Getting Started</title>
  </head>
  <body>
    <script src="dist/main.js"></script>
  </body>
</html>

src/index.js

import _ from 'lodash';

function component() {
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return div;
}

document.body.appendChild(component());

npx webpackを流してバンドルしてあげるとlodashが組み込まれたJSが吐き出される

CSSのバンドル

  1. npm i -D style-loader css-loaderを流して
  2. webpack.config.jssrc/index.cssを作成
  3. src/index.jsもちょっと書き換えます

webpack.config.js

const path = require('path');

module.exports = {
   entry: './src/index.js',
   output: {
    filename: 'bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
   module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

src/index.css

.hello {
  color: red;
}

src/index.js

import _ from 'lodash';
+import './index.css';

function component() {
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');
+  div.classList.add('hello');

  return div;
}

document.body.appendChild(component());

この状態でnpx webpackを流すとCSSのバンドルが確認出来る

assetsのバンドル

webpack.config.js

const path = require('path');

module.exports = {
   entry: './src/index.js',
   output: {
    filename: 'bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
   module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
+      {
+        test: /\.(png|svg|jpg|jpeg|gif)$/i,
+        type: 'asset/resource',
+      },
    ],
  },
};

src/index.js

import _ from 'lodash';
import './index.css';
+import Icon from './icon.png';

function component() {
  const div = document.createElement('div');
  div.innerHTML = _.join(['Hello', 'webpack'], ' ');
  div.classList.add('hello');

+  const img = document.createElement('img');
+  img.src = Icon;
+  div.appendChild(img);

  return div;
}

document.body.appendChild(component());

フォントファイルやデータファイルのバンドル

基本は同じなので公式のガイドを見るとわかりやすい

2024/01/22 16:03 技術::Cookieジャンル::調査

各サービスの振る舞いが少し気になったので適当にサッと軽く見たメモです
ある程度モダンそうなところを適当に選んだので特に観点とかはないです

確認環境

  • Google Chrome 91.0.4472.124(Official Build)
  • Cookie offはファーストパーティCookieをブロックして確認

超簡単なまとめ

サービス Cookie off ログイン JS off
Qiita エラー 一部描画が欠損
Twitter 何も起きない エラー
GitHub エラー 一部描画が欠損
Google エラー 一部描画が欠損, 場合によってエラー
Youtube 未確認 読込中になる
mercari 未確認 読込中になる
DMM 何も起きない 一部描画が欠損, 警告が出る, 一部機能不全
DLSite ログアウトページに飛ぶ 一部描画が欠損, 場合によって例外が出る
Skeb 白紙ページ 白紙ページ
Tayori エラー 一部描画が欠損, 一部機能不全
SoundCloud 何も起きない エラー

Qiita

ログインしようとするとエラーになります

JS off

ページの一部が欠損しますが、特にエラーは出ない模様

Twitter

ログインしようとするとログインページでループします

JS off

エラーが出ます

GitHub

めちゃくちゃシンプルなエラーが出ます

JS off

ページの一部が欠損し、場所によってはエラーになる模様

Google

検索ページとログインページで確認

ログインしようとするとエラーになります

JS off

検索はできましたが、ログインしようとするとエラーになります

Youtube

Googleと同じなのでパス

JS off

読込中の状態で止まります

mercari

未確認

JS off

読込中の状態で止まります

DMM

Twitter同様にログインページでループしました

JS off

ページ上部に通知が生えてきます
ついでにページ表示が崩れたり、一部のページ遷移が機能しなくなりました

DLSite

ログインしようとするとログアウト処理に飛びました

カートにアイテムを入れても入りません

JS off

ページの一部が欠損するので成人向けサイトでも超健全に!

カートからアイテムを消すと謎のエラーが出ますが、カートからは一応消えます

skeb

白紙ページになります
Consoleに次のエラーが出るので想定外ということでしょう

DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.

JS off

白紙ページになりました

Tayori

エラーになります

JS off

  • トップページの一部が欠損
  • トップページからヘッダーのリンクを叩くと表示されるコンテンツが白紙に
  • ユーザーのFAQページは検索が動作不能

SoundCloud

ログインできずにループします

JS off

エラーになります

nginxの設定ファイルを更新したのに読み込んでくれないときの対処法

  • 次のようにnginxのリロードや再起動をしても通じないとき
    • nginx -s reload
    • nginx -s stop -> nginx
  • 次のコマンドを流すとプロセスが綺麗に死んでくれて再読込できることがある
    • sudo kill -HUP $(cat /var/run/nginx.pid)