2

I have been trying to create some components for internal company use to be shared via our private npm repository. However, when it comes to adding these via npm & systemjs to an app, I keep getting a TS2307 cannot find module exception.

I used the angular.io quickstart to create this simple test.

I have tried a variety name variations for the import statement and the systemjs 'map' and 'packages' sections, but cannot get the module to load as per @angular or rxjs, etc. When I look in node_modules the folder and files all exist.

Q: How do I successfully import this simple typescript module and avoid the TS2307 error?

package.json:

{
  ...
  "dependencies": {
    ...
    "@oval/angular2-demo-test": "^1.0.0"
  },
  "devDependencies": {
    ...
  }
}

systemjs.config.js:

(function (global) {
  System.config({
    ...
    map: {
      app: 'app',
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      ...
      '@oval/test': 'npm:@oval/angular2-demo-test'
    },
    packages: {
      ...
      '@oval/test': {
        defaultExtension: 'js'
      }
    }
});

app.module.ts:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import { Test } from '@oval/test';

@NgModule({
    imports: [BrowserModule],
    declarations: [
        AppComponent,
        Test
    ],
    bootstrap: [AppComponent]
})

export class AppModule { }

app.component.ts:

import { Component } from '@angular/core';
import { Test } from '@oval/test';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1><br/><test [value]="value"></test>'
})

export class AppComponent {
    value: string;

    constructor() {
        this.value = "result";
    }
}

console error:

app/app.component.ts(2,22): error TS2307: Cannot find module '@oval/test'.
app/app.module.ts(4,22): error TS2307: Cannot find module '@oval/test'.

Here are the variations I have used to try and import the module:

import { Test } from '@oval';
import { Test } from '@oval/angular2-demo-test';
import { Test } from '@oval/angular2-demo-test/test.js';
import { Test } from '@oval/test.js';
import { Test } from './node_modules/@oval/angular2-demo-test/test.js';
import { Test } from '../node_modules/@oval/angular2-demo-test/test.js'; // this worked, although it obviously is not a realistic resolution

in the systemjs.config.js file I have also tried all of these variations in the map with the above imports, I have also made multiple variations to the packages section too, none of which have solved the issue.:

'@oval/test': 'npm:@oval/angular2-demo-test'
'@oval': 'npm:@oval/angular2-demo-test'
'@oval': 'npm:@oval/angular2-demo-test/test.js'
'@oval/angular2-demo-test': 'npm:@oval/angular2-demo-test'
'@oval/angular2-demo-test': 'npm:@oval/angular2-demo-test/test.js'

the module I am trying to load look like this:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'test',
    template: '<div>Test value: {{value}}</div>'
})

export class Test {
    @Input() value: string;
}

the npm package that gets created includes:

  • test.ts
  • test.js
  • test.js.map
  • package.json
  • readme.md
  • node_modules/

I have also tried including a typings folder in the package but this makes no difference.

Thank you for your time.

tsconfig.json as requested:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}
4
  • have you tried to import from @oval/test/test ? your systemJS says that the defaultExtention is .js, so if you import @oval/test/test, it should import @oval/test/test.js Commented Sep 16, 2016 at 12:31
  • makes no difference. If my systemjs directs '@oval/tests' to the folder 'node_modules/@oval/angular2-demo-test' where the test.js file is I would expect the import @oval/test/test to do as you suggest but it still gives the error Commented Sep 16, 2016 at 13:36
  • Can you please add your tsconfig.json file? Commented Sep 16, 2016 at 13:45
  • Update: I have not found a resolution to the error message, but a work around involves trimming the npm start param to not run tsc first. Then although the error occurs it does not prevent the app working. Commented Sep 30, 2016 at 9:43

2 Answers 2

1
app/app.component.ts(2,22): error TS2307: Cannot find module '@oval/test'.

This is typescript compilation error, and systemjs is not used at compilation time (well, unless you are using systemjs plugin for typescript, which I guess you don't).

If you are publishing typescript module using npm (no matter public or private), you need to make declaration files (.d.ts) for that module available for its users.

First, you have to compile the module with tsc -d, which will create .d.ts declaration files which need to be distributed together with compiled .js files.

Then, for typescript 2.0, you need to add one line to module package.json file which will tell typescript how to find .d.ts file for main javascript file. If your main is test.js, then this should work:

"types": "test.d.ts"  

Also, you don't need to distribute test.ts file with your package.

For more details, see section on publishing modules in the typescript handbook.

Sign up to request clarification or add additional context in comments.

3 Comments

I have been trying to create a '.d.ts' file, but am still getting the same error, now I suspect I am not creating the definition file correctly. I attempted to use dtsmake but that created an empty file with only some comments. I am assuming my d.ts file should look something like this declare class Test { value: string; } is that correct?
Yes .d.ts file should contain declarations like these, if you module is typescript then compiler can generate .d.ts when compiling it to javascript, you can use tsc -d on the command line for that.
oddly when I run that line the compiler throws a bunch of errors, TS1008, TS1005 & TS1001. telling me my file doesn't start with an import and the import doesn't end with a ';' etc. I will have more time on Wed to look into this. Thanks
0

If your main file (which contains decleration for Test class) is test.js try to configure systemjs.config.js like this:

'@oval/test': {
        main: 'test.js',
        defaultExtension: 'js'
 }

Then you should be able to import using:

import { Test } from '@oval/test';

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.