简体   繁体   中英

How to import from nested module?

I have a Typescript library I've written which is being emitted as follows. I'm not sure how to import from this module, though.

node_modules/my-module/dist/index.js (partial)

define("services/UserService", ["require", "exports", ..., "services/BaseService"], function (require, exports, ..., BaseService_31) {
    "use strict";
    var UserService = (function (_super) {
        // ... stuff here ...

        return UserService;
    }(BaseService_31.BaseService));
    exports.UserService = UserService;
});

I've installed this package with npm and configured JSPM as follows:

config.js (partial)

System.config({
  defaultJSExtensions: true,
  transpiler: "none",
  paths: {
    "*": "dist/*",
    "github:*": "jspm_packages/github/*",
    "npm:*": "jspm_packages/npm/*",
    "npm-ext:*": "node_modules/*"
  },
  map: {
    ...
    "my-module": "npm-ext:my-module/dist/index.js",
    ...
  }
});

I was expecting to be able to import this class as follows...

import {UserService} from "my-module/services/UserService";

I expected SystemJS to resolve the path to my-module and then locate the services/UserService module, and grab the single export UserService . But in the Chrome Console I see this is the path which is being loaded:

node_modules/my-module/dist/index.js/models/UserService.js

What's the correct way to import a module such as this?

Bonus: how can I get around including the full path to index.js ?

Your library code was emitted using named define

define("services/UserService",

And it looks like there are several such modules defined in the index.js file, that is, index.js is a bundle.

The only way to import such module using SystemJS is

import {UserService} from "services/UserService";

That is, imported module name must match exactly the name given to define . In your case, the location of the file does not affect module name in any way.

Now, SystemJS has to be configured to load library file, node_modules/my-module/dist/index.js , when it sees that import. For bundles, the preferred way to to it is via bundles config :

  bundles: {
    "npm-ext:my-module/dist/index.js": ["services/UserService.js"]
  }

Module name here, services/UserService.js , must have .js extension because it must match imported module name after defaultJSExtesions:true is applied.

If you want the module to be imported as my-module/services/UserService.js , then you need to make sure it is registered with that name. The easiest way is to have corresponding source file structure when compiling the library - that is, have UserService.ts in my-module/services folder.

You can find more information about named define in SystemJS module format docs , which says in particular

  • Named defines are supported and will write directly into the loader registry.

  • A single named define will write into the loader registry but also be treated as the value of the module loaded if the names do not match. This enables loading a module containing define('jquery', ....

PS Your browser tries to load

node_modules/my-module/dist/index.js/models/UserService.js

where does models come from?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM