I'm migrating a React Webpack project into a SolidJS Parcel project. However, the combination of SolidJS and Parcel seems to have problems with nested Typescript projects, which combinations of React and Webpack do not have.
In my minimal example project, I get the error: @parcel/core: Failed to resolve 'solid-js/jsx-runtime' from './foo/src/index.tsx'
. If I try to rename, index.tsx
into index.jsx
, Parcel can build the same file without any error. However, I want to use Typescript instead of JavaScript.
/.babelrc:
{
"presets": [ "solid" ]
}
/package.json:
{
"private": true,
"dependencies": {
"solid-js": "1.3.12"
},
"devDependencies": {
"babel-preset-solid": "1.3.12",
"parcel": "2.3.2",
"typescript": "4.6.2"
}
}
/tsconfig.json:
{
"compilerOptions": {
"isolatedModules": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"lib": [
"dom",
"es2021"
],
"module": "commonjs",
"noEmit": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": true,
"strict": true,
"target": "es5"
}
}
/foo/src/index.tsx:
export function HelloWorld() {
return <div>Hello World!</div>;
}
/foo/package.json:
{
"private": true,
"source": "src/index.tsx",
"scripts": {
"parcel:build": "npx parcel build"
}
}
How can I fix the error @parcel/core: Failed to resolve 'solid-js/jsx-runtime
in my nested Typescript project?
To run solid in parcel, you need to follow these steps:
Install babel-preset-solid
and @babel/core
.
Create a .babelrc file with the following content:
{
"presets": ["solid"]
}
Parcel automatically picks up babel configuration but it is best to stick to the json based configuration:
Parcel supports both project wide config files such as babel.config.json, as well as file relative configs such as .babelrc.
Note: JavaScript Babel configs (e.g. babel.config.js) should be avoided. These cause Parcel’s caching to be less effective, which means all of your JS files will be recompiled each time you restart Parcel.
As a side note, we don't need to provide babel-transform-runtime for parcel to work:
@babel/preset-env and @babel/plugin-transform-runtime are not necessary, since transpilation for your browser targets is handled automatically by Parcel. https://parceljs.org/languages/javascript/#babel
import { render } from 'solid-js/web';
import { App } from './App';
const dispose = render(() => <App />, document.body);
if (module.hot) {
module.hot.accept();
module.hot.dispose(dispose);
}
If you run into any problem, make sure you have properly set your workspace:
package.json file
{
"name": "parcel-solid-demo",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build",
"serve": "parcel serve"
},
"devDependencies": {
"babel-preset-solid": "^1.6.10",
"@babel/core": "^7.21.0",
"parcel": "^2.8.3"
},
"dependencies": {
"solid-js": "^1.6.11"
}
}
index.html file in the "source" directory from the package.json:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>My First Parcel App</title>
<link rel="stylesheet" href="style.css" />
<script type="module" src="index.tsx"></script>
</head>
<body>
</body>
</html>
tsconfig.json content:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js",
"noEmit": true
}
}