Perbedaan antara "membutuhkan (x)" dan "impor x"

190

Saya baru saja mulai bekerja pada proyek simpul kecil yang akan berinteraksi dengan MongoDB. Namun, sepertinya saya tidak bisa mendapatkan modul simpul yang relevan untuk mengimpor dengan benar, meskipun saya telah menginstalnya dengan benar npm.

Misalnya, kode berikut melempar kesalahan, memberi tahu saya bahwa "express tidak memiliki ekspor default":

import express from "express";

Namun, kode ini berfungsi:

const express = require("express");

Jadi pertanyaan saya adalah, apa perbedaan dalam bagaimana fungsi impor dan variabel / memerlukan metode? Saya ingin memperbaiki apa pun yang mengganggu impor saya di proyek ini, karena sepertinya akan menimbulkan masalah tambahan.

austinthemassive
sumber
Kecuali Anda memasukkan definisi pengetikan untuk express, form pertama tidak akan masuk akal - dalam hal ini Anda bisa menggunakan form kedua, tetapi variabel expressakan bertipe any. Anda dapat memasukkan definisi dari sini npmjs.com/package/@types/express
Filipe Sabella

Jawaban:

227

Diagram sederhana ini yang membantu saya memahami perbedaan antara requiredan import.

masukkan deskripsi gambar di sini

Selain itu,

Anda tidak dapat secara selektif memuat hanya potongan-potongan yang Anda butuhkan requiretetapi dengan imports, Anda dapat memuat secara selektif hanya potongan-potongan yang Anda butuhkan. Itu bisa menghemat memori.

Memuat sinkron (langkah demi langkah) karena requiredi sisi lain importdapat asinkron (tanpa menunggu impor sebelumnya) sehingga dapat melakukan sedikit lebih baik daripada require .

Selalu cerah
sumber
Perbedaan terbesar yang memengaruhi kode adalah bahwa ekspor dalam modul CommonJS "dihitung", sedangkan ekspor dalam modul ESM bersifat statis (ditentukan sebelumnya). JS dapat menentukan ekspor dalam modul ESM setelah hanya menguraikan kode (belum menjalankannya). Dalam modul commonJS, ekspor hanya diketahui saat modul benar-benar berjalan dan Anda melihat apa yang ditugaskan module.exportsketika kode inisialisasi modul selesai berjalan. Perbedaan ini sendiri menciptakan sakit kepala kompatibilitas dalam mencoba membuat satu modul berfungsi baik untuk ESM dan CommonJS.
jfriend00
Modul ESM lebih ramah untuk bundler, tetapi lebih membatasi untuk coder karena Anda tidak dapat menghitung ekspor dalam modul ESM.
jfriend00
76

Perbedaan utama antara requiredan import, adalah bahwa itu requireakan secara otomatis memindai node_modulesuntuk menemukan modul, tetapi import, yang berasal dari ES6, tidak akan.

Kebanyakan orang menggunakan babel untuk mengkompilasi importdan export, yang membuat importbertindak sama dengan require.

Versi Node.js yang akan datang mungkin mendukung importdirinya sendiri (sebenarnya, versi eksperimental sudah melakukannya ), dan menilai berdasarkan catatan Node.js, importtidak akan mendukung node_modules, itu berdasarkan ES6, dan harus menentukan jalur modul.

Jadi saya sarankan Anda tidak menggunakan importdengan babel, tetapi fitur ini belum dikonfirmasi, mungkin mendukung node_modulesdi masa depan, siapa yang tahu?


Untuk referensi, di bawah ini adalah contoh bagaimana babel dapat mengubah importsintaks ES6 menjadi sintaks CommonJS require.

Katakanlah file app_es6.jsberisi impor ini:

import format from 'date-fns/format';

Ini adalah arahan untuk mengimpor fungsi format dari paket node date-fns .

File terkait package.jsondapat berisi sesuatu seperti ini:

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

File terkait .babelrcbisa seperti ini:

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

build-server-fileScript ini didefinisikan dalam package.jsonfile adalah arahan bagi babel untuk mengurai app_es6.jsfile dan output file app.js.

Setelah menjalankan build-server-fileskrip, jika Anda membuka app.jsdan mencari date-fnsimpor, Anda akan melihatnya telah diubah menjadi ini:

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

var _format2 = _interopRequireDefault(_format);

Sebagian besar file itu adalah gobbledygook bagi kebanyakan manusia, namun komputer memahaminya.


Juga untuk referensi, sebagai contoh bagaimana modul dapat dibuat dan diimpor ke proyek Anda, jika Anda menginstal date-fnsdan kemudian buka node_modules/date-fns/get_year/index.jsAnda dapat melihatnya berisi:

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

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

module.exports = getYear

Menggunakan proses babel di atas, app_es6.jsfile Anda kemudian dapat berisi:

import getYear from 'date-fns/get_year';

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

Dan babel akan mengubah impor menjadi:

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

var _get_year2 = _interopRequireDefault(_get_year);

Dan menangani semua referensi ke fungsi yang sesuai.

Ayon Lee
sumber
aaaaahhhhhh. Babel belum diinstal pada proyek khusus ini, yang membuat semuanya masuk akal. Saya berpikir bahwa impor ES6 / ekspor yang fungsional sudah, tapi sekarang saya mengerti bahwa Babel hanya mengubah segalanya untuk requiretetap
austinthemassive
tetap membutuhkan untuk saat ini. Anda selalu dapat mengubahnya di masa mendatang tanpa masalah
Juan
1
import won't support node_modulesApa yang kamu maksud dengan itu?
PrivateOmega
11

Biarkan saya memberi contoh untuk Termasuk modul kilat dengan memerlukan & impor

-memerlukan

var express = require('express');

-impor

import * as  express from 'express';

Jadi setelah menggunakan salah satu dari pernyataan di atas kita akan memiliki variabel yang disebut sebagai 'ekspres' dengan kami. Sekarang kita dapat mendefinisikan variabel 'aplikasi' sebagai,

var app = express(); 

Jadi kami menggunakan 'wajib' dengan 'CommonJS' dan 'impor' dengan 'ES6'.

Untuk info lebih lanjut tentang 'wajib' & 'impor', baca tautan di bawah ini.

membutuhkan - Membutuhkan modul di Node.js: Semua yang perlu Anda ketahui

import - Pembaruan pada Modul ES6 di Node.js

saikiran_hegde
sumber
3

Bukan jawaban di sini dan lebih seperti komentar, maaf tapi saya tidak bisa berkomentar.

Di simpul V10, Anda bisa menggunakan flag --experimental-modulesuntuk memberi tahu Nodejs yang ingin Anda gunakan import. Tetapi skrip entri Anda harus diakhiri dengan .mjs.

Perhatikan ini masih merupakan hal yang eksperimental dan tidak boleh digunakan dalam produksi.

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

Ref 1 - Nodejs Doc

Ref 2 - masalah github

Tianpeng. Xia
sumber
3

ES6 baru:

'import' harus digunakan dengan kata-kata kunci 'export' untuk berbagi variabel / array / objek antara file js:

export default myObject;

//....in another file

import myObject from './otherFile.js';

skool lama:

'wajib' harus digunakan dengan 'module.exports'

 module.exports = myObject;

//....in another file

var myObject = require('./otherFile.js');
LaZza
sumber