NodeJS có kế hoạch hỗ trợ các mô-đun nhập / xuất es6 (es2015)


275

Tôi đã tìm kiếm trên internet mà không có câu trả lời rõ ràng cho việc này.

Hiện tại NodeJS chỉ sử dụng cú pháp CommonJS để tải các mô-đun và nếu bạn thực sự muốn sử dụng cú pháp mô-đun ES2015 tiêu chuẩn, bạn phải dịch mã nó trước hoặc sử dụng trình tải mô-đun bên ngoài khi chạy.

Hiện tại tôi không quá tích cực để sử dụng một trong hai phương pháp đó, các nhà bảo trì NodeJS thậm chí có kế hoạch hỗ trợ các mô-đun ES2015 hay không? Tôi chưa tìm thấy một gợi ý nào về việc này.

Hiện tại, NodeJS 6.x tuyên bố hỗ trợ 96% các tính năng ES2015, nhưng không có bất kỳ tham chiếu nào đến các mô-đun ( liên kết hỗ trợ NodeJS ES2105 ).

Bạn có biết nếu NodeJS sẽ hỗ trợ các mô-đun này ra khỏi hộp trong tương lai gần không?


2
Googling cho node es2015 modules, hiển thị như sau là một trong những kết quả hàng đầu: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Felix Kling

6
Cá nhân tôi sẽ bỏ phiếu để đóng câu hỏi này là "quá cục bộ", nhưng lý do gần gũi đó không còn tồn tại nữa. Giả sử Node quản lý để thực hiện các mô-đun ES6 vào ngày mai. Bạn sẽ xóa câu hỏi của bạn sau đó, bởi vì nó không còn phù hợp nữa? Hoặc ít nhất bạn sẽ cập nhật nó? Tôi không nghĩ rằng một câu hỏi phù hợp với SO nếu bạn đã biết rằng nó sẽ bị lỗi thời hoặc cần được cập nhật "sớm". Nhưng đó chỉ là ý kiến ​​của tôi và dường như có những người khác nghĩ ngược lại, điều đó cũng ổn đối với tôi :) (fwiw, bản thân câu hỏi tất nhiên là quan trọng và thú vị)
Felix Kling

2
Dù vậy, tôi ước có một vị trí trong Stack Universe cho những câu hỏi như thế này. Nó có thể không phù hợp về mặt kỹ thuật ở đây, nhưng tôi không biết rằng tôi đồng ý rằng nó thực sự "dựa trên ý kiến". OP đang tìm kiếm một câu trả lời cụ thể cho một câu hỏi cụ thể, nhưng một câu hỏi sẽ bị lỗi thời (tại một số điểm).
Wonko the Sane

5
Phrasing thay thế của câu hỏi này: "Trạng thái của node.js hỗ trợ cho các mô-đun ES6 là gì?" Câu trả lời cho nhiều câu hỏi SO thay đổi theo thời gian khi công nghệ phát triển. Tôi cũng gặp khó khăn khi tìm câu trả lời cho đến khi tôi hạ cánh ở đây.
Joe Lapp

4
@FelixKling Tôi đoán bạn muốn đóng câu hỏi này sẽ là một quyết định rất sai lầm vì đó là vấn đề 211 người cho đến nay thấy có vấn đề đủ để bỏ phiếu.
Muhammad Umer

Câu trả lời:


302

Nút 13.2.0 trở lên

NodeJS 13.2.0 hiện hỗ trợ các Mô-đun ES không có cờ 🎉 Tuy nhiên, việc triển khai vẫn được đánh dấu là thử nghiệm vì vậy hãy thận trọng khi sử dụng trong sản xuất.

Để bật hỗ trợ ESM trong 13.2.0, hãy thêm các mục sau vào package.json:

{
  "type": "module"
}

Tất cả .js, .mjs(hoặc các tệp không có phần mở rộng) sẽ được coi là ESM.

Có một số tùy chọn khác nhau ngoài toàn bộ tùy chọn package.json, tất cả đều được nêu chi tiết trong Tài liệu cho 13.2.0 .

Nút 13.1.0 trở xuống

Những người vẫn đang sử dụng các phiên bản cũ hơn của Node có thể muốn thử trình tải mô-đun esm , đây là một triển khai sẵn sàng sản xuất của Mô-đun ES Spec cho NodeJS:

