2016-09-02 3 views
1

Я хотел бы использовать TypeScript в моем приложении NodeJS. Чтобы сделать это, я подумал, что было бы неплохо использовать SystemJS, чтобы превратить мои исходные файлы на лету в JavaScript. Мне удалось обойти большинство проблем, связанных с конфигурацией SystemJS, кроме следующих:TypeScript для NodeJS через SystemJS

Как сделать SystemJS предотвращением обработки определенных импортных товаров и сделать его использование оригинальным require?

SystemJS через собственную версию require воплощает все в своем собственном представлении модуля, не уважая исходный тип модуля. Это делает такой 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}`); 
}); 

Другая проблема заключается в том, что путем замены оригинала требуют не только каждый модуль должен быть покрыт с конфигурацией 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 реализации?

Спасибо заранее!

+0

Я не знаю о SystemJS, но я использовал TypeScript с express и commonjs, установив «moduleResolution»: «node», в tsconfig, и я бы импортировал файлы следующим образом: import express = require ('express «); – ramon22

ответ

1

Если вы посмотрите на то, как 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 и т.д. - все еще доступны.

Или, если вы предпочитаете оригинальную форму для импорта, вы можете получить доступ к нему, как default собственность

import * as express from 'express'; 

console.log(typeof express.default); // function 

Теперь на ваш вопрос

как сделать SystemJS игнорировать определенный импорт (через конфигурацию) и управление байпасом для собственного NodeJS требует реализации?

Там нет такой опции в AFAIK конфигурации, но SystemJS обеспечивает оригинальный узел требует, как System._nodeRequire, так что вы можете использовать это в качестве запасного варианта в коде:

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

Примечание: в качестве LU4 отметил в комментарий, 'express': '@node/express' отображение в SystemJS config очень важно.Помимо загрузки с node_modules, @node специальная нотация сообщает SystemJS, что все пакеты, необходимые внутри модуля и его зависимостям, должны быть загружены узлом require и не должны быть преобразованы в модули. Это иногда необходимо, поскольку алгоритм разрешения модуля SystemJS отличается от nodejs, как указано в разделе формата модуля CommonJS в документах SystemJS.

+0

Я закончил отладку SystemJS около 4 утра утром и в конце концов нашел ваше решение самостоятельно, но был устал, чтобы дать ответ. Одна вещь, которую я бы упомянул в вашем ответе, состоит в том, что '' express ':' @ node/express'' является очень важным – Lu4

Смежные вопросы