28
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

拡張子がmjsとjsのファイルの違いについて

Posted at

Nodeのバージョン18以上のLambdaでは、デフォルトファイルの拡張子がmjsに変更されています。LambdaのNodeのバージョンを更新するにあたり、mjsファイルとjsファイルとの違いについて調査しました。結論として、拡張子の違いはJavaScriptのモジュールシステムの違いに由来しています。以下、詳細を解説します。

拡張子が.mjsと.jsのファイルの違い

前提

JavaScriptには2つの主要なモジュールシステムが存在します。

  • CommonJs
  • ECMAScript(ES Module, ES2015)

モジュールシステムと拡張子

  • CommonJs: cjs(あまり一般的ではありません)
  • ES Module: mjs

拡張子がjsの場合は、package.json内のtypeフィールドで指定されたモジュールシステムに従います。type"commonjs"または"module"のいずれかを指定できます。指定がない場合、デフォルトはCommonJSとなります。

実験

拡張子が.mjsのファイルでCommonJS形式で記述した場合

// lib.mjs
const sayHello = () => {
  console.log("Hello")
}

module.exports = { sayHello }
// index.mjs
const { sayhello } = require("./lib")

exports.handler = async (event) => {
  sayHello()
}

Lambdaを実行してみると、以下のエラーが表示されました。

{
  "errorType": "ReferenceError",
  "errorMessage": "require is not defined in ES module scope, you can use import instead",
  "trace": [
    "ReferenceError: require is not defined in ES module scope, you can use import instead",
    "    at file:///var/task/index.mjs:1:22",
    "    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)",
    "    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)",
    "    at async _tryAwaitImport (file:///var/runtime/index.mjs:1008:16)",
    "    at async _tryRequire (file:///var/runtime/index.mjs:1057:86)",
    "    at async _loadUserApp (file:///var/runtime/index.mjs:1081:16)",
    "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)",
    "    at async start (file:///var/runtime/index.mjs:1282:23)",
    "    at async file:///var/runtime/index.mjs:1288:1"
  ]
}

上記のLambdaを実行すると、requireがESモジュールスコープで定義されていないというエラーが表示されました。これは、拡張子が.mjsのファイルがESモジュールとして解釈されるため、CommonJS形式での記述がサポートされていないことを意味します。同じコードを.jsの拡張子で実行すると、問題なく動作します。

結論

  • 拡張子の違いは、JavaScriptのモジュールシステムの違いに基づく。
  • Nodeのバージョン18以降のLambdaではデフォルトのファイル拡張子が.mjsになっているが、CommonJS形式を引き続き使用したい場合は、.js(または.cjs)の拡張子を持つファイルを使用する必要がある。

参照

28
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?