Danack
Danack

Reputation: 25701

How to fix this typescript file "is not a module" error?

I've just published my first library package to NPM, and I'm trying to use it in an application project.

It's written in typescript and the project builds okay, and has been published to NPM. But then trying to use it fails as apparently it's not a valid module.

The code in the index.ts file that sets up the module export (afaik) is:

const initByClass = (widgetBindings: WidgetClassBinding[], h: any, render: any) => {
  for (const widgetBinding of widgetBindings) {
    setupWidget(widgetBinding, h, render);
  }
};

module.exports = {
  initByClass
};

And the tsconfig.json file in the library is:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "target": "ES6",
    "module": "ES6",
    "moduleResolution": "node",
    "declaration": true,
    "outDir": "./lib",
    "strict": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "**/__tests__/*"]
}

In my application code I have added the package to my package.json (and run npm update) and am trying to import it in the app entry file with:

import { initByClass } from "widgety";

but it gives me an error:

TS2306: File '/var/app/app/node_modules/widgety/src/index.ts' is not a module.

What do I need to change, to make the code be importable into another typescript project?

In case they are of use, all of project files: https://github.com/Danack/widgety/ And the NPM package entry: https://www.npmjs.com/package/widgety

Upvotes: 6

Views: 18440

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187024

A file is considered to be a module when it exports values with the export keyword.

I believe replacing module.exports = with this line, should fix the error:

export default initByClass;

See this documentation: https://www.typescriptlang.org/docs/handbook/modules.html

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

Using import or export is what makes the compiler consider a file a module, and assigning to module.exports or using require() does not.

For this reason, and others, always use import and export in typescript codebases.

Upvotes: 9

Related Questions