TypeScript: import module with only statements

2019-04-28 00:52发布

问题:

I have a page-a.ts which would compile into page-a.js:

alert('this is from page-a');

And I have a main.ts which compiles into main.js:

import pageA = module('page-a')
alert('this is from main');

And this is my tsc command line:

tsc --module amd page-a.ts main.ts

And I'm using requirejs like this:

<script src="require.js" data-main="main.js"></script>

I can't see the alert messagebox from page-a when loading the page. And in the generated scripts main.js, there is nothing about page-a.

My question is, why is this happening? And how do I force typescript to import a module that is not explicitly used by the code?

回答1:

Your generated js will not import a module not explicitly used in code. Typescript is clever that way and will not generate any js for a module that is only imported and not used.

You need to :

  • export a variable in the first module AND
  • import the first module in the second module AND
  • Use the exported variable in the second module

so have page-a.js something like:

export var x = 123; // just to export something that you can use
alert('this is from page-a');

and main.ts as :

import pageA = module('page-a')
var foo = pageA.x; // If you remove this line and you will not get the alert from page-a
alert('this is from main');


回答2:

There are two other ways besides the one mentioned by @basarat to ensure that the imported module is included in the define function and thus loaded.

Include the amd-dependency element at the top of your TypeScript file.

///<amd-dependency path="pathToFileRelativeToBaseWithoutFileExtension"/>

or

import moduleName = require("pathToFileRelativeToBaseWithoutFileExtension");
moduleName;  //Does not require declaring a new variable.

The former is probably the one with the least chance of having side effects. Unfortunately, the element and its usage are not well documented.

I found these methods necessary when using lazy loading of AngularJS modules that create and register types to be dependency injected. Since the type is never created or assigned as far as the TS compiler is concerned, it does not create the necessary parameter for the define function.

They say this is by design (https://typescript.codeplex.com/workitem/2436) but I respectfully disagree. If I have imported a module/file and I have a reference to a concrete type in that module, then that module must be loaded at that point to operate. Having to do extra steps is redundant.



回答3:

I know that I am late but here is another way to achieve this:
You can tell typescript to import a module just for the side effects by using:
import "path/to/external/module";
Though this is es6 syntax typescript will transform it into AMD require() when you pass --module amd to tsc and since it is only imported for side effects it will not get dropped.