Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't 'fs' work when imported as an ES6 module?

Why do I get errors like these when I try to use the new Node.js support for ES6 modules (e.g. with node --experimental-modules script.mjs)?

// script.mjs
import * as fs from 'fs';

// TypeError: fs.readFile is not a function
fs.readFile('data.csv', 'utf8', (err, data) => {
    if (!err) {
        console.log(data);
    }
});
// TypeError: fs.readdirSync is not a function
fs.readdirSync('.').forEach(fileName => {
    console.log(fileName);
});
like image 238
Qwertie Avatar asked Jun 02 '18 21:06

Qwertie


People also ask

Can I use fs in vanilla js?

While it is possible to get implementations of require that run client-side, you can't use the Node fs module in the browser. It has a JavaScript API but isn't written in JavaScript, it really does depend on Node. js.

Do I need to npm install fs?

Node Module fs - An Overview One of those useful modules is the nodejs install “fs” module. The fs module helps you to work around the files and directories to carry out different tasks, such as a store, access, read, write, rename, and others. There is no need to install fs in node js to use it.

How do I import a module in fs?

To import and use the fs module in TypeScript, make sure to install the type definitions for node by running npm i -D @types/node and import fs with the following line import * as fs from 'fs' , or import { promises as fsPromises } from 'fs' if using fs promises.


1 Answers

You must use import fs from 'fs', not import * as fs from 'fs'.

This is because (at least from the point of view of mjs files) the 'fs' module exports only one thing, which is called default. So if you write import * as fs from 'fs', fs.default.readFile exists but fs.readFile does not. Perhaps the same is true of all Node.js (CommonJS) modules.

Confusingly, in TypeScript modules (with @types/node and ES5 output), import fs from 'fs' produces error

error TS1192: Module '"fs"' has no default export

so in TypeScript you must write import * as fs from 'fs'; by default. It appears this can be changed to match the way mjs files work using the new "esModuleInterop": true option in tsconfig.json.

like image 112
Qwertie Avatar answered Nov 03 '22 09:11

Qwertie