同构应用程序,TypeORM && TypeScript && Express && Webpack 设置问题

Posted

技术标签:

【中文标题】同构应用程序,TypeORM && TypeScript && Express && Webpack 设置问题【英文标题】:Isomoprhic application, problem with TypeORM && TypeScript && Express && Webpack setup 【发布时间】:2020-01-05 13:40:56 【问题描述】:

我正在尝试制作同构 javascript 应用程序。

服务器端代码和客户端代码都由 Webpack 编译。

当我尝试运行包含 typeorm 连接的已编译服务器端包时,我收到了这样的错误

错误

(node:324) UnhandledPromiseRejectionWarning: /var/www/server/database/entity/WasteGroup.ts:1
(function (exports, require, module, __filename, __dirname)  import Entity,PrimaryGeneratedColumn, OneToMany from "typeorm";
                                                                     ^

SyntaxError: Unexpected token 
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)

预编译的 Server.ts

// Set up ======================================================================
// get all the tools we need
import express from 'express';
import http from 'http';
import logger from 'morgan';
import path from 'path';
import createConnection from "typeorm";
import apiVersion1 from './api/api1';
import  renderRouterMiddleware from '../iso-middleware/renderRoute';

const init = () => 
  createConnection().then(() => 

    require('dotenv').config();
    // Configuration ===============================================================
    const app = express();

    app.set('port', process.env.PORT || 3000);
    app.use(logger('short'));


    // Request Handlers
    const buildPath = path.join(__dirname, '../', 'build');

    app.use('/', express.static(buildPath));
    app.use('/api', apiVersion1);

    app.get('*', renderRouterMiddleware);

    // launch ======================================================================
    // Starts the Express server on port 3001 and logs that it has started
    http.createServer(app).listen(app.get('port'), () => 
      console.log(`Express server started at: http://localhost:$app.get('port')/`); // eslint-disable-line no-console
    , );

  )


export 
  init

Webpack 相关配置

常见

const path = require('path')
const webpack = require('webpack')

module.exports = 
    mode: 'development',
    devtool: '#source-map',

    output: 
      path: path.resolve(__dirname, '..','build'),
      publicPath: '/',
      filename: '[name].js'
    ,
    module: 
      rules: [
        
          test: /\.(jsx?|tsx?)$/,
          exclude: /node_modules/,
          use: 
            loader: 'babel-loader',
            options: 
              presets: ['@babel/preset-env', "@babel/preset-react"],

            
          
        ,
        
          test: /\.tsx?$/,
          loader: 'awesome-typescript-loader',
          exclude: /node_modules/
        ,
        
          enforce: "pre",
          test: /\.js$/,
          exclude: /node_modules/,
          loader: "eslint-loader",
          options: 
            emitWarning: true,
            failOnError: false,
            failOnWarning: false,
            fix:true
          
        ,
        
          test: /\.css$/,
          use: ['style-loader', 'css-loader']
        ,
        
          test: /\.(png|svg|jpg|gif)$/,
          use: ['file-loader']
        
      ]
    ,
    resolve: 
      alias: 
        Shared: path.resolve(__dirname, '../shared')
      ,
      extensions: ['.js','.ts', '.tsx', '.jsx', '.css', '.es6'],
    ,
    plugins: [
      // new webpack.NoEmitOnErrorsPlugin()
    ],
  

服务器

const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const merge = require('webpack-merge')
const commonDevConfig = require('./webpack.dev.common.js')

const server = 
  target: 'node',
  node: 
    // Need this when working with express, otherwise the build fails
    __dirname: false,   // if you don't put this is, __dirname
    __filename: false,  // and __filename return blank or /
  ,
  externals: [nodeExternals()],
  entry: 
    server: './server/server.ts',
  ,
  output:
    libraryTarget:'commonjs2'
  


module.exports = merge(commonDevConfig, server)

WasteGroup.ts

    import Entity,PrimaryGeneratedColumn, OneToMany from "typeorm";
    import WasteType from './WasteType'
    @Entity()
    export class WasteGroup 
        @PrimaryGeneratedColumn()
        id: number;

        @OneToMany(type => WasteType, WasteType => WasteType.wasteGroup)
    types:WasteType;


