【发布时间】:2016-09-19 11:15:32
【问题描述】:
我正在开发一个名为 expresskit 的 express 库。目标是为节点休息服务器设置一些组织标准,以便有一种我希望它工作的特定方式。
一方面,我想使用 es6 显式导入,而不是纠结于 require。像这样-
import ExpressKit from 'expresskit';
ExpressKit.start({
port: 8000
});
出于多种原因,我想这样做而不是 var ExpressKit = require('expresskit');。首先,IDE 知道导入是什么,而 require 会丢失任何智能感知。我不想使用引用,因为我想避免在我的所有文件中都有/// <reference/> 标签。其次,使用 es6 显式导入,您不需要命名空间/模块,因为路径本身就是命名空间,例如 com.org.foo.bar。这是一个使用 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();
}
}
您确切地知道正在使用什么以及它来自哪里。没有全局范围的对象或通过 expresskit 命名空间进行引用。替代方案是这样的-
/// <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();
}
}
所以我遇到的问题以及我无法让 es6 显式导入正常工作的原因是当通过 tsc 编译打字稿时。 Javascript 构建到 bld 目录。由于您通过 es6 导入引用 expresskit 源,因此它也将其构建为 bld。结果看起来像这样-
/
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
现在,当我通过运行 node bld/index.js 运行构建项目时,我得到了错误-
错误:找不到模块“express”
这是因为bld/node_modules/expresskit/index.js的expresskit调用require('express'),它在bld/node_modules/中寻找express,而它的实际位置在node_modules/。
我不想复制从 node_modules/ 到 bld/node_modules/ 的所有内容,如果我这样做了,我认为该库的实用性会受到质疑。
我将尝试做的是使用systemjs 而不是commonjs 编译成单个文件。这将需要一个自定义构建脚本,将var System = require('systemjs') 注入到构建文件的顶部。但这可能是我的选择中侵入性最小的。这是要走的路吗?
那么我怎样才能把蛋糕也吃掉呢?
【问题讨论】:
-
为什么要保留两个
node_modules目录?您可以将bld/node_modules移动到node_modules。 nodejs.org/api/… -
我没有。这就是建造的结果。我已经设法使用 sytemjs 找到了解决方案,但它需要自定义构建过程。只有几行,但在展示我的解决方案之前,我将把它打开一段时间以寻找更好的解决方案。
标签: javascript node.js typescript ecmascript-6