要約
私たちが普段利用しているnpmサードパーティパッケージは、この2つの仕様に基づいて開発されていることが多いのですが、プロジェクト内にCommonJSとES Moduleが両方存在する状況が起こりやすく、CommonJSとES Moduleが混在して開発される問題をどう解決すればよいでしょうか。 ESモジュール??
CommonJSとは何ですか?
- 2009 年、アメリカのプログラマー Ryan Dahl は、サーバーサイド プログラミングに JavaScript 言語を使用するために、node.js プロジェクトを作成しました。これにより、「JavaScript モジュール型プログラミング」が正式に誕生しました。サーバー側には、オペレーティング システムや他のアプリケーションと対話するモジュールが必要です。
- CommonJS は、Python、Ruby、Java に似た標準ライブラリを提供し、開発者が CommonJS API を使用して、さまざまな JavaScript インタープリターやさまざまなホスト環境で実行できるアプリケーションを作成できるようにします。
- NodeJS、webpack 通常は CommonJS の形式で書きます。
CommonJS では次のプログラムを開発できます。
(1)、サーバーサイド JavaScript アプリケーション
(2)、コマンドライン ツール
(3)、GUI アプリケーション
(4)、ハイブリッド アプリケーション (Titanium または Adobe AIR など)
コードフォーム
平たく言えば、この機能は次のようになります: require キーワードを使用して依存関係を導入します。次に例を示します。
const path = require('path')
const AutoLoad = require('@fastify/autoload')
および module.exports
module.exports = async function (fastify, opts) {
fastify.get('/', async function (request, reply) {
return 'this is an example'
})
}
ESモジュールとは何ですか?
ES Modules (ESM) は、モジュールを処理するための ECMAScript 標準です。Node.js は長い間 CommonJS 標準を使用してきましたが、ブラウザーにはモジュール システムが存在したことはありませんでした。すべての主要な決定 (モジュール システムなど) は、まず ECMAScript によって標準化され、次にブラウザによって実装される必要がありました。
ES モジュール (ESM) は、JavaScript の公式の標準化されたモジュール システムです。
ESモジュールの仕組み
開発にモジュールを使用すると、モジュール間の依存関係グラフが作成されます。異なる依存関係間のリンクは、使用するインポート ステートメントから得られます。
違い
- CommonJS のオンデマンド読み込み、動的読み込み、条件付き読み込み、および循環読み込み
- ESM は静的に読み込まれるため、依存関係を解析し、操作効率を最適化するのに便利です。import() は現在動的にロードすることもできます
- CommonJS モジュール出力値のコピー、ESM 出力値への参照。
- CommonJS は実行時にロードされ、ESM はコンパイル時にインターフェイスを出力します。
- CommonJS モジュールの require() は同期的にロードされ、ESM のインポートは非同期的にロードされ、独立したモジュールの依存関係解析フェーズがあります。
- ESM のインポートが促進され、変数 const は読み取り専用になります。
違いの例
CommonJS では、次のように __dirname を直接使用できます。
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'plugins'),
options: Object.assign({}, opts)
})
ただし、これは ESM ではサポートされなくなったため、次のように変更する必要があります。
import {dirname} from 'path';
import { fileURLToPath } from 'url';
function getDirname(url) {
const __filename = fileURLToPath(url);
return dirname(__filename);
}
解決
解決策 1: ES モジュールの仕様に従って、「タイプ」を指定します
CommonJSモジュールまたはESモジュールモジュールを使用するために特定のファイルを別途指定します
- 通常の状況では、設定しない場合、プロジェクトはデフォルトで CommonJS 仕様になります。
- package.json ファイルで "type": "module" を指定すると、ES モジュールの仕様に従います。
- 必須の指定ファイルのサフィックスが .cjs になった後、このファイルは CommonJS 仕様に準拠します。
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'test/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
ReferenceError: 在 ES 模块范围中没有定义要求,您可以使用 import 代替
这个文件被视为 ES 模块,因为它有一个’。Js 的文件扩展名和‘ test/package.json’包含“ type”: “ module”。若要将其视为 CommonJS 脚本,请将其重命名为使用’。Cjs 的文件扩展名。
「type」:「module」の場合、このエラーを解決するにはどうすればよいですか?
CommonJS スクリプトを使用するためにファイルのサフィックス名を個別に設定できます。指定されたファイルのサフィックスは mandatory.cjs です。
解決策 2: CommonJS 仕様に従って、構成を行わない
ES モジュールを使用する必要があるファイルのサフィックスを .mjs として指定すると、このファイルは ES モジュール仕様を使用するように強制されます。
解決策 3: Babel を使用して CommonJS および ES モジュールを完全に構成し、自由に使用します (現在、これには更新された構成ソリューションがあり、作業が完了したら解決策 4 を作成します。解決策 3 も使用できます)
依存関係をインストールする
npm install --save-dev babel-cli babel-preset-env babel-register babel-preset-stage-0
npm install --save babel-polyfill # babel转码时不能识别一些全局对象的API,例如Object.assign,使用它可以解决这个问题
- babel-polyfill babel はトランスコード時に一部のグローバル オブジェクト API を認識しません
- babel-preset-stage-0 es 段階的提案構文 stage-0 には stage1、2、3 が含まれます
- babel-register フック。トランスコーディングを実現するためにプログラム エントリ ファイルに導入できます。
ルート ディレクトリに新しい .babelrc を作成します。
{
"presets": [
"env",
"stage-0"
]
}
コマンドエントリを設定し、ルートディレクトリに新しい main.js を作成します。
require('babel-polyfill');
require('babel-register');
require('./app.js'); // 引入您的项目的启动文件
コマンドラインを設定する
package.jsonに追加
"scripts": {
"start": "node main.js",
},
スタートアッププロジェクト
npm start
これで完了です。次のプロジェクトで任意の型を問題なく作成できます。
解決策 4: 完了したら、追加を続けます。依存関係を少なくできる、より良い方法があります。
- 今日はここに書きます〜
- 友達、( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ また明日~~
- みんなも毎日幸せになろうね
記事の修正が必要な箇所はどなたでもご指摘ください~
学習には終わりがなく、協力は双方に利益をもたらします