Vyhledávání na webu

reactjs - Neočekávaný token „<“, očekáváno „{“ při předávání rozhraní do React třídy komponenty


Narazil jsem na problém ve svém prostředí Laravel 8/Babel/Mix/React/TypeScript, kde běžná React třída komponenty způsobuje chybu při kompilaci, protože jsem projekt přemigroval na TypeScript a začal komponentě předávat prázdný props a jednoduché rozhraní stavu.

Zkoušel jsem předávat prázdné JSON objekty, zakomentovat různé příkazy importu, přesunout volání export default pod funkci, ale zatím to nezabralo.

Chybové hlášení při kompilaci:

Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/.../MyComponent.tsx: Unexpected token, expected "{" (10:54)

   8 | import { IState } from '../interfaces';
   9 |
> 10 | export default class MyComponent extends React.Component<{}, IState> {
     |                                                         ^
  11 |
  12 |     constructor(props:any) {
  13 |       super(props);
    at Object._raise (/Users/.../node_modules/@babel/parser/lib/index.js:796:17)

MyComponent.jsx úryvek:

import { IState } from '../interfaces';

export default class MyComponent extends React.Component<{}, IState> {

    constructor(props:any) {
      super(props);
      this.state = dummyData;
    }
    ...

Zjednodušený interfaces.ts:

export interface IState {
    tasks: {
        [key: string]: ITask
      };
    columns: {
        [key: string]: IColumn
    };
    columnOrder: string[];
}
webpack.mix.js
const mix = require('laravel-mix');

require('laravel-mix-purgecss');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.ts', 'public/js')
    .react()
    .sass('resources/sass/app.scss', 'public/css')
    .postCss('resources/css/app.css', 'public/css', [
        require('tailwindcss')(),
    ])
    .setResourceRoot("/") // This allows easy resource linking from React components
    .purgeCss({
        //enabled: mix.inProduction(),
        enabled: true,
        folders: ['resources', 'app'],
        extensions: ['html', 'js', 'ts', 'tsx', 'php', 'vue'],
    });

mix.extend('customAdditions', function(webpackConfig, ...args) {
    webpackConfig.resolve.extensions.push('.ts', '.tsx');
});

mix.customAdditions();
.babelrc
{
    "plugins": ["transform-class-properties"],
    "presets": [["@babel/preset-env", {"modules": false}],
    "@babel/preset-react"]
}
tsconfig.json
{
  "compilerOptions": {
    "target": "es5", 
    "module": "commonjs", 
    "lib": ["dom", "es2017"],   
    "jsx": "react",      
    "strict": true, 
    "noImplicitAny": true,   
    "moduleResolution": "node",  
    "esModuleInterop": true,   
    "skipLibCheck": true,    
    "forceConsistentCasingInFileNames": true ,
    "watch": true,
  }
}

Aktualizace 1: Další vyzkoušené věci bez úspěchu:

  • Postupné snižování verze Reactu (mezitím spouštění yarn při změnách čísla verze balíčku) až na 16.14.0
  • Poté, co to nefungovalo, jsem downgradoval jak @types/react, tak @types/react-dom na jejich nejnovější verze 16, aby odpovídaly downgradeovaným balíkům react
  • Spuštění tohoto příkazu na principu vypálené země: watchman watch-del-all && rm -f yarn.lock && rm -rf node_modules && yarn && yarn cache clean && yarn dev

Odpověď č. 1

Přišel jsem na to: bylo potřeba v mém .babelrc vyměnit @babel/preset-react za @babel/preset-typescript, po přidání těchto presetů pomocí yarn add @babel/preset-typescript --dev. Díky odpovědi Leona Gabana, která mě nasměrovala tímto směrem 🙌

Nový .babelrc:

{
    "plugins": ["transform-class-properties"],
    "presets": [
        ["@babel/preset-env", {"modules": false}],
        "@babel/preset-typescript" // <--
    ]
}

To by také vyřešilo problém, pokud někdo zaznamenal chybu interface is a reserved word... při deklaraci rozhraní těsně před jejich třídní komponentou.

Související články