0

I'm working on a library for express called expresskit. The goal is to setup some organization standards for a node rest server so there is a specific way I'd like it to work.

For one, instead of having a tangle of require I want to use es6 explicit imports. Like this-

import ExpressKit from 'expresskit';

ExpressKit.start({
  port: 8000
});

I want to do this instead of var ExpressKit = require('expresskit'); for a number of reasons. First, the IDE knows what the import is, while the require loses any intellisense. I don't want to use references because I want to avoid having /// <reference/> tags in all of my files. Second, with es6 explicit imports you shouldn't need namespaces/modules since the path acts as the namespace itselfs, like com.org.foo.bar. Here is an example of a route with expresskit-

import Route from 'expresskit/route';
import {Param} from 'expresskit/property';
import User from './';

export default class UserRouter {
  @Route('GET', '/user/:id')
  public static getUser(@Param('id') userId: number,) {
    return new User();
  }
}

You know exactly what's being used an where it comes from. There is no global-scoped objects or referencing via the expresskit namespace. The alternative would be something like this-

/// <reference path="../node_modules/expresskit/expresskit.d.ts"/>

var ExpressKit = require('expresskit');
var Route = ExpressKit.Route;
var Param = ExpressKit.Param;

import User from './';

export default class UserRouter {
  @Route('GET', '/user/:id')
  public static getUser(@Param('id') userId: number,) {
    return new User();
  }
}

So the problem I'm having and the reason why I can't get the es6 explicit imports to work properly, is when the typescript is compiled via tsc. Javascript is built to a bld directory. Since you are referencing expresskit source via es6 imports, it is also building this to bld. The result looks like this-

  /
    bld/
      node_modules/
        expresskit/
          ...
      user/
        index.js
        router.js
      index.js
    node_modules/
      expresskit/
        ...
      express/
        ...
      body-parser/
        ...
    user/
      index.ts
      router.ts
    index.ts
    tsconfig.json

Now when I run the build project by running node bld/index.js I get the error-

Error: Cannot find module 'express'

The reason for this is because expresskit as bld/node_modules/expresskit/index.js is calling require('express'), which it looking for express in bld/node_modules/ when it's actual location is in node_modules/.

I don't want to copy everything from node_modules/ to bld/node_modules/ and if I did I think the usefulness of the library would be questionable.

What I'm about to try to do is compile to a single file using systemjs instead of commonjs. This will require a custom build script that injects var System = require('systemjs') to the top of the built file. But this may be the least invasive of my options. Is this the way to go?

So how can I have my cake and eat it too?

2
  • Why do you keep two node_modules directories? You can move bld/node_modules to node_modules. nodejs.org/api/… Commented May 22, 2016 at 16:25
  • I don't. That is the result of building. I have managed to find a solution using sytemjs but it requires a custom build process. Only a few lines but I'm going to leave this open a little longer in search for a better solution before showing my solution. Commented May 22, 2016 at 17:38

1 Answer 1

1

While I assume that OP has solved their problem after more than a year, for everyone how comes here later, here's how it works.

You just add node_modules to the "exclude" list in your tsconfig.json file. While you're at it, might as well add your build folder to not reprocess it every time and add more unnecessary files (resulting in folders like bld/bld/bld/...) and build time every time you compile.

{
    "compilerOptions": { /* ... */ },
    "exclude": ["node_modules", "bld"]
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.