8

I am new to Node js and got some issues. Previously I was using node Js v13.8 to run my express application and it was working very well. I was using es6 syntax and type module having JS extension files. But, when I upgraded to Node 14.1.0. It's showing the following error(Same error with 13.9 as well).

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for D:\Projects\matri-site\bin\www.

Here is my error snippet

Again when I downgraded to Node 13.8, it works fine.

Here is my package.json file :

{
  "name": "matri-site",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "buffer": "^5.5.0",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "4.16.1",
    "handlebars": "^4.7.6",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "jsonwebtoken": "^8.5.1",
    "mongoose": "^5.8.9",
    "morgan": "~1.9.1",
    "nodemailer": "^6.4.2",
    "redis": "^3.0.2",
    "validator": "^12.1.0",
    "validatorjs": "^3.18.1"
  },
  "devDependencies": {
    "eslint": "^6.8.0"
  }
}

Here is my WWW file:

#!/usr/bin/env node

/**
 * Module dependencies.
 */

// var app = require('../app');
// var debug = require('debug')('matri-site:server');
// var http = require('http');

import app from '../app.js';
import debug from "debug";
 debug.debug('matri-site:server');
import http from "http";

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

2
  • Did u tried to put an extension to WWW file? WWW.js for example Commented May 1, 2020 at 8:19
  • Yes I did.. and it worked for me. Can you tell why it worked with js extension and not working before ? Commented May 1, 2020 at 13:53

4 Answers 4

17

The real cause is due to the new specification on ESM support. That is, the file that contains #!/usr/bin/env node requires an extension when "type": "module". Native ESM requires .js extension to identify if it is ESM (you need to specify .cjs extension if your code is actually written in commonjs), which is why it was complaining about TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ""

That is, if you want to use native ESM, you will define "type": "module" in package.json and the file name must include .js extension, i.e. file.js. Otherwise, do not specify "type" (or specify "type": "commonjs") and the file name can be with or without the .js extension. For ESM under this case, you will need to have ".mjs" extension.

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

3 Comments

When you say "For ESM under this case, you will need to have ".mjs" extension." is that saying that if we don't want to use an extension in an import statement, it must be an mjs extension on the file?
I stated the root cause of the problem and suggested 2 solutions. I'm not sure if it is possible to use bare specifiers via package.json to fix this. nodejs.org/api/esm.html#esm_import_specifiers
My vite-react app is working locally, but when I az webapp up deploy it to an Azure App Service...I get this same "unknown file extension" for /home/site/wwwroot/bin/www. Unfortunately, my app doesn't have a www file...nor even that file path...thus I cannot change the filename. I'm guessing Azure is adding the file for me during deployment. Any other ideas to remedy this? I am using node 16.18.1.
2

Ok I write the solution here if you succeeded, in addition I also tell you the reasons for the error. WWW needs an extension, like .js (WWW.js). This is because get_format.js tries to get the type of exetension, it's all written in the error generated in the console.

3 Comments

Ok.. I want to know why this was working without an extension in Node 13.8 version ?
I don't know for sure but we might think that in the other version of node this control is not there. Can you upvote and accept the solution please?
this didn't work for me in node v15 -- still getting the error
2

I solved it by providing .js extension to my WWW file. I am not sure why it needs an extension for Node 13.9 and above while it worked perfect for 13.8.

Comments

1

This is the workaround I used:

index.js

import { NeuralNetwork } from './brain.cjs'

brain.cjs

module.exports = require('brain.js')

In my case brain.js did not include an extension to their main file, so node couldn't load it with ESM.

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.