The difference between import from and import require in TypeScript

typescriptimage.jpeg?w=2924

You might sometimes see import * from library in the third-party library or some project, and in the meantime, you can also see this code import something = require('library'). Would you wonder what the difference between these two sentences is? Here is the explanation about what difference between import from and import require is.

Let’s see an example first, and you can find these two usages:

1
import uuid = require('uuid');

And, another way like this:

1
import uuid from 'uuid';

Here comes a question: is there any difference between these two ways? Or, put it in another word: which way is correct to use? Let’s check the fundamental difference between these two ways first.

import from import require
Static estimation Dynamic estimation
Compile-time error Runtime error

You might know CommonJS and ESM. Those two are the JavaScript format spec. In the CommonJS, it involves a Module concept. After CommonJS, ESM introduces the import/export concept and does the performance tuning for this concept. Let’s see CommonJS way first:

module.js

1
2
3
4
module.exports = {
foo: function () {},
bar: 'a'
}

app.js

1
2
3
var module = require('module')
console.log(module.bar)
module.foo()

In the CommonJS, it uses module.exports to export resources to outside callers. Then how does the ESM do?

module.js

1
2
export foo function(){}
export const bar = 'a'

app.js

1
2
3
import { foo, bar } from 'module'
console.log(bar)
foo()

If you use require, the compiler changes to the exported module as followed format:

1
2
3
4
function (exports, require, module, __filename, __dirname) {
const m = 1;
module.exports.m = m;
}

And then, when you are running the code:

1
2
3
const module = { exports: {} }
const require = function(){/* ...some module load code here */}
fun(module.exports, require, module, __filename, __dirname)

After this, you can get the module variables, so you can see what things the require does are:

  1. Resolution -> get the real path of the module.
  2. Loading -> load module.
  3. Wrapping -> encapsulate the module.
  4. Evaluation -> VM does this for running the module.
  5. Caching -> reuse of this module.

That’s the reason why require means runtime linking, but ESM does that in compile-time.

In the TypeScript, it supports this:

1
import uuid = require('uuid');

But it recommends that you can use this way:

1
import * as uuid from 'uuid';

These two are equivalent.
Happy coding, enjoy.

Reference

  1. Modules · TypeScript
  2. Requiring modules in Node.js: Everything you need to know
  3. The Node.js Way - How require() Actually Works