3

This is the error that I get

./src/core/providers/todoApi/TodoApiProvider.ts 10:14 Module parse failed: Unexpected character '@' (10:14) File was processed with these loaders:

  • ./node_modules/react-scripts/node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
  • ./node_modules/babel-loader/lib/index.js You may need an additional loader to handle the result of these loaders. | class TodoApiProvider {

constructor(@inject(TYPES.HttpClient) | httpClient) { | this.httpClient = void 0;

TodoApiProvider.ts

class DefaultTodoApiProvider implements TodoApiProvider {
  private httpClient: HttpClient;

  // @inject(TYPES.HttpClient) return error
  constructor(@inject(TYPES.HttpClient) httpClient: HttpClient) {
    this.httpClient = Dependency.get(TYPES.HttpClient);
  }

  async getTodoById(id: string) {
    const data = await this.httpClient.get(
      `https://jsonplaceholder.typicode.com/todos/${id}`
    );

    return data;
  }
}

decorate(injectable(), TodoApiProvider);

export default DefaultTodoApiProvider;

If I put @inject(TYPES.HttpClient) above private httpClient: HttpClient; it will get another error Cannot access 'TYPES' before initialization.

.babelrc

{
  "presets": [
    ...,
    "@babel/preset-typescript"
  ],
  "plugins": [
    ...,
    "babel-plugin-transform-typescript-metadata",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ],
  "env": {
    "test": {
      "plugins": [
        "transform-require-context",
        "babel-plugin-transform-typescript-metadata",
        "babel-plugin-parameter-decorator"
      ]
    }
  }
}

tsconfig.js

{
  "compilerOptions": {
    ...,
    "emitDecoratorMetadata": false,
  },
}

Alan Yong
  • 993
  • 2
  • 12
  • 25

1 Answers1

0

Both stage 1 and stage 2 decorator proposals do not support parameter decorators. The @babel/plugin-proposal-decorators which implements the proposals do not know how to handle parameter decorators. As a result, the error message Unexpected character '@' was produced. Only Typescript is aware of parameter decorators.

I use Next.js not CRA but I believe it is the same problem. For Next.js, I solved this problem by installing ts-loader and configuring the Next.js webpack configuration to use ts-loader before babel-loader.

The snippet below is specific to Next.js. I reference it to clarify my point.

config.module.rules.forEach((rule) => {
  if (rule.test instanceof RegExp && rule.test.test(".ts")) {
    if (Array.isArray(rule.use)) {
      rule.use.push("ts-loader");
    } else {
      rule.use = [rule.use, "ts-loader"];
    }
  }
});

About accesing TYPES before initialization, I did not investigate why it happens since it is solved by using ts-loader as well when fixing the first issue.

Dharman
  • 30,962
  • 25
  • 85
  • 135