はじめに
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 での対応を続ける必要があります。
_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" なら