「require(x)」と「import x」の違い


190

MongoDBと連動する小さなノードプロジェクトの作業を始めたところです。ただし、を使用して適切にインストールしたにもかかわらず、関連するノードモジュールを正しくインポートできないようですnpm

たとえば、次のコードはエラーをスローし、「エクスプレスにはデフォルトのエクスポートがない」と通知します。

import express from "express";

ただし、このコードは機能します。

const express = require("express");

だから私の質問は、インポートと変数/要求メソッドの機能の違いは何ですか?今後、問題が発生する可能性があるため、プロジェクトでのインポートの問題を修正します。


expressの型定義を含めない限り、最初の形式は意味がありません。その場合、2番目の形式を使用できますが、変数expressはtypeになりanyます。ここから定義を含めることができますnpmjs.com/package/@types/express
Filipe Sabella

回答:


227

requireとの違いを理解するのに役立つこの簡単な図import

ここに画像の説明を入力してください

それとは別に、

で必要な部分のみを選択的にロードすることはできませんrequireimports、を使用すると、必要な部分のみを選択的にロードできます。メモリを節約できます。

ローディングは、同期のために(段階的)require一方がimportそのように(前のインポートを待つことなく)非同期であることができる少し良くより行うことができます require


コードに影響する最大の違いは、CommonJSモジュールでのエクスポートは「計算」されるのに対し、ESMモジュールでのエクスポートは静的(事前定義)であることです。JSは、コードを解析するだけで(まだ実行していない)、ESMモジュールのエクスポートを判別できます。commonJSモジュールでは、エクスポートはモジュールが実際に実行されたときにのみ認識されmodule.exports、モジュール初期化コードの実行が終了したときに何が割り当てられるかがわかります。この違いだけでも、ESMとCommonJSの両方で1つのモジュールを機能させようとするときに互換性の問題が生じます。
jfriend00

ESMモジュールは、バンドラーにはより使いやすくなっていますが、ESMモジュールで計算されたエクスポートを行うことができないため、コーダーにはより制限的です。
jfriend00

76

主な違いrequireとはimport、つまりrequire自動的にスキャンするnode_modulesモジュールを見つけるために、しかしimport、ES6から来ていることはありません。

ほとんどの人は使用バベルをコンパイルするimportexportなりこれ、import同じ行動しますrequire

Node.jsの将来のバージョンはimportそれ自体をサポートする可能性があり(実際、試験的なバージョンはすでにサポートしています)、Node.jsのメモによるimportと、サポートしませんnode_modules。ES6に基づいており、モジュールのパスを指定する必要があります。

だから私はあなたimportがバベルと一緒に使用しないことをお勧めしますが、この機能はまだ確認されていませんnode_modules、将来的にサポートされるかもしれません、誰が知っているでしょうか?


参考までに、以下はbabelがES6のimport構文をCommonJSのrequire構文に変換する方法の例です。

ファイルapp_es6.jsに次のインポートが含まれているとします。

import format from 'date-fns/format';

これは、ノードパッケージdate-fnsからフォーマット関数をインポートするためのディレクティブです

関連package.jsonファイルには次のようなものを含めることができます:

"scripts": {
    "start": "node app.js",
    "build-server-file": "babel app_es6.js --out-file app.js",
    "webpack": "webpack"
}

関連.babelrcファイルは次のようになります。

{
    "presets": [
        [
            "env",
            {
                "targets":
                {
                    "node": "current"
                }
            }
        ]
    ]
}

ファイルでbuild-server-file定義されているこのスクリプトpackage.jsonは、babelがapp_es6.jsファイルを解析してファイルを出力するためのディレクティブですapp.js

build-server-fileスクリプトを実行した後app.jsdate-fnsインポートを開いて探すと、次のように変換されていることがわかります。

var _format = require("date-fns/format");

var _format2 = _interopRequireDefault(_format);

そのファイルのほとんどは、ほとんどの人間にとってはむちゃくちゃですが、コンピュータはそれを理解しています。


また、参考までに、モジュールを作成してプロジェクトにインポートする方法の例として、インストールdate-fnsしてから開くと、次のnode_modules/date-fns/get_year/index.jsものが含まれていることがわかります。

var parse = require('../parse/index.js')

function getYear (dirtyDate) {
  var date = parse(dirtyDate)
  var year = date.getFullYear()
  return year
}

module.exports = getYear

上記のバベルプロセスを使用すると、app_es6.jsファイルに次の内容を含めることができます。

import getYear from 'date-fns/get_year';

// Which year is 2 July 2014?
var result = getYear(new Date(2014, 6, 2))
//=> 2014

そして、babelはインポートを次のように変換します。

var _get_year = require("date-fns/get_year");

var _get_year2 = _interopRequireDefault(_get_year);

そして、それに応じて関数へのすべての参照を処理します。


ああああ この特定のプロジェクトにはBabelがインストールされていないため、すべてが理にかなっています。私はES6の輸入/輸出はすでに機能したと思ったが、今私はバベルがちょうどにすべてを変えていることを理解しrequire、とにかく
austinthemassive

とりあえず必要なこだわり。いつでも問題なく変更できます
Juan

1
import won't support node_modulesあなたはそれによって何を意味しました?
PrivateOmega 2019

11

require&importでExpressモジュールを含める例を挙げましょう

-必要とする

var express = require('express');

-インポート

import * as  express from 'express';

したがって、上記のステートメントのいずれかを使用した後、 'express'と呼ばれる変数が作成されます。これで、「app」変数を次のように定義できます。

var app = express(); 

したがって、「require」を「CommonJS」で使用し、「import」を「ES6」で使用します。

「必要」と「インポート」の詳細については、以下のリンクをお読みください。

require- Node.jsのモジュールが必要:知っておくべきことすべて

import- Node.jsのES6モジュールの更新


3

ここでは答えではなく、コメントのようです。申し訳ありませんが、コメントはできません。

ノードV10では、フラグ--experimental-modulesを使用してNodejsに使用することを通知できますimport。ただし、入力スクリプトはで終わる必要があり.mjsます。

これはまだ実験的なものであり、本番環境で使用しないください

// main.mjs
import utils from './utils.js'
utils.print();
// utils.js
module.exports={
    print:function(){console.log('print called')}
}

参照1-Nodejsドキュメント

参照2-githubの問題


3

新しいES6:

jsファイル間で変数/配列/オブジェクトを共有するには、 'import'を 'export'キーワードとともに使用する必要があります。

export default myObject;

//....in another file

import myObject from './otherFile.js';

古いskool:

'require'は 'module.exports'と共に使用する必要があります

 module.exports = myObject;

//....in another file

var myObject = require('./otherFile.js');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.