我想在我的 NodeJS 应用程序中使用 TypeScript。为了做到这一点,我认为最好使用 SystemJS 将我的源文件即时转译为 JavaScript。我已经设法绕过了与 SystemJS 配置相关的大多数问题,除了以下问题:
如何让 SystemJS 阻止处理某些导入并使其使用原始 require
?
SystemJS 通过它自己的 require
实现将所有内容包装在它自己的模块表示中,不尊重模块的原始类型。它使 express
这样的 NodeJS 模块成为一个对象而不是函数(问题出在下面的代码中)
'use strict';
console.log('In server.ts');
if ('production' === process.env.NODE_ENV)
require('newrelic');
let PORT = process.env.PORT || 3333;
import * as fs from 'fs';
import * as os from 'os';
import * as https from 'https';
import * as express from 'express'; // <------------- SystemJS makes express an object
import * as socketio from 'socket.io';
import { Routes } from './routes/index';
import { DBConfig } from './config/db.conf';
import { RoutesConfig } from './config/routes.conf';
import { SocketServer } from "./reflex/SocketServer";
const app = express(); // <------------ This is object, so no way to initialize
RoutesConfig.init(app);
DBConfig.init();
Routes.init(app, express.Router());
const opts = {
key: fs.readFileSync(__dirname + '/cert/server.key'),
cert: fs.readFileSync(__dirname + '/cert/server.crt')
};
let server = https.createServer(opts, <any>app);
let socket = socketio(server, { transports: ['websocket'] });
let socketServer = new SocketServer(100, socket);
server.listen(PORT, () => {
console.log(`Application is up and running @: ${os.hostname()} on port: ${PORT}`);
console.log(`enviroment: ${process.env.NODE_ENV}`);
});
另一个问题是,通过替换原来的 require,不仅每个模块都应该被 SystemJS 配置覆盖,而且每个子模块都应该被覆盖,这是一个矫枉过正的行为。
这是我的 SystemJS 配置:
SystemJS.config({
transpiler: 'typescript',
defaultJSExtensions: false,
map: {
// ------ system modules ------
"console": "@node/console",
"buffer": "@node/buffer",
"querystring": "@node/querystring",
"events": "@node/events",
"http": "@node/http",
"cluster": "@node/cluster",
"zlib": "@node/zlib",
"os": "@node/os",
"https": "@node/https",
"punycode": "@node/punycode",
"repl": "@node/repl",
"readline": "@node/readline",
"vm": "@node/vm",
"child_process": "@node/child_process",
"url": "@node/url",
"dns": "@node/dns",
"net": "@node/net",
"dgram": "@node/dgram",
"fs": "@node/fs",
"path": "@node/path",
"string_decoder": "@node/string_decoder",
"tls": "@node/tls",
"crypto": "@node/crypto",
"stream": "@node/stream",
"util": "@node/util",
"assert": "@node/assert",
"tty": "@node/tty",
"domain": "@node/domain",
"constants": "@node/constants",
// ------ common modules ------
'helmet': '@node/helmet',
'morgan': '@node/morgan',
'express': '@node/express',
'mongoose': '@node/mongoose',
'socket.io': '@node/socket.io',
'socket.io-client': '@node/socket.io-client', // <----- this module is being referenced by 'socket.io'
'body-parser': '@node/body-parser',
// ------ SystemJS configuration ------
json: './node_modules/systemjs-plugin-json/json.js'
},
meta: {
'*.json': {
loader: 'json'
}
},
paths: {
'typescript': './node_modules/typescript',
},
packages: {
'typescript': {
main: 'lib/typescript'
},
'server': {
defaultExtension: 'ts'
}
},
typescriptOptions: tsconfig
});
所以问题如下:如何让 SystemJS 忽略某些导入(通过配置)并绕过对原生 NodeJS require
实现的控制?
提前谢谢您!
最佳答案
如果你看看express.js如何导出东西,你会发现
exports = module.exports = createApplication;
然后
exports.application = proto;
exports.request = req;
exports.response = res;
当 SystemJS 将其转换为模块时,您需要的函数 createApplication
将变为 default export .
有一个仅导入默认值的简写语法
import express from 'express';
console.log(typeof express); // function
当然,分配给它的所有属性 - application
、request
等 - 仍然可用。
或者,如果您更喜欢导入原始表单,则可以将其作为默认
属性进行访问
import * as express from 'express';
console.log(typeof express.default); // function
现在回答你的问题
how to make SystemJS ignore certain imports (via configuration) and bypass control to native NodeJS require implementation?
据我所知,配置中没有这样的选项,但 SystemJS 提供了原始 Node 需求为 System._nodeRequire
,因此您可以在代码中使用它作为后备:
var express = System._nodeRequire('express');
注意:正如 Lu4 在评论中指出的那样,SystemJS 配置中的 'express': '@node/express'
映射非常重要。除了从 node_modules
加载之外,@node
特殊符号告诉 SystemJS 模块内所需的所有包及其依赖项都将通过 Node require
加载并且不转换为模块。这有时是必要的,因为 SystemJS 模块解析算法与 Nodejs 不同,如 CommonJS 中所述。 SystemJS 文档中的模块格式部分。
关于javascript - 通过 SystemJS 用于 NodeJS 的 TypeScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39301352/