Alexander Mills
Alexander Mills

Reputation: 99970

Dynamically reference static ESNext imports

Say I have these imports:

import clearLineReporter from '../modules/clear-line-reporter';
import karmaReporter from '../modules/karma-reporter';
import metaTestReporter from '../modules/meta-test-reporter';
import stdReporter from '../modules/std-reporter';
import tapJSONReporter from '../modules/tap-json-reporter';
import tapReporter from '../modules/tap-reporter';
import webSocketReporter from '../modules/websocket-reporter';

these must be referenced like I do above, in other words, I obviously can't do this:

const imports = {
     stdReporter: import(...),
     tapJSONReporter: import(...),
     ...
     webSocketReporter: import(...)
}

Is there any way I can reference imported files through some form of reflection? Because it seems like I can't group them together to reference them somehow.

Instead of import syntax, I could use require(), but I am wondering if there is some way I can do some dynamic things with import statements, for example reference them all dynamically, such that if I add or remove an import, I don't have to change any other code.

Upvotes: 1

Views: 543

Answers (2)

Alexander Mills
Alexander Mills

Reputation: 99970

There is a great answer to this question that I discovered by asking a different question, here:

exporting imports as a namespace with TypeScript

Create a file name grouped-modules.ts for example, where you want to simply list only the modules and export each one.

export {default as clearLineReporter} from '../modules/clear-line-reporter';
export {default as karmaReporter} from '../modules/karma-reporter';
export {default as metaTestReporter} from '../modules/meta-test-reporter';
...
export {default as stdReporter} from '../modules/std-reporter';
export {default as tapJSONReporter} from '../modules/tap-json-reporter';

Then in your module you can just do :

import * as mods from './grouped-modules'

export {mods}

It will export both types and values in a namespace called s. You can then import them using :

import {mods} from 'your-module'

const anObject: mods.clearLineReporter = ...;

This allows you to dynamically group your modules into one variable.

Upvotes: 2

Vladislav Ihost
Vladislav Ihost

Reputation: 2187

Is there any way I can reference imported files through some form of reflection?

Answer is dependent on environment, meant in questing, because import statement can be ES native modules implementation in browser, or babel-ed to require statements in node.js, or compile-time resolved bindings in webpack.

So, in each case there is solution to do something reflection. In node.js with babel-ed code import is just require wrapper, so any information is available there.

In browser with native ES modules, all requests to them can be served via ServiceWorker, so it can provide necessary information about fetched ES modules. Also in browser ES modules can be dynamically imported that way: https://matthewphillips.info/posts/loading-app-with-script-module

Most interesting part is webpack: compile-time resolve and semi-reflection can be achieved by externals resolver in functional style (https://webpack.js.org/configuration/externals/#function), and runtime by load module API (https://webpack.js.org/api/module-variables/#webpack_modules-webpack-specific- )

Upvotes: 1

Related Questions