Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typeorm Decorators cause Module parse failed: Unexpected character '�' #776

Open
sinamics opened this issue Sep 17, 2021 · 5 comments
Open
Labels
bug Something isn't working

Comments

@sinamics
Copy link

Im trying to build a node typescript app, but it fails with the bellow output.
Seems like it fails in typeorm decorator.

ERROR in ./index 1:0
Module parse failed: Unexpected character '' (1:0)
File was processed with these loaders:
 * ../../../../AppData/Roaming/npm/node_modules/@vercel/ncc/dist/ncc/loaders/shebang-loader.js
You may need an additional loader to handle the result of these loaders.
(Source code omitted for this binary file)
 @ ./node_modules/typeorm/decorator/Unique.js 3:14-33
 @ ./node_modules/typeorm/index.js 54:21-50
 @ ./src/entity/Camera.ts 13:18-36
 @ ./src/resolvers/CameraResolver.ts 30:17-44
 @ ./src/index.ts 40:25-62

running ncc as:
ncc build -w src/index.ts -o ./build

@styfle
Copy link
Member

styfle commented Sep 17, 2021

Can you share the contents of src/index.ts and tsconfig.json?

@sinamics
Copy link
Author

sinamics commented Sep 17, 2021

@styfle
Sure, see bellow:

index.ts

import 'reflect-metadata';
import path from 'path';
import http from 'http';
import express from 'express';
import session from 'express-session';
import connectSqlite3 from 'connect-sqlite3';
import { ApolloServer } from 'apollo-server-express';
import { buildSchema } from 'type-graphql';
import compression from 'compression';
import dotv from 'dotenv';
import cors from 'cors';
import Log from './logger/winstonLogger';
import { PubSub } from 'apollo-server-express';
import { CameraResolver } from './resolvers/CameraResolver';
import ValidateLicenseKey from './license';
import { createTypeormConn } from './createTypeormCon';
import { getCoreTempinfo } from './logger/temperature';
import { getNetworkinfo } from './logger/network';
import { getCpuInfo } from './logger/cpu';

const pubsub = new PubSub();
dotv.config();
const SQLiteStore = connectSqlite3(session);

const server = async () => {
  createTypeormConn().then(() => {
    new ValidateLicenseKey().timer();
  });

  const app = express();
  app.use(cors());

  app.use(
    session({
      store: new SQLiteStore({
        db: 'database.db',
        dir: 'usr/local/database',
        concurrentDB: true,
      }),
      name: 'uavid',
      secret: process.env.ACCESS_TOKEN_SECRET || '',
      resave: false,
      saveUninitialized: false,
      cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        maxAge: 1000 * 60 * 60 * 24 * 100, 
      },
    })
  );

  if (process.env.NODE_ENV === 'production') {
    console.log('Running Production Server');
    app.use(compression());
    app.use(express.static(path.join(__dirname, '../../frontend/build')));

    // Route all requests to index
    app.get('/*', function (_, res) {
      res.sendFile(path.join(__dirname, '../../frontend/build/index.html'), function (err) {
        if (err) {
          res.status(500).send(err);
        }
      });
    });
  }

  const apolloServer = new ApolloServer({
    schema: await buildSchema({
      resolvers: [CameraResolver],
      validate: false,
    }),
    subscriptions: {
      path: '/subscriptions',
    },
    context: ({ req, res }) => ({ req, res, pubsub }),
    playground: {
      settings: {
        'request.credentials': 'include',
      },
    },
  });
  apolloServer.applyMiddleware({ app, cors: false });
  const httpServer = http.createServer(app);

  apolloServer.installSubscriptionHandlers(httpServer);

  const port = process.env.SERVER_PORT || 4000;
  httpServer.listen(port, () => {
    Log.server(`started at http://localhost:${port}/graphql`);
  });
};

server();

tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "allowJs": true,
    "module": "commonjs",
    "lib": [
      "dom",
      "es6",
      "es2017",
      "esnext.asynciterable"
    ],
    "sourceMap": true,
    "outDir": "./dist",
    "moduleResolution": "node",
    "removeComments": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "baseUrl": "."
  },
  "include": [
    "src/**/*.tsx",
    "src/**/*.ts",
    "src/**/*.js",
  ]
}

@styfle styfle added the bug Something isn't working label Oct 16, 2021
@orefalo
Copy link

orefalo commented Oct 21, 2021

Hi,
love this idea of this project.

Same issue with mikro-orm and type-graphql annotations

@rethab
Copy link
Contributor

rethab commented Oct 27, 2021

Having similar issues with decorators. The change seems to be between 0.30.0 and 0.31.0. Unfortunately, I didn't have enough time to really isolate it into a reproducible example, but here's roughly what I have:

class Foo {
  @test('value') readonly att: string = '';
}

The decorator test just assigns the passed value to the attribute.

With 0.30.0 the generated code looks something like this:

class Foo {
  constructor() {
    this.att = '';
  }
}

but with 0.31.0 it changes to:

class Foo {
  att = '';
}

The way the decorators are generated didn't change in the output.

The effect in this case is that the att is undefined with 0.31.0 whereas with 0.30.0 the decorator would assign the value.

Versions:

  • ts-node: 10.4.0
  • tslib: 2.3.1
  • typescript: 4.4.4

Running ncc like so: npx @vercel/ncc@0.31.0 build .

@rethab
Copy link
Contributor

rethab commented Nov 2, 2021

I have identified why things were not working for me.

In my tsconfig.json, I use extends: my-base-config, where I define target: "es2019" as part of the compile options.

This project uses tsconfig-paths to resolve tsconfig, but that project has an issue which means it could never correctly resolve my tsconfig. It would just silently not load the parent. I have logged an issue about that here: dividab/tsconfig-paths#182

Something seems to have changed with ncc version 0.31.0 which changed the default target and that now generates code that breaks my decorators. Looking at the changelog, I suspect this PR:
#766

Eventually, I could reference the base config like so extends: my-base-config/tsconfig.json and that made it resolve correctly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants