jsdelivr無料CDNを利用してスクリプトで自動アップロードとローカル画像パスの置換を実現する方法
- 1344単語
- 7分
- 21 Jul, 2024
生産環境では、画像をCDN(コンテンツ配信ネットワーク)に保存することで、読み込み速度を向上させ、ユーザー体験を向上させることができます。最近、次のような要件に直面しました。プロジェクトでローカル画像を参照する場合、/images/xxx.{jpg,jpeg,png,gif}
などを使用してローカル開発を容易にし、開発が完了したら、images
ディレクトリのすべての画像を圧縮して /project/resources/images
に移動(resourcesはgitプロジェクト)し、gitを介して自動的にGitHubにアップロードし、ローカルプロジェクトで参照されている画像パスを見つけ、CDNパスに変更します。このプロセスを理解した上で、スクリプトを使用してこのプロセスを自動化できます。まず、jsdelivrがCDNをどのように実現するかを理解しましょう。
jsdelivr CDN と GitHub の関係
jsdelivrは、無料で信頼性の高いコンテンツ配信ネットワーク(CDN)サービスで、開発者が静的リソースをGitHubリポジトリに保存し、jsdelivrを介してグローバルに加速アクセスを行うことを許可します。具体的には、jsdelivrはCDNアドレスを提供し、GitHubリポジトリに保存されているリソースを加速することができ、これによりこれらのリソースがグローバルに迅速に読み込まれるようになります。
GitHubプロジェクトとjsdelivrを関連付ける方法
-
リソースをGitHubリポジトリにアップロードする
まず、開発者は静的リソース(画像、JavaScriptファイル、CSSファイルなど)をGitHubリポジトリの特定のディレクトリにアップロードする必要があります。例えば、my-project
という名前のGitHubリポジトリがあり、その中に画像を保存するimages
フォルダがあるとします。 -
jsdelivr CDNを使用してアクセスする
一旦リソースがGitHubリポジトリにアップロードされると、jsdelivrが提供するURLを使用してこれらのリソースにアクセスできます。jsdelivrはGitHubプロジェクトに関連付けられたCDNアドレスを提供し、そのアドレスは以下の形式に従います:1https://cdn.jsdelivr.net/gh/[GitHubユーザー名]/[リポジトリ名]@[タグまたはブランチ]/[ファイルパス][GitHubユーザー名]
:あなたのGitHubユーザー名。[リポジトリ名]
:リソースをアップロードしたGitHubリポジトリ名。[タグまたはブランチ]
:使用するGitHubのタグまたはブランチ(例:main
やv1.0
)。[ファイルパス]
:リポジトリ内のリソースのパス。
例:
あなたのGitHubユーザー名が
johnsmith
、リポジトリ名がmy-project
、main
ブランチにimages
フォルダがあり、その中にlogo.png
という画像があるとします。この画像にアクセスするために、次のjsdelivr CDN URLを使用できます:1https://cdn.jsdelivr.net/gh/johnsmith/my-project@main/images/logo.pngウェブページでこのURLを使用して画像を参照すると、jsdelivrがグローバルのサーバーキャッシュからこの画像を加速読み込みし、読み込み速度を向上させます。
-
自動同期更新
GitHubリポジトリのリソースを更新すると、jsdelivrは自動的にGitHubから最新のリソースを取得し、CDN上のリソースを最新の状態に保ちます。つまり、GitHubリポジトリに新しいバージョンのリソースをアップロードするだけで、jsdelivrのURLが自動的に更新され、最新のファイルを提供するようになります。
このようにして、開発者はjsdelivr CDNのグローバル分散ネットワークを利用して、GitHubリポジトリに保存された静的リソースの読み込み速度を向上させ、ユーザー体験を向上させることができます。
実現ステップ
1. 依存関係のインストール
1pnpm add sharp fs-extra globby simple-git replace-in-file;
2. 画像の圧縮と移動
まず、sharp
ライブラリを使用して画像を圧縮し、フォルダ構造を保持しつつ画像をターゲットディレクトリに移動します。以下は実装コードです:
1import { promises as fs } from "fs";2import path from "path";3import sharp from "sharp";4import fse from "fs-extra";5import { globby } from "globby";6
7const imagesDir = "/project/myproject/public/images";8const targetDir = "/project/resources/images";9
10async function compressAndCopyImages(srcDir, destDir) {11 try {12 const sourDir = `${srcDir}/**/*.{jpg,jpeg,png,gif}`;13 await fse.ensureDir(destDir);14 const entries = await globby([sourDir], { onlyFiles: false });15
16 for (const entry of entries) {17 const relativePath = path.relative(srcDir, entry);18 const destPath = path.join(destDir, relativePath);19
20 if ((await fs.stat(entry)).isDirectory()) {21 await fse.ensureDir(destPath);22 } else {23 const metadata = await sharp(entry).metadata();24
25 let options = {};26 let formatOptions = {};27
28 switch (metadata.format) {29 case "gif":30 options = { animated: true, limitInputPixels: false };31 formatOptions = { colours: 128 };32 break;33 default:34 formatOptions = { quality: 75 };35 }36
37 if (metadata.size < 10000) {38 await fse.copy(entry, destPath);39 console.log(`Copied ${relativePath} without compression`);40 } else {41 const dirPath = path.dirname(destPath);42 await fse.ensureDir(dirPath);43 await sharp(entry)?.[metadata.format](formatOptions).toFile(destPath);44 console.log(`Compressed and copied ${relativePath}`);45 }46 }47 }48 } catch (error) {49 console.error("Error during image compression and copy:", error);50 }51}
3. Git操作
次に、simple-git
ライブラリを使用して画像を自動的にGitHubリポジトリにアップロードします:
1import simpleGit from "simple-git";2
3const gitRepoDir = "/project/resources";4
5async function gitOperations() {6 try {7 const git = simpleGit(gitRepoDir);8 await git.add("./*");9 await git.commit("Update images");10 await git.push("origin", "main");11 console.log("Pushed changes to GitHub");12 } catch (error) {13 console.error("Error during Git operations:", error);14 }15}
4. 画像パスの更新
最後に、replace-in-file
ライブラリを使用してプロジェクト内のローカル画像パスをオンラインパスに置き換えます:
1import { globby } from "globby";2import { replaceInFile } from "replace-in-file";3
4// 画像パスを置き換えるディレクトリとファイル5const contentDir = "/project/myproject/src/content/**/*.{html,js,jsx,ts,tsx}";6const cdnBaseUrl =7 "https://cdn.jsdelivr.net/gh/[GitHubユーザー名]/resources/images";8
9async function updateImagePaths() {10 try {11 const files = await globby([contentDir]);12
13 const replaceOptions = {14 files,15 from: /(["'])\/images\/(.+\.(jpg|jpeg|png|gif))/g,16 to: `$1${cdnBaseUrl}/$2`,17 };18
19 const results = await replaceInFile(replaceOptions);20 console.log(21 "Modified files:",22 results23 .filter((result) => result.hasChanged)24 .map((result) => result.file),25 );26 } catch (error) {27 console.error("Error during updating image paths:", error);28 }29}
5. メイン関数
上記のステップを1つのメイン関数に統合します:
1(async function main() {2 await compressAndCopyImages(imagesDir, targetDir);3 await gitOperations();4 await updateImagePaths();5})();
以上のコードは、画像の圧縮、移動、アップロード、およびパスの置換を実現し、ローカル画像からCDNホスティングへの自動化プロセスを完了します。このようにして、ローカル開発中にローカル画像を使用し、生産環境ではCDN加速された画像を使用することで、ウェブサイトの読み込み速度とパフォーマンスを向上させます。