node -r esm main.js

Cập nhật chi tiết ...

23 tháng 4 năm 2019

Một PR gần đây đã hạ cánh để thay đổi cách phát hiện Mô-đun ES: https://github.com/nodejs/node/pull/26745

Nó vẫn ở phía sau --experimental-modulescờ, nhưng có những thay đổi lớn trong cách các mô-đun có thể được tải:

  • package.typeđó có thể là modulehoặccommonjs
    • type: "commonjs":
      • .js được phân tích cú pháp như commonjs
      • mặc định cho điểm vào mà không có phần mở rộng là commonjs
    • type: "module":
      • .js được phân tích cú pháp như esm
      • không hỗ trợ tải JSON hoặc Module tự nhiên theo mặc định
      • mặc định cho điểm vào mà không có phần mở rộng là esm
  • --type=[mode]để cho phép bạn đặt loại trên điểm vào. Sẽ ghi đè package.typecho điểm vào.
  • Một phần mở rộng tập tin mới .cjs.
    • điều này đặc biệt để hỗ trợ nhập commonjs trong modulechế độ.
    • đây chỉ là trong trình tải esm, trình tải chungj vẫn chưa được xử lý, nhưng phần mở rộng sẽ hoạt động trong trình tải cũ nếu bạn sử dụng đường dẫn tệp đầy đủ.
  • --es-module-specifier-resolution=[type]
    • tùy chọn là explicit(mặc định) vànode
    • theo mặc định, trình tải của chúng tôi sẽ không cho phép các tiện ích mở rộng tùy chọn trong quá trình nhập, đường dẫn cho mô-đun phải bao gồm tiện ích mở rộng nếu có
    • theo mặc định, trình tải của chúng tôi sẽ không cho phép nhập các thư mục có tệp chỉ mục
    • các nhà phát triển có thể sử dụng --es-module-specifier-resolution=nodeđể kích hoạt thuật toán phân giải chỉ định chung
    • Đây không phải là một tính năng của người Viking mà là một triển khai để thử nghiệm. Dự kiến ​​sẽ thay đổi trước khi cờ được gỡ bỏ
  • --experimental-json-loader
    • Cách duy nhất để nhập json khi "type": "module"
    • khi bật tất cả import 'thing.json'sẽ đi qua trình tải thử nghiệm độc lập với chế độ
    • dựa trên whatwg / html # 4315
  • Bạn có thể sử dụng package.mainđể đặt điểm vào cho mô-đun
    • phần mở rộng tập tin được sử dụng trong chính sẽ được giải quyết dựa trên loại mô-đun

17 tháng 1 năm 2019

Nút 11.6.0 vẫn liệt kê các Mô-đun ES là thử nghiệm, đằng sau một cờ.

Ngày 13 tháng 9 năm 2017

NodeJS 8.5.0 đã được phát hành với sự hỗ trợ cho các tệp mjs phía sau một cờ:

node --experimental-modules index.mjs

Kế hoạch cho việc này là xóa cờ cho bản phát hành L10 v10.0.

- Thông tin bổ sung. Giữ ở đây cho các mục đích lịch sử--

Ngày 8 tháng 9 năm 2017

Chi nhánh chính của NodeJS đã được cập nhật với sự hỗ trợ ban đầu cho các mô-đun ESM:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

Điều này sẽ có sẵn trong đêm mới nhất (điều này có thể được cài đặt qua nvm để chạy cùng với cài đặt hiện tại của bạn):
https://nodejs.org/doad/nightly/

Và được bật phía sau --experimental-modulescờ:

pack.json

{
  "name": "testing-mjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs" <-- Set this to be an mjs file
}

Sau đó chạy:

node --experimental-modules .

Tháng 2 năm 2017:

https://medium.com/@jasnell/an-update-on-es6-modules-in-node-js-42c958b890c#.6ye7mtn37

Các anh chàng NodeJS đã quyết định rằng giải pháp ít tệ nhất là sử dụng .mjsphần mở rộng tập tin. Điểm nổi bật của việc này là:

Nói cách khác, được cung cấp hai tệp foo.jsbar.mjs, sử dụng import * from 'foo'sẽ coi foo.jslà CommonJS trong khi import * from 'bar' sẽ coi bar.mjslà Mô-đun ES6

Và đối với các mốc thời gian ...

