16

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

Is it possible in Typescript to dynamically set the from path into a variable when importing?

Eg turn this:

import {HomeComponent} from './dashboard/home/home.component';

To something like this:

let hompageComponentPath = './dashboard/home/home.component';
import * from hompageComponentPath;
3
  • Have you tried that exact thing? Commented Nov 24, 2016 at 10:19
  • it was the first thing i did... :) "] ERROR in ./script/core/app.module.ts [1] (62,42): error TS1141: String literal expected." Commented Nov 24, 2016 at 10:36
  • Try this: declare var require: any; let hompageComponentPath = './dashboard/home/home.component'; let importedModule = require(hompageComponentPath ); Commented Nov 24, 2016 at 11:26

2 Answers 2

7

With the dynamic import proposal

There is a proposal for dynamic import in ECMAScript.

Since TypeScript 2.4, dynamic import expressions are available. Here is an example:

async function getZipFile(name: string, files: File[]): Promise<File> {
    const zipUtil = await import('./utils/create-zip-file');
    const zipContents = await zipUtil.getAsBlob(files);
    return new File(zipContents, name);
}

The import, used as a function, returns a promise which can be awaited.

... But not with the ES6 static import / export

It's not possible to do that with the syntax import / export because the ES6 standard had explicitly defined modules in a static way.

From the article ES6 In Depth: Modules:

For a dynamic language, JavaScript has gotten itself a surprisingly static module system.

  • All flavors of import and export are allowed only at toplevel in a module. There are no conditional imports or exports, and you can’t use import in function scope.
  • All exported identifiers must be explicitly exported by name in the source code. You can’t programmatically loop through an array and export a bunch of names in a data-driven way.
  • Module objects are frozen. There is no way to hack a new feature into a module object, polyfill style.
  • All of a module’s dependencies must be loaded, parsed, and linked eagerly, before any module code runs. There’s no syntax for an import that can be loaded lazily, on demand.
  • There is no error recovery for import errors. An app may have hundreds of modules in it, and if anything fails to load or link, nothing runs. You can’t import in a try/catch block. (The upside here is that because the system is so static, webpack can detect those errors for you at compile time.)
  • There is no hook allowing a module to run some code before its dependencies load. This means that modules have no control over how their dependencies are loaded.
Sign up to request clarification or add additional context in comments.

2 Comments

Actually there is newer proposal that's being worked on now: github.com/tc39/proposal-dynamic-import
dynamic import has been implemented. See import() - JavaScript | MDN
3

You can use import as a function and then pass any dynamically created string rather than a string literal.

This returns a Promise though so keep in mind that it needs to be run within an async function rather than at the very top of the file.

eg.

async main(): Promise<void> { 

        const  myData = await import(`../../data/${environment.theme}/chapters`);
        
        console.log({ myData });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.