132

How do I load a regular NodeJS module (from node_modules) from within a TypeScript class?

When I try to compile .ts file that contains:

var sampleModule = require('modulename');

Compiler prompts that I can't use require in this scope. (That line is at the beginning of the file).

2240
  • 1,547
  • 2
  • 12
  • 30
Zdenek Sejcek
  • 1,367
  • 2
  • 9
  • 8
  • 1
    Can you show us your code ( original and compiled one )? I thought that `require` can be used anywhere, it does not depend on scope. – freakish Oct 05 '12 at 08:10
  • Yes, but have to be declared and is not declared in default lib.d.ts as Valentin suggested. – Zdenek Sejcek Oct 05 '12 at 08:42
  • TypeScript should not complain if the target is set to ES6 using `"target": "es6",` in the `compilerOptions` in `tsconfig.json`. – Mike Poole Oct 14 '22 at 06:22

5 Answers5

130

Typescript will always complain when it is unable to find a symbol. The compiler comes together with a set of default definitions for window, document and such specified in a file called lib.d.ts. If I do a grep for require in this file I can find no definition of a function require. Hence, we have to tell the compiler ourselves that this function will exist at runtime using the declare syntax:

declare function require(name:string);
var sampleModule = require('modulename');

On my system, this compiles just fine.

Valentin
  • 7,874
  • 5
  • 33
  • 38
  • 25
    Thank you. This will work for all functions not declared. Better solution I have found is to get node.d.ts from typescript samples and reference it. Than you have everything. There is also express.d.ts. – Zdenek Sejcek Oct 05 '12 at 08:41
  • 3
    I think you can also do `import sampleModule = module('modulename')` – mpen Jan 31 '13 at 20:23
  • Yeah but node.d.ts is currently at `v0.8.8`. Better to use the approach by @Valentin and then use say WebStorm IDE that can download definitions for the version of Node you are running and give you autocomplete etc on that. – Radek Jun 21 '13 at 18:56
  • @Radek How do you do that? I use WebStorm 7.0.2 (latest) Btw I don't find the script node.d.ts, where does it is located? Thx. – Vadorequest Nov 26 '13 at 19:19
  • 1
    @Vadorequest this should help: http://www.jetbrains.com/webstorm/webhelp/configuring-javascript-libraries.html – Radek Nov 27 '13 at 13:19
  • @Radek I found the file at C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TypeScript\lib.d.ts , in addition I plugged the declare function require(name:string); into that file so that it would always be automatically available, vs adding that snippet to every script – john.da.costa Nov 26 '15 at 00:32
  • Include in ts file /// – FacePalm Apr 01 '16 at 07:11
  • In case you missed it (as I did), you can get the `*.d.ts` files from [http://definitelytyped.org](http://definitelytyped.org/) (as @Jesse said in his answer below), and you include them in your project using `/// ` in your .ts file (as @FacePalm said in the above comment). – Travesty3 May 02 '16 at 19:15
92

The correct syntax is:

import sampleModule = require('modulename');

or

import * as sampleModule from 'modulename';

Then compile your TypeScript with --module commonjs.

If the package doesn't come with an index.d.ts file and its package.json doesn't have a "typings" property, tsc will bark that it doesn't know what 'modulename' refers to. For this purpose you need to find a .d.ts file for it on http://definitelytyped.org/, or write one yourself.

If you are writing code for Node.js you will also want the node.d.ts file from http://definitelytyped.org/.

ItalyPaleAle
  • 7,185
  • 6
  • 42
  • 69
Jesse
  • 6,725
  • 5
  • 40
  • 45
  • I followed this approach, using "import * as $s from 'scriptjs';" since I am using TypeScript. The CKEDITOR.replace() command seems to execute, and I get what looks like a valid DOM element from it, however nothing changes in the browser (still a textarea) and my editor.on( 'contentDom', ...) callbacks (also installed inside the $s callback) never get called. Any idea what's up? – Vern Jensen Apr 19 '17 at 02:54
56

The best solution is to get a copy of Node's type definitions. This will solve all kinds of dependency issues, not only require(). This was previously done using packages like typings, but as Mike Chamberlain mentioned, Typings are deprecated. The modern way is doing it like this:

npm install --save-dev @types/node

Not only will it fix the compiler error, it will also add the definitions of the Node API to your IDE.

m93a
  • 8,866
  • 9
  • 40
  • 58
rharriso
  • 1,151
  • 10
  • 11
  • 1
    This worked for me too! But what I don't understand is that I had it installed globally (ie: `npm install -g @types/node`) but that didn't work? – Jeach Mar 17 '19 at 15:30
  • 1
    What if types module is not available in npm ? – Sudharshan Nair Jan 24 '20 at 12:18
  • @SudharshanNair there are a lot of types defined by the DefinitelyTyped project. Other options include contrinuting to Definitely typed declaring types within your own project, or using without type defs, – rharriso Mar 16 '20 at 05:14
3

Use typings to access node functions from TypeScript:

typings install env~node --global

If you don't have typings install it:

npm install typings --global
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
1

when loading typescript module I use module name with extension i.e. ".ts"

const sampleModule = require('modulename.ts');

FYI, in my case "node" command (v14.17.1) using ".ts" files directly without generating "*.js" files.

GLK
  • 875
  • 2
  • 9
  • 25