ormconfig.json


    "type": "mysql",
    "host": "mysql",
    "port": 3306,
    "username": "nodedock",
    "password": "nodedock",
    "database": "wietlin_osada_db",
    "entities": ["server/database/entity/*.ts"],
    "migrations":[
      "server/database/migration/*.ts"
    ],
    "cli":
      "migrationsDir":"server/database/migration",
      "entitiesDir": "server/database/entity"
    ,
    "logging": true,
    "synchronize": false
  

tsconfig.json


    "compilerOptions": 
        "module":"es6",
        "target":"es6",
        "moduleResolution":"node",
        "noImplicitAny": false,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports":true,
        "removeComments": true,
        "preserveConstEnums": true,
        "experimentalDecorators":true,
        "emitDecoratorMetadata":true,
        // "noEmit":true,
        "jsx":"react",
        "sourceMap":true
    ,
    "include": [
        "server/*"
    ],
    "exclude": [
        "node_modules",
        "**/*.spec.ts"
    ]

我在使用这样的 npm 脚本编译 webpack 后运行应用程序

"runNodeServerApp":"node -e 'require(\"./build/server.js\").init()'"

当我在没有 TypeORM 连接的情况下运行应用程序时,它确实可以正常工作。

这是 TypeORM 问题还是我的设置问题?

如果它可以帮助任何人,这是我的项目树。

├── build
│   ├── main.js
│   ├── main.js.map
│   ├── server.js
│   └── server.js.map
├── client
│   └── main.js
├── configs
│   ├── webpack.dev.client.js
│   ├── webpack.dev.common.js
│   └── webpack.dev.server.js
├── iso-middleware
│   └── renderRoute.js
├── ormconfig.json
├── package.json
├── package-lock.json
├── README.md
├── server
│   ├── api
│   │   └── api1.ts
│   ├── controller
│   │   └── WastePickupController.ts
│   ├── database
│   │   ├── entity
│   │   │   ├── WasteGroup.ts
│   │   │   ├── WastePickupEvent.ts
│   │   │   └── WasteType.ts
│   │   ├── migration
│   │   │   └── 1567256869205-Init.ts
│   │   └── repositories
│   │       └── TestRepository
│   │           └── index.js
│   └── server.ts
├── shared
│   ├── App.js
│   ├── components
│   │   ├── html.js
│   │   ├── icons
│   │   │   └── DumpTruck
│   │   │       └── index.js
│   │   ├── Main.js
│   │   ├── NotFound.js
│   │   ├── pages
│   │   │   └── Home
│   │   │       ├── components
│   │   │       │   ├── MainAppBar
│   │   │       │   │   └── index.js
│   │   │       │   ├── WasteScheduleCard
│   │   │       │   │   ├── DumpTruck
│   │   │       │   │   │   └── index.js
│   │   │       │   │   ├── index.js
│   │   │       │   │   └── WasteScheduleLegendOpener
│   │   │       │   │       └── index.js
│   │   │       │   ├── WeatherCard
│   │   │       │   │   └── index.js
│   │   │       │   └── WeatherWidget
│   │   │       │       └── index.js
│   │   │       └── index.js
│   │   └── Root.js
│   ├── renderFullApp.js
│   ├── routes.js
│   └── theme
│       └── index.js
└── tsconfig.json

【问题讨论】:

【参考方案1】:

这里的问题是您在 ormconfig.json 中引用了 TypeScript 文件,而您的节点服务器无法处理 TypeScript。您需要转译它们并改为引用 JavaScript 文件。 另见post。

【讨论】:

谢谢你的回答。我在***上看到了这个话题。我想这个问题没有其他解决方案。我只想有一个由typescript生成的文件。我觉得很麻烦js 和 ts 文件包含几乎相同的逻辑。 好的,我认为您的设置无法做到这一点(TypeORM 需要您的实体作为转译的 js 文件)。在我看来,您不应该将服务器代码打包到一个文件中,因为这样做没有任何好处。

以上是关于同构应用程序,TypeORM && TypeScript && Express && Webpack 设置问题的主要内容,如果未能解决你的问题,请参考以下文章

Typescript & TypeORM:不能在模块外使用 import 语句

[BJOI2015]树的同构 && 树哈希教程

字符串同构最小表示法

在 TypeORM 和 NodeJS 中加入表

如何删除多行 typeorm - postgresql 和 node.js(typescript)

ZOJ-4089-Little Sub and Isomorphism Sequences