Weird problem with or without `babel.config.json` about `@linaria/babel-preset`
Environment
- Linaria version: 7.23.3
- Bundler (+ version): Babel 7.23.3
- Node.js version: 18.16.1
- OS: macOS Sonama 14.1.1
Description
I met a weird problem when attempting to upgrade from Linaria v2 to v5. It seems that the use of @linaria/babel-preset causes @babel/preset-typescript invalid when utilizing Babel CLI with the --presets parameter instead of using a babel.config.json file.
yarn run v1.22.19
$ babel --presets=@babel/typescript,@linaria src/index.ts
SyntaxError: /Users/malash/Projects/test-goji/src/index.ts: /Users/malash/Projects/test-goji/src/index.ts: Missing initializer in const declaration. (1:7)
> 1 | const a: number = 1;
| ^
2 |
at constructor (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:356:19)
at Parser.raise (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:3223:19)
at Parser.parseVar (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:13267:16)
at Parser.parseVarStatement (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:13100:10)
at Parser.parseStatementContent (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:12683:23)
at Parser.parseStatementLike (/Users/malash/Projects/test-goji/node_modules/@babel/parser/lib/index.js:12588:17)
For more details you can checkout this repo: https://github.com/malash/linaria-issue-1382
You can reproduce the issue on the master branch, and as a contrast the good-case contains a babel.config.json and it works well.
I believe both usages should function in the same way.
Also, I'm confident this is a bug of Linaria v5 because it doesn't reproduce on Linaria v2, see the good-case-linaria-2 branch.
Reproducible Demo
https://github.com/malash/linaria-issue-1382
I found a similar issue https://github.com/callstack/linaria/issues/1218
I spent few hours to deep dive the root cause of this issue. I found a way to reproduce this issue even with a babel.config.json file. I created a new branch bad-case-with-babel-config to approve it. On this branch I added a second parameter to the @linaria preset to disable the useBabelConfigs feature.
{
"presets": [
"@babel/typescript",
[
"@linaria",
{
"features": { "useBabelConfigs": false }
}
]
]
}
By disabling this feature, the @babel/preset-typescript could not be able to run during the parse phase. This may cause the TypeScript parsing syntax error.
Therefore, I can fix this issue by adding the @babel/preset-typescript again to the babelOptions parameter of the @linaria preset. It may sound tricky, but does work.
{
"presets": [
"@babel/typescript",
[
"@linaria",
{
"features": { "useBabelConfigs": false },
"babelOptions": {
"presets": ["@babel/typescript"]
}
}
]
]
}
I believe the root cause is that @linaria/babel-preset uses a pre hook of Babel to parse the source code:
https://github.com/callstack/linaria/blob/1467f4a7017fe2420d65ec0572bc2fdcc24d7e68/packages/babel/src/plugins/babel-transform.ts#L23
I have no idea whether it's a recommended way to implement the Babel plugin. But in Linaria v2, it uses a visitor hook and everything works fine.
@Anber Could you please take a look at this issue? I saw you say useBabelConfigs will be changed to false in the next major release in https://github.com/callstack/linaria/pull/1355 . If it happened, I think it would break most TypeScript projects.