“Gereksinim (x)” ve “içe aktarma x” arasındaki fark


193

Bir MongoDB ile arayüz kuracak küçük bir düğüm projesi üzerinde çalışmaya başladım. Ancak, doğru bir şekilde kurduğum halde, ilgili düğüm modüllerinin doğru bir şekilde içe aktarılmasını sağlayamıyorum npm.

Örneğin, aşağıdaki kod bir hata atar ve bana "ekspresin varsayılan dışa aktarımı olmadığını" söyler:

import express from "express";

Ancak, bu kod çalışır:

const express = require("express");

Benim sorum, içe aktarma ve değişken / gereksinim yöntemlerinin işleyişindeki fark nedir? Projede ithalatımı rahatsız eden her şeyi düzeltmek istiyorum, çünkü yolda ek sorunlara neden olabilir gibi görünüyor.


Express için yazım tanımlarını dahil etmedikçe, ilk form mantıklı olmaz - bu durumda ikinci formu kullanabilirsiniz, ancak değişken tür expressolacaktır any. Tanımları buradan ekleyebilirsiniz npmjs.com/package/@types/express
Filipe Sabella

Yanıtlar:


232

requireVe arasındaki farkı anlamama yardımcı olan bu basit diyagram import.

resim açıklamasını buraya girin

Onun dışında,

Sen olamaz seçici sizinle gereken tek parça yüklemek requirefakat imports, seçerek sadece ihtiyacınız parçaları yükleyebilirsiniz. Bu hafızadan tasarruf edebilir.

Öte yandan yükleme eşzamanlı (adım adım) için eşzamansız olabilir (önceki içe aktarmayı beklemeden), böylece biraz daha iyi performans gösterebilir .requireimport require


Kodu etkileyen en büyük fark, CommonJS modüllerindeki ihracatın "hesaplanmış" iken, ESM modülündeki ihracatın statik (önceden tanımlanmış) olmasıdır. JS, ESM modülündeki dışa aktarmaları yalnızca kodu ayrıştırdıktan sonra (henüz çalıştırmadan) belirleyebilir. CommonJS modülünde dışa aktarma işlemi, yalnızca modül gerçekten çalıştığında bilinir module.exportsve modül başlatma kodu çalışmayı bitirdiğinde neye atandığını görürsünüz . Tek başına bu fark, hem ESM hem de CommonJS için tek bir modülün çalışması için uyumluluk baş ağrıları oluşturur.
jfriend00

ESM modülleri paketleyicilerin dostudur, ancak ESM modüllerinde hesaplanmış dışa aktarım yapamayacağınız için kodlayıcılar için daha kısıtlayıcıdır.
jfriend00

77

Arasındaki büyük fark requireve import, yani requireotomatik olarak tarar node_modulesmodülleri bulmak için, ama import, ES6 geliyor ki, olmaz.

Çoğu insan derlemek için babil kullanır importve exportbu da importaynı şeyi yapar require.

Node.js'nin gelecekteki sürümü importkendini destekleyebilir (aslında, deneysel sürüm zatenimport destekliyor) node_modulesve Node.js'nin notlarına bakılırsa desteklenmez , ES6'ya dayanır ve modülün yolunu belirtmelidir.

Bu yüzden importbabel ile kullanmamanızı öneririm , ancak bu özellik henüz onaylanmadı, node_modulesgelecekte destekleyebilir , kim bilir?


Referans olarak, aşağıda babil ES6'nın importsözdizimini CommonJS'nin sözdizimine nasıl dönüştürebileceğinin bir örneğidir require.

Dosyanın app_es6.jsbu içe aktarmayı içerdiğini varsayalım:

import format from 'date-fns/format';

Bu, format işlevini date-fns düğümü paketinden içe aktarmak için bir yönergedir .

İlgili package.jsondosya böyle bir şey içerebilir:

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

İlgili .babelrcdosya şöyle olabilir:

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

Dosyada build-server-filetanımlanan bu komut package.jsondosyası, babel'in app_es6.jsdosyayı ayrıştırıp çıktısını alması için bir yönergedir app.js.

build-server-fileKomut dosyasını çalıştırdıktan sonra app.js, date-fnsiçe aktarmayı açar ve ararsanız, bu dosyaya dönüştürüldüğünü görürsünüz:

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

var _format2 = _interopRequireDefault(_format);

Bu dosyanın çoğu çoğu insan için gobbledygook, ancak bilgisayarlar bunu anlıyor.


Ayrıca bir modül oluşturulur ve yüklerseniz, projenize içine alınabilir nasıl bir örnek olarak referans için date-fnsve daha sonra açmak node_modules/date-fns/get_year/index.jsİçerdiği görebilirsiniz:

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

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

module.exports = getYear

Yukarıdaki babel işlemini kullanarak app_es6.jsdosyanız şunları içerebilir:

import getYear from 'date-fns/get_year';

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

Babel ithalatı şu şekilde değiştirir:

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

var _get_year2 = _interopRequireDefault(_get_year);

Ve işleve ilişkin tüm referansları buna göre ele alın.


aaaaahhhhhh. Babel, bu projeye yüklenmedi, bu da her şeyin anlamlı olduğunu gösteriyor. ES6 ithalatının / ihracatının zaten işlevsel olduğunu düşündüm, ancak şimdi require
Babel'in

şimdilik talep sopa. Gelecekte her zaman sorunsuzca değiştirebilirsiniz
Juan

2
import won't support node_modulesBununla ne demek istedin?
PrivateOmega

11

Gereksinim ve içe aktarma özellikli ekspres modülü dahil etmek için bir örnek vereyim

-require

var express = require('express');

-ithalat

import * as  express from 'express';

Dolayısıyla yukarıdaki ifadelerden herhangi birini kullandıktan sonra bizimle 'ekspres' adı verilen bir değişkenimiz olacaktır. Şimdi 'app' değişkenini şu şekilde tanımlayabiliriz:

var app = express(); 

Bu yüzden 'CommonJS' ile 'zorunlu' ve 'ES6' ile 'içe aktar' kullanırız.

'Zorunlu' ve 'içe aktarma' hakkında daha fazla bilgi için aşağıdaki bağlantıları okuyun.

gerektirir - Node.js'de modül : Bilmeniz gereken her şey

import - Node.js'deki ES6 Modüllerinde Güncelleştirme


3

Burada bir cevap değil ve daha çok bir yorum gibi, üzgünüm ama yorum yapamam.

V10 düğümünde, --experimental-modulesNodejs'e kullanmak istediğinizi bildirmek için bayrağı kullanabilirsiniz import. Ancak giriş komut dosyanızın.mjs .

Bunun hala deneysel bir şey olduğunu ve üretimde kullanılmaması gerektiğini unutmayın .

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

Referans 1 - Nodejs SPORCU BİLGİLERİ

Ref 2 - Github Sorunu


3

yeni ES6:

js dosyaları arasında değişkenleri / dizileri / nesneleri paylaşmak için 'import' anahtar kelimeleriyle 'export' kullanılmalıdır:

export default myObject;

//....in another file

import myObject from './otherFile.js';

eski skool:

'modül' ile 'talep' kullanılmalıdır.

 module.exports = myObject;

//....in another file

var myObject = require('./otherFile.js');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.