DEV Community

Discussion on: Adding URL Search Parameters to Imports!

Collapse
 
prantlf profile image
Ferdinand Prantl • Edited

I use it in my test harness to create a named test suite by a single import line. Instead of the usual importing index.min.mjs and calling the test suite factory:

import tehanu from './node_modules/tehanu/dist/index.min.mjs'

const test = tehanu('sum')
Enter fullscreen mode Exit fullscreen mode

I can import suite.min.mjs which recognises the URL parameter name, creates a test suite with the name and exports it:

import test from './node_modules/tehanu/dist/suite.min.mjs?name=sum'
Enter fullscreen mode Exit fullscreen mode

It's a pity that this works only in browsers. Node.js doesn't separate the URL parameters from the file path, which leads to an invalid script path, if they are attached:

❯ node 'lib/index.mjs'
no suites

❯ node 'lib/index.mjs?test'
node:internal/modules/cjs/loader:936
  throw err;
  ^
Error: Cannot find module '/.../tehanu/packages/teru/lib/index.mjs?test'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}
Enter fullscreen mode Exit fullscreen mode

This has probably a consequence that the URL parameters can't be used in subpackages either. If a library exposes a subpackage suite, for example:

{
  "exports": {
    ".": {
      "require": "./lib/index.cjs",
      "import": "./lib/index.mjs"
    },
    "./suite": "./lib/suite.mjs"
  }
}
Enter fullscreen mode Exit fullscreen mode

it has to be used as-is:

import test from 'tehanu/suite'
Enter fullscreen mode Exit fullscreen mode

instead of the desired:

import test from 'tehanu/suite?name=sum'
Enter fullscreen mode Exit fullscreen mode

which fails:

❯ node lib/index.mjs test/index.mjs
node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './suite?name=sum' is not defined by "exports" in /.../tehanu/packages/teru/node_modules/tehanu/package.json imported from /.../tehanu/packages/teru/test/index.mjs
    at new NodeError (node:internal/errors:372:5)
    at throwExportsNotFound (node:internal/modules/esm/resolve:472:9)
    at packageExportsResolve (node:internal/modules/esm/resolve:753:3)
    at packageResolve (node:internal/modules/esm/resolve:935:14)
    at moduleResolve (node:internal/modules/esm/resolve:1003:20)
    at defaultResolve (node:internal/modules/esm/resolve:1218:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:580:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:294:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
    at link (node:internal/modules/esm/module_job:78:36) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}
Enter fullscreen mode Exit fullscreen mode

Related:

Collapse
 
lioness100 profile image
Lioness100

WOW! I never thought of that use case, and your findings are really interesting! Thank you so much!! ♥️♥️