systemjs / systemjs

Dynamic ES module loader

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[NodeJS] Should System.import('my-module') refetch if called twice?

tbrannam opened this issue · comments

temJS Version:

  • Which library are you using?
    • system.js
    • s.js
    • system-node.cjs
  • Which extras are you using?
    • AMD extra
    • Named Exports
    • Named Register
    • Transform
    • Use Default
    • Global
    • Dynamic Import Maps
  • Are you using any custom hooks?
const systemJSPrototype = globalSystem.constructor.prototype
const oldInstantiate = systemJSPrototype.instantiate
systemJSPrototype.instantiate = function (...args) {
  const [url, parent, meta] = args
  console.log(url, parent, meta)
  // handle node: imports
  if (url.startsWith('node:')) {
    const module = url.replace('node:', '')
    return [[], function (_export) {
      return {
        setters: [],
        execute: function () {
          _export('default', globalThis.require(module))
        },
      }
    }]
  }

  // fallback to default behavior
  return oldInstantiate.apply(this, args)
}


Question

Does system-node.cjs's System.import cache modules?

When using System.import within a node instance, I had expected multiple calls to System.import('my-module') to resolve fetch once for a given import-map entry. By adding logging the following logging to instantiate it seems to verify that fetching is occurring on every top level call to System.import. Which in turn seems to suggest that new instances of the module is also being created.

Is this the intent of the code? I had expected that System.import('x') would return a cached module 'x' for the given instance of SystemJS (global or System.contsructor())

The observed behavior is calling

System.import('my-module');

// next loop, another part of the code

System.import('my-module');

Will result in multiple 'did fetch' log messages, even if there was sufficient time to finish the fetch (i.e. it isn't a network race condition)

    systemJSPrototype.instantiate = function (url, parent, meta) {
      var loader = this;
      console.log('instantiate', url)
      if (!this.shouldFetch(url, parent, meta)) {
        console.log('should not fetch', url)
        return instantiate.apply(this, arguments);
      }
      return this.fetch(url, {
        credentials: 'same-origin',
        integrity: importMap.integrity[url],
        meta: meta,
      })
        .then(function (res) {
          console.log('did fetch', res)
    ....

It seems that the tests indicate that the assumption should be true - that the module returned is the same

const m1 = await loader.import('./register-modules/no-imports.js');

I will see if i can create a standalone test case

This is user error. My implementation is using NodeCache to manage multiple System instances... the default behavior of NodeCache is to clone the items cached. Adding { useClones: false } to the constructor of NodeCache fixes this issue.