Sự khác biệt giữa nhập yêu cầu (x) nhập và x


190

Tôi mới bắt đầu làm việc với một dự án nút nhỏ sẽ giao diện với MongoDB. Tuy nhiên, tôi dường như không thể có được các mô-đun nút có liên quan để nhập chính xác, mặc dù tôi đã cài đặt chúng chính xác thông qua npm.

Ví dụ: đoạn mã sau đưa ra lỗi, cho tôi biết rằng "express không có xuất mặc định":

import express from "express";

Tuy nhiên, mã này hoạt động:

const express = require("express");

Vì vậy, câu hỏi của tôi là, sự khác biệt trong cách nhập và biến / yêu cầu phương thức hoạt động là gì? Tôi muốn khắc phục bất cứ điều gì đang gây khó khăn cho việc nhập khẩu của tôi vào dự án, vì nó dường như có thể gây ra thêm vấn đề.


Trừ khi bạn bao gồm các định nghĩa gõ cho biểu thức, biểu mẫu đầu tiên sẽ không có ý nghĩa - trong trường hợp đó bạn có thể sử dụng biểu mẫu thứ hai, nhưng biến expresssẽ có kiểu any. Bạn có thể bao gồm các định nghĩa từ đây npmjs.com/package/@types/express
Filipe Sabella

Câu trả lời:


227

Sơ đồ đơn giản này giúp tôi hiểu sự khác biệt giữa requireimport.

nhập mô tả hình ảnh ở đây

Ngoài ra,

Bạn không thể chỉ chọn tải những phần bạn cần requirenhưng với imports, bạn chỉ có thể tải có chọn lọc những phần bạn cần. Điều đó có thể tiết kiệm bộ nhớ.

Tải là đồng bộ (từng bước) requiremặt khác importcó thể không đồng bộ (không phải chờ nhập trước đó) để nó có thể thực hiện tốt hơn một chút so với require .


Sự khác biệt lớn nhất ảnh hưởng đến mã là xuất khẩu trong các mô-đun CommonJS được "tính toán", trong khi xuất khẩu trong mô-đun ESM là tĩnh (được xác định trước). JS có thể xác định xuất khẩu trong một mô-đun ESM chỉ sau khi phân tích cú pháp mã (chưa chạy nó). Trong một mô-đun commonJS, xuất khẩu chỉ được biết khi mô-đun thực sự chạy và bạn thấy những gì được gán cho module.exportskhi mã khởi tạo mô-đun kết thúc chạy. Sự khác biệt này một mình tạo ra đau đầu tương thích trong việc cố gắng làm cho một mô-đun duy nhất hoạt động cho cả ESM và CommonJS.
jfriend00

Các mô-đun ESM thân thiện hơn với các trình đóng gói, nhưng hạn chế hơn đối với các lập trình viên vì bạn không thể tính toán xuất trong các mô-đun ESM.
jfriend00

76

Sự khác biệt chính giữa requireimport, là requiresẽ tự động quét node_modulesđể tìm các mô-đun, nhưng import, xuất phát từ ES6, sẽ không.

Hầu hết mọi người sử dụng babel để biên dịch importexport, điều này làm cho importhành động tương tự như require.

Phiên bản tương lai của Node.js có thể importtự hỗ trợ (thực tế, phiên bản thử nghiệm đã có ) và đánh giá theo ghi chú của Node.js, importsẽ không hỗ trợ node_modules, dựa trên ES6 và phải chỉ định đường dẫn của mô-đun.

Vì vậy, tôi sẽ đề nghị bạn không sử dụng importvới babel, nhưng tính năng này chưa được xác nhận, nó có thể hỗ trợ node_modulestrong tương lai, ai sẽ biết?


Để tham khảo, dưới đây là một ví dụ về cách babel có thể chuyển đổi importcú pháp của ES6 thành cú pháp của CommonJS require.

Nói rằng tệp app_es6.jschứa nhập này:

import format from 'date-fns/format';

