pillarjs / router

Simple middleware-style router
MIT License
409 stars 102 forks source link

"Router is not a function" #90

Closed TeamDoodz closed 4 years ago

TeamDoodz commented 4 years ago

When I import "Router" in TypeScript, it is not a function and is instead some weird object. Here is my code:

import * as Router from 'router';
import * as FinalHandler from 'finalhandler';
import * as HTTP from 'http';
import * as FS from 'fs';
import * as MD from './md_convert';

const Port = 80;

var router = Router();

router.get('/', function (req, res) {
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  res.end(MD.CompileMarkdown(FS.readFileSync("content/test.md")));
});

var server = HTTP.createServer(function(req, res) {
  router(req, res, FinalHandler(req, res));
});

server.listen(Port);

Here is the object:

console.log(Router);
> { Route: [Function: Route],
  default: { [Function: Router] Route: [Function: Route] } }
dougwilson commented 4 years ago

That is strange, as it is a function in javascript. This module is only published in javascript so I'm not sure why it would be different in typescript? The Router export is a constructor function (all constructors in javascript are also just functions).

I'm not sure how to actually run the code you provided above, being unfamiliar with typescript. Can you provide perhaps a project I can clone that has everything set up so I can just run it to see the issue?

TeamDoodz commented 4 years ago

Here is the compiled javascript code:

"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var Router = __importStar(require("router"));
var FinalHandler = __importStar(require("finalhandler"));
var HTTP = __importStar(require("http"));
var FS = __importStar(require("fs"));
var MD = __importStar(require("./md_convert"));
var Port = 80;
console.log(Router);
var router = Router();
router.get('/', function (req, res) {
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.end(MD.CompileMarkdown(FS.readFileSync("content/test.md")));
});
var server = HTTP.createServer(function (req, res) {
    router(req, res, FinalHandler(req, res));
});
server.listen(Port);

and for md_convert.js:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function CompileMarkdown(input) {
    for (var i = 0; i < 6; i++) {
        input = input.replace(eval("new RegExp('^" + ('#').repeat(i + 1) + "\s(.*?)$');"), "<h" + (i + 1) + ">$1</h" + (i + 1) + ">");
    }
    return input;
}
exports.CompileMarkdown = CompileMarkdown;
dougwilson commented 4 years ago

Looks like the issue is the __importStar is destroying the exported function. Probably a bug to report on the code generator I presume.

TeamDoodz commented 4 years ago

Ok!

dougwilson commented 4 years ago

I've been doing some searching on the web about how to import CommonJS modules (like this one -- the default module type of Node.js ecosystem) with TypeScript and I think that the format import * as Router from 'router'; is the issue here; I think it is supposed to be written as import Router from 'router'; from what I am seeing, but IDK how to try it out since there is not a reproduction provided here. I also see something about a compiler flag esModuleInterop being enabled, but not sure what that means.

TeamDoodz commented 4 years ago

I will try that.