nodejs / nodejs/node

import(cjs) and require(cjs) share a cache

Đang mở
#49,453 7 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
JavaScript
Star
122k
Fork
37.3k
Merge trung bình
4 ngày 2 giờ
Pull request đã merge (30 ngày)
283

Mô tả

Hiya! 👋

This might very well be on purpose, and if so feel free to close this issue.

For background, I'm currently working on ESM support in Jest. We implement our own resolution and module loading (including caching), so I'm writing some tests to try to make sure our semantics matches node's semantics.

I wrote the following test:

// stateful.cjs
'use strict';

let num = 0;

module.exports = function inc() {
  num++;
  return num;
};
// test.mjs
import * as assert from 'assert';
import {createRequire} from 'module';

async function main() {
  const require = createRequire(import.meta.url);

  const requiredStateful = require('./stateful.cjs');
  // delete require.cache[require.resolve('./stateful.cjs')];
  const {default: importedStateful} = await import('./stateful.cjs');

  assert.equal(importedStateful(), 1);
  assert.equal(importedStateful(), 2);
  assert.equal(requiredStateful(), 1);
  assert.equal(importedStateful(), 3);
  assert.equal(requiredStateful(), 2);
  assert.equal(requiredStateful(), 3);
}

main().catch(err => {
  process.exitCode = 1;

  console.error(err);
});

However, this test fails because the numbers are 1, 2, 3, 4, 5, 6, e.g. they share the same module rather than having their own.

I assumed that the module cache of require and import() would not be shared, based on

require.cache is not used by import. It has a separate cache.

From https://nodejs.org/api/esm.html#esm_no_require_cache

Note that if I swap the order from require then import to import then require (and uncomment the delete), the test behaves like I expect.

So doing import(cjs) populates require.cache which means require(cjs) loads the cached module, and require(cjs) populates the cache so import(cjs) reads it, but doing delete require.cache only affect require, not import.

If import populates and reads from require.cache, I'd expect it do respect deletions from that same property. What I would expect from reading the docs is that import would neither populate nor read from require.cache.

I ran these tests with no flags, using node v13.12.0.


Again, this might be expected behavior, and if so I'd be happy to provide a PR with a docs change specifying this. As a user I find it quite confusing, though

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với phần tài liệu ESM về bộ nhớ đệm require.cache riêng biệt và tái hiện các ví dụ test.mjs và stateful.cjs của issue trên một phiên bản Node.js hiện tại. Xác nhận mối quan hệ được quan sát giữa import(), require() và require.cache, sau đó ghi lại hành vi dự kiến và ngữ nghĩa xóa nếu hành vi này là đúng như dự kiến.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript, node.js
Lĩnh vực
documentation
Loại issue
Tài liệu
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
48/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.