Đây là một lệnh để nhập hàm định dạng từ gói ngày-fns .

Các package.jsontập tin liên quan có thể chứa một cái gì đó như thế này:

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

Các .babelrctập tin liên quan có thể là một cái gì đó như thế này:

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

Đây build-server-filekịch bản được định nghĩa trong package.jsontập tin là một chỉ thị cho babel để phân tích các app_es6.jstập tin và sản lượng các tập tin app.js.

Sau khi chạy build-server-filetập lệnh, nếu bạn mở app.jsvà tìm date-fnsnhập, bạn sẽ thấy tập lệnh đã được chuyển đổi thành:

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

var _format2 = _interopRequireDefault(_format);

Hầu hết các tập tin đó là gobbledygook cho hầu hết mọi người, tuy nhiên máy tính hiểu nó.


Cũng để tham khảo, như một ví dụ về cách mô-đun có thể được tạo và nhập vào dự án của bạn, nếu bạn cài đặt date-fnsvà sau đó mở, node_modules/date-fns/get_year/index.jsbạn có thể thấy nó chứa:

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

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

module.exports = getYear

Sử dụng quy trình babel ở trên, app_es6.jstệp của bạn có thể chứa:

import getYear from 'date-fns/get_year';

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

Và babel sẽ chuyển đổi nhập khẩu thành:

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

var _get_year2 = _interopRequireDefault(_get_year);

Và xử lý tất cả các tham chiếu đến chức năng cho phù hợp.


aaaaahhhhhh. Babel đã không được cài đặt trên dự án cụ thể này, điều này làm cho mọi thứ có ý nghĩa. Tôi đã nghĩ rằng nhập / xuất ES6 đã hoạt động, nhưng bây giờ tôi hiểu rằng Babel chỉ thay đổi mọi thứ thành requiredù sao đi nữa
austinthemassive

dính để yêu cầu cho bây giờ. Bạn luôn có thể thay đổi nó trong tương lai mà không gặp vấn đề gì
Juan

1
import won't support node_modulesCậu nói thế là ý gì?
PrivateOmega

11

Hãy để tôi đưa ra một ví dụ cho Bao gồm mô-đun express với yêu cầu & nhập

yêu cầu

var express = require('express');

nhập khẩu

import * as  express from 'express';

Vì vậy, sau khi sử dụng bất kỳ câu lệnh nào ở trên, chúng tôi sẽ có một biến gọi là 'express' với chúng tôi. Bây giờ chúng ta có thể định nghĩa biến 'ứng dụng' là,

var app = express(); 

Vì vậy, chúng tôi sử dụng 'yêu cầu' với 'CommonJS' và 'nhập' với 'ES6'.

Để biết thêm thông tin về 'yêu cầu' & 'nhập', hãy đọc qua các liên kết bên dưới.

yêu cầu - Yêu cầu các mô-đun trong Node.js: Mọi thứ bạn cần biết

nhập - Cập nhật về các Mô-đun ES6 trong Node.js


3

Không phải là một câu trả lời ở đây và giống như một bình luận, xin lỗi nhưng tôi không thể bình luận.

Trong nút V10, bạn có thể sử dụng cờ --experimental-modulesđể báo cho Nodejs bạn muốn sử dụng import. Nhưng kịch bản nhập cảnh của bạn nên kết thúc bằng .mjs.

Lưu ý đây vẫn là một điều thử nghiệm và không nên được sử dụng trong sản xuất.

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

Tham chiếu 1 - Nodejs Đốc

Tham chiếu 2 - vấn đề github


3

ES6 mới:

'Nhập' nên được sử dụng với các từ khóa 'xuất' để chia sẻ biến / mảng / đối tượng giữa các tệp js:

export default myObject;

//....in another file

import myObject from './otherFile.js';

skool cũ:

'Yêu cầu' nên được sử dụng với 'module.exports'

 module.exports = myObject;

//....in another file

var myObject = require('./otherFile.js');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.