EY-Office ブログ

import.meta.globって何?

EY-OfficeサイトのAstro化も終わり、すでににAstro版に置きかわりました。🎉

実は公開寸前にブログのRSSフィードが無いことに気が付きました。最近はRSSはマイナーな存在かもしれませんが、私自身も使っていますし、昔からインターネットを使っていた人達は使っているかも知れませんね。

調べてみるとAstroにもRSS機能がありました。😊

import.meta.glob DeepAIが生成した画像です

AstroでRSSを作るには

AstroでRSSを作る方法はRSSページに書かれてます。 デフォルのディレクトリー構成だと最初のコードのように簡単に出来ますが、EY-Officeサイトはディレクトリー構成が標準通りではないので2番目のコードを基に作りました。

これらのサンプル・コードを見ていて import.meta.glob とうい見慣れないものを発見しました。

export const get = () => rss({
  // ・・・
  items: import.meta.glob('./**/*.md'),
  // ・・・
});
// ・・・
const postImportResult = import.meta.glob('../posts/**/*.md', { eager: true });
const posts = Object.values(postImportResult);
// ・・・

importはimport文のインポートと違うのかな??

import.metaとは

import.metaはES2020で追加された機能で、MDNに解説ドキュメントがありました。

import.meta オブジェクトはコンテキスト固有のメタデータを JavaScript のモジュールに公開します。これには、モジュールの URL のようなモジュールに関する情報が含まれています。

何をいってるんだろう? 例に書いてある事は判るのですが、何に使うんだろう? import.meta.glob は定義されてないの・・・??
でしたが説明の2行目には、

import.meta オブジェクトは ECMAScript 実装によって生成され、プロトタイプは null です。オブジェクトは拡張でき、そのプロパティは書き込み、構成、列挙可能です。

と拡張できるそうです。だれかが拡張してるらしい?

また、MDNのimportを読み直してみましたが、構文の最後にvar promise = import("module-name"); のように値を戻すimportが書かれていました。

import.meta.globとは

Astroは快適な開発環境が提供できるようにViteの上に構築されています。そしてimport.meta.glob はViteに定義されていました。→ Glob Import
import.meta.globは引数で指定された正規表現にマッチするファイル(モジュール)を全てインポートしてくれます。

正確には、

  • import.meta.glob('./**/*.md')./**/*.mdにマッチするファイル(モジュール)をインポートする関数を値に、パス名をキーに持ったオブジェクトを戻します
  • import.meta.glob('../posts/**/*.md', { eager: true })の戻り値は、キーはパス名ですが、値はインポートされたファイル(モジュール)の内容になります
  • AstroではViteのプラグイン機能を使い、ファイルの拡張子が.mdならMarkdownファイルを表すオブジェクトとして読み込まれます

AstroにはAstro.glob()関数がありますが、これはimport.meta.glob()をラップした関数で正規表現にマッチしたファイルの内容オブジェクトの配列が戻ってきます。

まとめ

Astroオブジェクトは.astroファイルでしか使えないので、今までは以下のように.astroファイルで postsを取得しライブラリーlastBlog()に渡していました。

  • blog.astro
import BlogLayout from '@layouts/Blog.astro';
import { lastBlog, recentBlogs, featuredBlogs } from '@utils/BlogPost';

const posts = await Astro.glob('/src/_blog/*.md');
const blog = lastBlog(posts);
---

<BlogLayout title="EY-Office ブログ">
<main class="blog-page blog-top">
  <div class="blog-p__latest">

// ・・・

しかしimport.meta.globAstro.glob()の実体だと知り、ライブラリーlastBlog()内で全て処理できるようになりました。

  • blog.astro
---
import BlogLayout from '@layouts/Blog.astro';
import { lastBlog, recentBlogs, featuredBlogs } from '@utils/BlogPost';
const blog = lastBlog();
---

<BlogLayout title="EY-Office ブログ">
<main class="blog-page blog-top">
  <div class="blog-p__latest">

// ・・・
  • utils/BlogPost.ts
// ・・・

export const blogInfo = (post: MarkdownInstance<Record<string, any>>) => {
  // ・・・
}

// ・・・

const postImportResult = import.meta.glob('../_blog/**/*.md', { eager: true });
const posts = Object.values(postImportResult).reverse() as MarkdownInstance<Record<string, any>>[];

export const lastBlog = () => {
  return blogInfo(posts[0]);
};

// ・・・

知らないもの・不思議なものが出てきたら調べてみると学びがあるだけでなく、コードの改善にも役立ちますね。

- about -

EY-Office代表取締役
・プログラマー
吉田裕美の
開発者向けブログ