Skip to content

Astroで相対パスを置換

Published: at 16:00

Table of contents

Open Table of contents

作った経緯

Astroでサイト構築を行ない、buildした際、hrefやsrcのパスは、/_astro/index.XXXXX.cssのような形で出力される。 今回作成したサイトはhttp://sample.com/sample/のようにサブディレクトリで公開するため、そのままのコードだとCSS,JSファイルを正常に読み込めない。 そこでパスを書き換える必要があった。

サイト構成

サイト構成は下記の通り。最低限のものだけ記載。

repalce.mjs
dist
├── _astro
│   ├── XXXX.js
│   └── XXXX.css
├── en
│   ├── index.html
│   ├── member
│   │   └── index.html
│   └── topics
│       └── index.html
├── images
│   ├── home
│   │   ├── XXXX.png
│   │   └── XXXX.png
│   └── member
│       ├── XXXX.jpg
│       └── XXXX.png
├── index.html
├── about
│   └── index.html
└── topics
    └── index.html

コード

コードは下記に示す。

import { writeFileSync, readFileSync } from 'fs';
import {glob} from 'glob';

const replaceInHtmlFiles = () => {
  try {
    const files = glob.sync('dist/**/*.{html,css}');
    for (const file of files) {
      // htmlファイルの読み込み
      const data = readFileSync(file, 'utf8');
      const depth = file.split('/').length - 1; 
      console.log(file, depth);
      let relativePath = './'; // デフォルトは同一ディレクトリ
      if (depth > 1) {
        // ファイルがサブディレクトリにある場合、適切な数の `../` を使用
        relativePath = '../'.repeat(depth - 1);
      }

      if(file.match(/\.css$/)) {
        const result = data.replace(/url\(\/(.*?)\)/g, `url(${relativePath}$1)`)
        writeFileSync(file, result, 'utf8');
      } else if(file.match(/\.html$/)){
        // htmlファイルの場合、相対パスを置換

        const result = data
            .replace(/href="\/(.*?)"/g, `href="${relativePath}$1"`)
            .replace(/src="\/(.*?)"/g, `src="${relativePath}$1"`)
            .replace(/srcset="\/(.*?)"/g, `srcset="${relativePath}$1"`)
          writeFileSync(file, result, 'utf8');
      }
    }

    console.log('Replace in html, css files done');
  } catch (error) {
    console.log(error);
  }
};

replaceInHtmlFiles();

使用方法

使用したいディレクトリにreplace.mjsというファイルで作成。 node replace.mjs と入力して使用する。

自分はbuild時にのみ使用していたため、package.jsonの中で "build": "astro check && astro build && node replace.mjs"と設定し、build時に同時に処理することとした。