Skip to content

Instantly share code, notes, and snippets.

@croaky
Last active July 25, 2021 19:55
Show Gist options
  • Save croaky/e3394e78d419475efc79c1e418c243ed to your computer and use it in GitHub Desktop.
Save croaky/e3394e78d419475efc79c1e418c243ed to your computer and use it in GitHub Desktop.
Parcel + TypeScript + React

Directory tree:

.
├── package.json
├── src
│   ├── entrypoint.tsx
│   ├── index.html
│   └── ui
│       ├── App.tsx
│       └── shared
│           └── Reset.ts
├── start.sh
└── tsconfig.json

TypeScript's tsconfig.json sets paths to Parcel's ~ module resolution convention and baseUrl to src directory.

Parcel is given src/index.html as its input, which references src/entrypoint.tsx.

All TypeScript files in src may use the ~ non-relative import paths.

import * as React from 'react'
// routing, etc.
import { Reset } from '~/ui/shared/Reset'
export class App extends React.Component {
public render() {
return (
<div>
<title>Dashboard</title>
<Reset />
</div>
)
}
}
import * as React from 'react'
import { render } from 'react-dom'
// App wrapped with redux Provider, store, etc.
import { App } from '~/ui/App'
render(
<App />,
document.getElementById('root')
)
<!doctype html>
<html>
<body>
<div id='root'></div>
<script src='./entrypoint.tsx'></script>
</body>
</html>
{
"dependencies": {
"react": "^16.6.3",
"react-dom": "^16.4.2",
},
"devDependencies": {
"@types/node": "^10.7.0",
"@types/react": "^16.7.17",
"@types/react-dom": "^16.0.7",
"parcel-bundler": "1.10.0",
"typescript": "^3.0.1"
},
"scripts": {
"build": "$(npm bin)/parcel build ./src/index.html",
"start": "./start.sh"
}
}
#!/bin/bash
set -e
"$(npm bin)/tsc" --noEmit --watch &
"$(npm bin)/parcel" ./src/index.html
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"~/*": ["./*"]
},
"typeRoots": ["node_modules/@types"]
},
"include": ["src/**/*"]
}
@Inori-Lover
Copy link

I've got my project set up like this:

├── package.json
├── public
│   ├── index.html
├── src
│   ├── index.tsx
│   ├── App.tsx
│   └── components
│       └── InboxScreen
│           └── index.tsx
│       └── Task
│           └── index.tsx
│       └── TaskList
│           └── index.tsx
└── tsconfig.json

and my tsconfig.json set up exactly like yours. Typescript is happy with it, but parcel throws an error:

/c/Users/username/Projects/taskbox/src/components/InboxScreen/index.tsx:3:21: Cannot resolve dependency '~/components/TaskList' at '/c/Users/username/Projects/taskbox/src/components/InboxScreen/~/components/TaskList'

No idea what I'm doing wrong here... Any insight?

it look weird... why it search file from taskbox/src/components/InboxScreen/ but not src.
i think it must be something wrong in tsconfig, for example baseUrl

@gsoulavy
Copy link

I use "esModuleInterop": true for default import (it's only my preference).

@schematis
Copy link

I've got my project set up like this:

├── package.json
├── public
│   ├── index.html
├── src
│   ├── index.tsx
│   ├── App.tsx
│   └── components
│       └── InboxScreen
│           └── index.tsx
│       └── Task
│           └── index.tsx
│       └── TaskList
│           └── index.tsx
└── tsconfig.json

and my tsconfig.json set up exactly like yours. Typescript is happy with it, but parcel throws an error:

/c/Users/username/Projects/taskbox/src/components/InboxScreen/index.tsx:3:21: Cannot resolve dependency '~/components/TaskList' at '/c/Users/username/Projects/taskbox/src/components/InboxScreen/~/components/TaskList'

No idea what I'm doing wrong here... Any insight?

it look weird... why it search file from taskbox/src/components/InboxScreen/ but not src.
i think it must be something wrong in tsconfig, for example baseUrl

{
  "compilerOptions": {
    "target": "ES2019",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
		"baseUrl": "./src",
		"paths": {
			"~/*": ["./*"]
		},
  },
  "include": [
    "src/**/*", "@types"
  ]
}

That's how I've got my tsconfig set up. The baseUrl and paths are set up correctly.

@miloslavnosek
Copy link

I have the same problem as @schematis. Typescript resolves the modules correctly, IDE is showing code completion like it's supposed to, but parcel crashes on first occurrence of '~' module resolution notation.

{
  "compilerOptions": {
    "baseUrl": "./src",
    "jsx": "react",
    "esModuleInterop": true,
    "paths": {
      "~*": ["./*"]
    }
  },
  "include": ["src/**/*"]
}

@croaky
Copy link
Author

croaky commented Sep 30, 2020

I'm not working on any TypeScript + Parcel projects at the moment but if someone has an updated working version, I can try to replicate locally and then update the original Gist for future folks.

@teintinu
Copy link

Can someone help me please? I'm trying to do that but it's not working well.

https://codesandbox.io/s/rough-violet-81bj9?

@insanity54
Copy link

Can someone help me please? I'm trying to do that but it's not working well.

https://codesandbox.io/s/rough-violet-81bj9?

I think your baseUrl needs to be as follows.

"baseUrl": "./src",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment