Giới thiệu về module ECMAScript mới trong Node v12
Nếu bạn đã quen thuộc với các framework frontend JavaScript phổ biến như React và Angular, thì khái niệm ECMAScript sẽ không hoàn toàn mới đối với bạn. Các module ES có cú phápimport
và export
mà ta thường thấy trong các khuôn khổ giao diện user . ** Node sử dụng CommonJS dựa vào request require()
để nhập. Bây giờ ta có thể sử dụng nhập và xuất trong Node ngoài require()
. Đó không phải là tất cả những gì đi kèm với bản phát hành Node v12 mới, hãy nói về tất cả các tính năng thú vị mới mà ta có thể mong đợi. Mô-đun ES mới
Trước đây, bản phát hành Node trước đó đã được xuất xưởng với hỗ trợ thử nghiệm cho các module ECMAScript . Sự hỗ trợ này nằm sau --experimental-modules
và vẫn còn, nhưng rất nhiều điều đã xảy ra kể từ bản phát hành cuối cùng và ta rất vui vì những gì sắp tới sẽ xảy ra. Ta biết thực tế rằng một số mối quan tâm và phản hồi nêu ra từ bản phát hành cuối cùng đã được xử lý và sẽ trở thành hiện thực trong bản phát hành tiếp theo.
Phản hồi nổi bật là Node.js cần cung cấp cách sử dụng cú pháp nhập và xuất trong file .js
. Trong --experimental-modules
, hai cách được cung cấp cho bạn:
- Đặt
“type” : “module”
trongpackage.json
// package.json { "type": "module" }
Điều này yêu cầu Node.js coi tất cả các file .js
trong dự án của bạn là Mô-đun ES. Nếu bạn vẫn có các file CommonJS mà bạn không muốn coi là module , bạn có thể đổi tên chúng bằng phần mở rộng file .cjs
, phần mở rộng này sẽ yêu cầu Node.js phân tích cú pháp chúng thành CommonJS một cách rõ ràng. Ngoài ra, bạn có thể đặt tất cả các file CommonJS của bạn trong một folder con chứa file package.json
với "type":"commonjs"
, trong đó tất cả các file .js
được coi là CommonJS.
Nếu file cha mẹ package.json gần nhất thiếu trường
type
hoặc chứa"type": "commonjs"
, các file không có đuôi và .js được coi là CommonJS. Nếu đạt đến ổ đĩa root và không tìm thấy package.json, Node.js định nghĩa thành mặc định, một package.json không có trường"type" field.import
lệnh nhập của .js và file không có đuôi được coi là module ES nếu file cha gần nhất package.json chứa"type": "module"
.
Bạn có thể nghĩ về loại và phạm vi mở rộng này như cách hoạt động của thứ tự ưu tiên CSS, nó phân tầng cây từ con lên đến root .
- Sử dụng
--input-type flag
“` bash node –experimental-modules –input-type = module –eval \ "import {sep} from 'path'; console.log (sep);”
echo “nhập {sep} từ 'path'; console.log (sep); ” | \
node –experimental-modules –input-type = module
The second way of using the import and export syntax is to use `--input-type=module` to run string input (via `--eval`, `--print`, or `STDIN`) as an ES module. The `--input-type` flag can be either `--input-type=module` or `--input-type=commonjs`. In our case, it’ll be the earlier since we are setting it to modules, not CommonJS. ## More expected WIP features Given that the Node.js Modules team are still working on these features, we can’t exactly report them as existing features. Why? they are still being worked on so they are all probably still going to change, however, we have an idea of what they are and how they are likely to behave. ## Module Loaders The Very WIP feature. Though the first implementation of the `--loader` API has shipped, it's still being worked on hence, it is still subject to changes in the next release. ## Package path maps This feature has not shipped yet. It would redefine how we make module imports and allow for less verbose imports in certain situations. ## Automatic entry point module type detection This feature will make it possible for Node to identify the type of module we have present in our projects. When shipped, it will be possible for Node to know if a particular module is an ES Module or a CommonJS Module. There are so many other new features in Node v12, feel free to dig deeper in the official blog post by [the Modules Team](https://medium.com/@nodejs/announcing-a-new-experimental-modules-1be8d2d6c2ff) on Medium. But in the meantime, let’s take a closer look at the types of modules we have in Node. ## Different Types of Modules in Node This might look obvious at this point but i have come to understand with experience that most people have troubles understanding the different types of modules we have in Node. Given that until recently, all we needed in Node is the CommonJS syntax, it’s understandable that a few people find it confusing. There are two module types in Node. 1. The CommonJS Module type 1. The ES Module type ###CommonJS Module The CommonJS Module is the default module that comes with Node. Before the inception of the ES Modules, every Node application works with the CommonJS module construct that uses the `require()` and `module.exports` syntax to pull in modules and export them. Consider this example: ```javascript //src/main.js var products = require('src/products'); // import module
Ở đây, ta vừa nhập một module products
vào file main.js
từ một file khác trong folder src
của ứng dụng của ta . Ta có thể tiếp tục và sử dụng module trong file hiện tại nếu ta muốn. Sao có thể như thế được? Bởi vì chức năng products
được đặt thành đối tượng xuất khẩu trong file src/products
theo đặc tả CommonJS.
//src/products.js exports = function(){ return response.get('all-products); }
Triển khai Node.js
Việc triển khai Node.js không khác quá nhiều so với những gì ta vừa thấy ở trên từ CommonJS. Sự khác biệt là ở cách các module được xuất từ các file server của chúng. Trong khi CommonJS xuất module với biến exports
, module Node sử dụng đối tượng module.exports
.
//src/products function products(){ return response.get('all-products); } modules.exports = products;
Cũng giống như việc triển khai CommonJS, đây là một quá trình đồng bộ không kém vì các file được tải lần lượt theo thứ tự xuất hiện bên trong file .
Mô-đun ES
Mô-đun ES có thể được coi là một cải tiến trên hệ thống module CommonJS. Nó cung cấp khả năng nhập và xuất các module chỉ bằng cách sử dụng các từ khóa import
và export
để thay thế cho các require
trong CommonJS. Không giống như CommonJS, các module ES tương thích với cả chế độ hoạt động đồng bộ và không đồng bộ.
Xem xét ví dụ về sản phẩm mà ta đã thấy với CommonJS trong các ví dụ trước ở trên, ta có thể làm lại file với Mô-đun ES như sau:
//src/main.js import products from 'src/products'
Như ta đã giải thích trước đây, câu lệnh import
được sử dụng để đưa các module vào không gian tên. Nó hoạt động gần như chính xác như yêu cầu thay thế trong CommonJS nhưng nó không động, do đó, bạn không thể sử dụng nó ở bất kỳ đâu trong file . , ta có thể nhập file này để sử dụng ở đây vì file có thể đã được xuất từ file server của nó.
//src/products.js export function products() { return response.get('all-products); }
Câu lệnh export
ở đây giúp bạn có thể truy cập hàm này từ file khác. Nói một cách đơn giản, nó làm cho chức năng có thể truy cập rộng rãi. Do đó, các bộ phân tích tĩnh trước tiên sẽ xây dựng cây phụ thuộc trong khi đóng gói file trước khi cuối cùng chạy mã. Theo tôi, đây là một lợi thế lớn của việc sử dụng Mô-đun ES.
ESM trong Node trong quá khứ
Khái niệm Mô-đun ES trong Node không hẳn là mới, nó đã có từ năm 2017 khi Node.js 8.9.0 vận chuyển hỗ trợ thử nghiệm cho các module ECMAScript , được biết đến với các câu lệnh nhập và xuất đằng sau --experimental-modules
.
Tuy nhiên, cho đến thời điểm này, tính năng này vẫn ở trạng thái thử nghiệm. Lý do? để cho phép cộng đồng Node.js có thời gian sử dụng nó và cung cấp phản hồi hữu ích về thiết kế đó. Kể từ đó, rất nhiều điều đã xảy ra. Các trình duyệt chính hiện hỗ trợ module ECMAScript (mô-đun ES) thông qua <script type="module">
. Các gói npm với nguồn module ES hiện có sẵn để sử dụng trong các trình duyệt thông qua <script type="module">
. Hỗ trợ nhập bản đồ , mang đến cho trình duyệt tên gói kiểu Node.js trong câu lệnh import
, sắp có mặt trên Chrome . Và rất nhiều thứ khác nữa.
Đã chờ đợi một thời gian dài, nhận được phản hồi về thiết kế ESM thử nghiệm và do có những thời gian chạy và môi trường khác mà các module ES đang được sử dụng, không có thời gian nào tốt hơn để Node.js hỗ trợ tiêu chuẩn ESM JavaScript này hơn bây giờ. Và đây là lý do tại sao Group Mô-đun đã công bố một triển khai mới để hỗ trợ các module ES. Theo họ, nó sẽ xuất xưởng như một phần của Node.js 12 và sẽ thay thế việc triển khai --experimental-modules
cũ, đằng sau cùng một lá cờ.
Bắt đầu với v12 bằng nvm
Trong khi chờ đợi sự hỗ trợ lâu dài cho ESM, ta có thể bắt đầu làm quen với các hoạt động và tính năng của nó bằng cách sử dụng nvm. nvm cho phép bạn cài đặt nhiều version nút trên một máy và chuyển đổi giữa chúng khi bạn cần.
Điều này nghĩa là , mặc dù bạn hiện đang chạy Node v6 hoặc v10 bất kỳ version nào, bạn có thể chuyển đổi lên version mới nhất hoặc version cũ hơn và thử mọi thứ trong khi vẫn giữ nguyên version và file hiện tại của bạn.
Tôi rất muốn giới thiệu cách bạn có thể cài đặt nvm và sử dụng nó để quản lý các version Node của bạn để thử các tính năng khác nhau chưa tồn tại trong version hiện tại của bạn nhưng Michael Wanyoike đã làm rất tốt điều đó trên bài đăng này trên Sitepoint . Nếu bạn muốn tìm hiểu cách nvm hoạt động trên các nền tảng OSS khác nhau, hãy ghé thăm bài đăng.
Sử dụng Cờ —experimental-module để hỗ trợ nhập cho đến khi LTS
Giống như ta đã đề cập trước đó trong bài đăng này, Mô-đun ES đã xuất hiện được một thời gian và có hai cách ta có thể sử dụng chúng cho đến khi LTS.
-
node index.js --experimental-modules
-
node --experimental-modules index.js
Thật không may, cách đầu tiên tức là sử dụng node index.js --experimental-modules
không hoạt động, do đó, để hỗ trợ nhập ESM trong các ứng dụng Node của bạn, bạn sẽ phải sử dụng tùy chọn thứ hai ở trên.
Nhập động sẽ không còn ở đâu
Cần lưu ý nhập khẩu động không chịu bất kỳ mối đe dọa nào từ việc triển khai Mô-đun ES sắp tới. Trước kỷ nguyên ESM này, nhập động cung cấp cho ta khả năng nhập và sử dụng động các module từ các vị trí khác nhau trong ứng dụng của ta .
Giả sử rằng nhập động trả về một lời hứa cho đối tượng không gian tên module của module được yêu cầu, có thể sử dụng async/await
và kiểu gọi lại dựa trên .then()
để xử lý tất cả các hành vi của module để có thể tải module không đồng bộ. Đây là lý do tại sao tất cả ta đều yêu thích nó và thật là một tin tốt khi biết rằng ta sẽ không đánh mất nó trước các triển khai mới.
Nhập file JSON thì sao?
Hiện tại, việc nhập module JSON chưa được hỗ trợ trong chế độ module
. Tuy nhiên, nó được hỗ trợ trong chế độ commonjs
và là bộ nạp với bộ nạp CJS. Điều đó nói rằng, các nỗ lực hiện đang được thực hiện đảm bảo rằng việc nhập JSON được hỗ trợ trong chế độ module
. Ví dụ: tại thời điểm hiện tại, các module WHATWG JSON hiện đang được chuẩn hóa và được hỗ trợ thử nghiệm bằng cách bao gồm cờ bổ sung --experimental-json-modules
khi chạy Node.js.
Mặc dù việc nhập JSON được hỗ trợ ngoài hộp ở chế độ commonjs
, khi --experimental-json-modules
được bao gồm, cả commonjs
và chế độ module
sẽ sử dụng trình tải JSON thử nghiệm mới.
Tuy nhiên, có một chút hạn chế, JSON được nhập chỉ để lộ default
, vì vậy hiện tại không có hỗ trợ cho các xuất có tên. Vì trình tải JSON thử nghiệm cũng được ưu tiên hơn chế độ commonjs
, một mục nhập bộ nhớ cache riêng được tạo trong cache ẩn CommonJS, để tránh trùng lặp. Đối tượng tương tự sẽ được trả về trong CommonJS nếu module JSON đã được nhập từ cùng một đường dẫn. Hãy xem xét ví dụ dưới đây:
import productsConfif from './package.json';
Để điều này thực sự hoạt động, ta cần cập nhật
node --experimental-modules index.js
đến
node --experimental-modules --entry-type=module --experimental-json-modules index.js
Càng sớm sẽ không thành công vì không có sẵn --experimental-json-modules
.
Lời kết
Đã có quá nhiều lời bàn tán xung quanh Mô-đun EcmaScript mới sắp có mặt trên Node.js v12. Trong bài viết này, ta đã xem xét kỹ hơn nó để hiểu những gì nó cung cấp so với giải pháp thay thế CommonJS thông thường.
Các tin liên quan