用于NodeJS的TypeScript通过SystemJS

我想在我的NodeJS应用程序中使用TypeScript。 为了做到这一点,我认为这将是很好的使用SystemJS使我的源文件飞到JavaScript脚本。 我设法绕过了大部分与SystemJSconfiguration相关的问题,除了以下内容:

如何使SystemJS防止处理某些import,并使其使用原来的require

SystemJS通过它自己的require实现将所有的东西都包含在它自己的模块表示中,而不考虑模块的原始types。 它使这样的NodeJS模块express一个对象而不是函数(问题在于下面的代码中)

 '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}`); }); 

另一个问题是,通过replace原来的需求,不仅每个模块应该覆盖SystemJSconfiguration,而且每个子模块都是一个矫枉过正的问题。

这是我的SystemJSconfiguration:

 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忽略某些导入(通过configuration),并绕过控制本地NodeJS require实现?

先谢谢你!

如果你看看express.js如何导出东西,你会看到

 exports = module.exports = createApplication; 

接着

 exports.application = proto; exports.request = req; exports.response = res; 

当SystemJS将其转换为模块时,您需要的函数createApplication成为默认导出 。

只有导入默认值的简写语法

 import express from 'express'; console.log(typeof express); // function 

当然,分配给它的所有属性 – applicationrequest等等仍然可用。

或者,如果您偏好原始表单进行导入,则可以将其作为default属性进行访问

 import * as express from 'express'; console.log(typeof express.default); // function 

现在你的问题

如何使SystemJS忽略某些导入(通过configuration)和绕过控制本地NodeJS需要实现?

在configurationAFAIK中没有这样的选项,但是SystemJS提供原始的节点需求作为System._nodeRequire ,所以你可以在代码中使用这个作为回退:

 var express = System._nodeRequire('express'); 

注意:正如Lu4在注释中指出的, 'express': '@node/express' SystemJSconfiguration中的'express': '@node/express'映射是非常重要的。 除了从node_modules加载node_modules@node特殊符号告诉SystemJS模块内部所需的所有软件包及其依赖关系都将被加载,并且不会被转换为模块。 这有时是必需的,因为SystemJS模块parsingalgorithm与nodejs不同,正如SystemJS文档中的CommonJS模块格式部分所述。