Reputation: 101
Ran into an issue in my Laravel 8/Babel/Mix/React/TypeScript environment where a regular React class component is producing a compile error, since I've migrated the project to TypeScript and started passing an empty props and simple state interface to the component.
I've tried passing empty JSON objects, commenting out various import statements, moving the export default
call below the function, but no dice so far.
The compile error:
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
snippet:
import { IState } from '../interfaces';
export default class MyComponent extends React.Component<{}, IState> {
constructor(props:any) {
super(props);
this.state = dummyData;
}
...
Simplified 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,
}
}
Update 1: Additional Things Tried to No Avail:
yarn
in between package version number changes) down to 16.14.0@types/react
and @types/react-dom
to their latest version 16 releases to match the downgraded react packageswatchman watch-del-all && rm -f yarn.lock && rm -rf node_modules && yarn && yarn cache clean && yarn dev
Upvotes: 3
Views: 1223
Reputation: 101
Figured it out: needed to swap @babel/preset-react
in my .babelrc
for @babel/preset-typescript
, after adding those presets with yarn add @babel/preset-typescript --dev
. Shoutout to Leon Gaban's answer for pointing me in that direction 🙌
The new .babelrc
:
{
"plugins": ["transform-class-properties"],
"presets": [
["@babel/preset-env", {"modules": false}],
"@babel/preset-typescript" // <--
]
}
This would also fix it if someone was experiencing the error interface is a reserved word
... when declaring an interface right before their class component.
Upvotes: 2