はじめに
Eleventy は、日々メンテナンスされ、更新が行われています。v1に始まり、v2, v3とバージョンの更新が行われてきました。
Eleventy v3 では、従来の Node.js のモジュールシステム require(CommonJS)に加え、import / export(ESM)にも、対応するようになりました。
この記事では、Eleventy v3 への対応として、require(CommonJS)を import / export(ESM)に、切り替える方法についてまとめています。
package.json の変更
まず、最初に修正が必要なのは、package.json ファイルになります。
基本的に、 Eleventy v3 でも、従来の require(CommonJS)も使用可能ですが、 Node.js の公式方針がimport / export(ESM)へ移行しているため、今後は ESM が主流になると考えられます。
現状、Eleventy v3 の挙動は Node.js の "type" 設定に従います。そのため、"type" を書かない場合は Node.js のデフォルトである CommonJS として扱われます。
Eleventy v3 の仕様は次の通りです。
| package.jsonの設定 | モジュールタイプ | require/module.exports | import/export |
|---|---|---|---|
| "type": "commonjs" | CommonJS | ⭕ 動く | ❌ 基本使えない |
| "type": "module" | ESM | ❌ 動かない | ⭕ 動く |
| "type" を書かない | CommonJS | ⭕ 動く | ❌ 基本使えない |
👉 Eleventy v3 は ESM を強制しておらず、Node.js の設定に従います。
もし、package.json に下記の定義があると、
"type": "commonjs"
これは Node.js に対して:「このプロジェクトの .js は CommonJS として扱ってください」という意味になります。
その為、 ESM を使いたい場合は、意図的に package.json に、下記の定義を加えるか、従来の定義を変更する必要があります。
"type": "module"
👉 これで、このプロジェクトの .js が ESM として扱われるようになります。
Eleventyの定義の変更
Eleventy が起動された時に読み込まれる .eleventy.js ファイルですが、これは、純粋な JavaScript ファイルなので、当然、モジュールタイプの影響を受けます。
ファイルに記述されている
require(CommonJS)をimport(ESM) に変更module.exports =(CommonJS)をexport(ESM)に変更
する必要があります。
例: .eleventy.js
const { DateTime } = require("luxon");
const slugify = require("slugify");
const fs = require("fs");
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const markdownIt = require("markdown-it");
const markdownItAttrs = require("markdown-it-attrs");
const categoryDefine = require("./src/_data/categoryDefine.js");
module.exports = function (eleventyConfig) {
:
CommonJS から ESM へ変更 👇
import { DateTime } from "luxon";
import slugify from "slugify";
import fs from "fs";
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
import markdownIt from "markdown-it";
import markdownItAttrs from "markdown-it-attrs";
import categoryDefine from "./src/_data/categoryDefine.js";
export default function (eleventyConfig) {
:
👉 これで、Eleventy の定義ファイルが正しく動作するようになります。
注意点
Node.js の ESM では、「npm パッケージの import には .js を付けなくてよい」ですが、「相対パスの import には .js が必須」です。
また、import で読み込まれるモジュールは、ESM 対応され、該当のエントリーが、 export されている必要があります。
外部モジュールを読み込んでいる場合は、該当モジュールが ESM 対応されているかどうかを事前に確認の上、行ってください。
ESM 対応されていないモジュールがある場合は、ESM 対応されている他のモジュールに切り替えるか、従来通り、CommonJS での対応を続ける必要があります。
Eleventy v3 では従来の .eleventy.js に加えて eleventy.config.js という新しい設定ファイル名が利用できます。
Cloudflare Workers(Wrangler)環境では、.eleventy.js が正しく読み込まれないケースがあるため、eleventy.config.js を使用することを推奨します。
_data 配下のスクリプトの変更
ソースディレクトリの _data 配下に、データファイルとして、 .js ファイルを用意している場合は、これらも CommonJS から ESM に変更する必要があります。
Eleventy は _data/*.js を Node.js と同じモジュール方式で読み込みます。そのため、プロジェクトが ESM の場合は _data/*.js も ESM にする必要があるのです。
module.exports =(CommonJS)をexport(ESM)に変更
例: _data/tagDefine.js
module.exports = {
"はじめて": {
yomi: "hajimete"
},
:
CommonJS から ESM へ変更 👇
export default {
"はじめて": {
yomi: "hajimete"
},
:
👉 これで、データファイルとして、正しく読み込まれます。
その他の JavaScript ファイル
上記以外の .js や ~.11ty.js ファイルがある場合、これらも CommonJS から ESM に変更する必要があります。
変更内容は、.eleventy.js ファイルと同様です。
require(CommonJS)をimport(ESM) に変更module.exports =(CommonJS)をexport(ESM)に変更
例:
const fs = require("fs");
const categoryDefine = require("./src/_data/tagDefine.js");
module.exports = {
data: {
permalink: "feed.xml",
eleventyExcludeFromCollections: true,
contentType: "application/xml"
},
:
CommonJS から ESM へ変更 👇
import fs from "fs";
import categoryDefine from "./src/_data/tagDefine.js";
export default {
data: {
permalink: "feed.xml",
eleventyExcludeFromCollections: true,
contentType: "application/xml"
},
:
👉 これで、正しく、読み込まれるようになります。
まとめ
-
Eleventy v3 は ESM(import/export)を推奨しているが、 CommonJS(require)も普通に使える。
-
Eleventy v3 のモジュール方式は Node.js の package.json の "type" 設定に従う。
- "type": "commonjs" なら
require/module.exportsが動く - "type": "module" なら
import/exportが必要
- "type": "commonjs" なら