Tại thời điểm hiện tại, vẫn còn một số vấn đề về đặc tả và triển khai cần phải xảy ra ở phía ES6 và Máy ảo trước khi Node.js thậm chí có thể bắt đầu triển khai các mô-đun ES6 có thể hỗ trợ. Công việc đang được tiến hành nhưng sẽ mất một thời gian - Hiện tại chúng tôi đang xem xét ít nhất là khoảng một năm .

Tháng 10 năm 2016:

Một trong những nhà phát triển trên Node.JS gần đây đã tham dự một cuộc họp TC-39 và đã viết một bài viết tuyệt vời về các trình chặn để triển khai cho Node.JS:

https://hackernoon.com/node-js-tc-39-and-modules-a1118aecf95e

Cơ bản mang đi từ đó là:

  • Các mô-đun ES được phân tích tĩnh, CommonJS được đánh giá
  • Các mô-đun CommonJS cho phép xuất khẩu bản vá khỉ, Mô-đun ES hiện không
  • Thật khó để phát hiện Mô-đun ES là gì và CommonJS là gì nếu không có một số dạng đầu vào của người dùng, nhưng họ đang thử.
  • *.mjs dường như là giải pháp khả thi nhất, trừ khi họ có thể phát hiện chính xác Mô-đun ES mà không cần đầu vào của người dùng

- Câu trả lời gốc -

Đây là một củ khoai tây nóng trong một thời gian khá dài. Điểm mấu chốt là có, cuối cùng Node sẽ hỗ trợ cú pháp ES2015 để nhập / xuất các mô-đun - rất có thể khi thông số kỹ thuật cho việc tải các mô-đun được hoàn tất và đồng ý.

Dưới đây là một tổng quan tốt về những gì giữ NodeJS lên. Về cơ bản, họ cần đảm bảo rằng thông số kỹ thuật mới hoạt động cho Node, chủ yếu có điều kiện, tải đồng bộ và cả HTML mà chủ yếu là không đồng bộ.

Không ai biết chắc chắn ngay bây giờ, nhưng tôi tưởng tượng Node sẽ hỗ trợ import/exporttải tĩnh, ngoài ra mới System.importcho tải động - trong khi vẫn giữ requiremã kế thừa.

Dưới đây là một vài đề xuất về cách Node có thể đạt được điều này:


38
Về .mjsphần mở rộng : We have affectionately called these “Michael Jackson Script” files in the past. Chỉ trong trường hợp bạn nghe ai đó nói về các nghệ sĩ nhạc pop trong buổi nói chuyện về JS.
Jeewes

1
Tôi không thấy lý do tại sao thay đổi cú pháp nhập không đủ. Một cú pháp để nhập es (một 'chính xác') và một cú pháp để nhập cjs? Nói cách khác, được cung cấp hai tệp foo.js và bar.js, import * from 'foo'sẽ coi foo.js vì CommonJS import * as bar from 'bar'sẽ coi bar.js là Mô-đun ES6 Ai đó có thể giải thích?
Corey Alix

1
@CoreyAlix Cú pháp thường không được thay đổi để hỗ trợ môi trường. Điều này thực sự chỉ ảnh hưởng đến Node sau tất cả. Ngoài ra, cú pháp là một chút không trực quan. Làm cách nào để truy cập vào xuất khẩu theo cú pháp đề xuất của bạn?
Mã hóa

Để rõ ràng, đó không phải là đề xuất "của tôi", tôi đang sao chép những gì bản thảo đang làm. Để trả lời câu hỏi của bạn, bạn truy cập vào bản xuất bằng "bar": bar.foobar () nhập {foo dưới dạng Foo} từ Hồi ./foo tựa là cơ chế xác định mô-đun ES6. var Foo = Yêu cầu (thời gian ./ foo) là cơ chế để xác định mô-đun CJS. Trong Bản mô tả, đầu ra commonjs trông như thế này: var mod1_1 = quiries ("./ mod1"); export.mod1 = mod1; Đầu ra ES6 trông như thế này: nhập {mod1} từ trên. xuất {mod1}
Corey Alix

1
Tôi sẽ thực sự thú vị trong bản cập nhật Node 10 cho câu trả lời này. Có phải tính năng này đã bị cắt, hay nó vẫn ở phía sau một lá cờ?
dcorking
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.