parcel-bundler / parcel

The zero configuration build tool for the web. ๐Ÿ“ฆ๐Ÿš€
https://parceljs.org
MIT License
43.29k stars 2.26k forks source link

Parcel does not read `jsconfig.json` only `tsconfig.json`, even with `@parcel/transformer-typescript-tsc` #9771

Open al-the-x opened 1 month ago

al-the-x commented 1 month ago

๐Ÿ› bug report

I cannot get parcel to pick up jsconfig.json using either the native Typescript transformer or @parcel/transform-typescript-tsc as per previous issues reported by others and considered fixed in #6501:

I am specifically trying to compile *.js files respecting the baseUrl and include settings in our jsconfig.json to avoid having to rewrite every import statement in the project to use leading ~ or similar bare specifiers.

When no tsconfig.json is presentย and only a jsconfig.json, parcel will not attempt to compile any files to TypeScript and ignores the jsconfig.json. When tsconfig.json is present with compilerOptions.allowJs = true, parcel correctly transforms the JS files respecting the baseUrl value and other directives in tsconfig.json. Even when *.{js,jsx} files are configured to use @parcel/transform-typescript-tsc, the jsconfig.json is ignored.

๐ŸŽ› Configuration (.babelrc, package.json, cli command)

Project structure:

.parcelrc
package.json
jsconfig.json
tsconfig.json
src/
    index.html
    index.js
    App.jsx
    components/
        HelloWorld.jsx

jsconfig.json / tsconfig.json minimally:

{
  "compilerOptions": {
    "allowJs": true, // unnecessary in `jsconfig.json`
    "baseUrl": "src"
  },
  "include": ["src"]
}

package.json minimally:

{
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
  },
  "devDependencies": {
    "@babel/core": "^7.24.6",
    "@parcel/packager-raw-url": "^2.12.0",
    "@parcel/packager-xml": "^2.12.0",
    "@parcel/transformer-typescript-tsc": "^2.12.0",
    "@parcel/transformer-webmanifest": "^2.12.0",
    "@parcel/transformer-xml": "^2.12.0",
    "parcel": "^2.12.0",
    "typescript": "^5.4.5"
  },
 "babel": {
    "presets": [
      "@babel/preset-react"
    ],
  }
}

.parcelrc to enable compilation of JS files via tsc:

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{js,jsx}": ["@parcel/transformer-typescript-tsc", "..."]
  }
}

index.js

import { createRoot } from 'react-dom/client'
import App from 'App' // should import from `src/App.jsx`

createRoot(document.getElementById('root')).render(<App />)

App.jsx

import HelloWorld from 'components/HelloWorld' // should import `src/components/HelloWorld.jsx`

function App () {
  return <HelloWorld />
}

๐Ÿค” Expected Behavior

WHEN jsconfig.json is present and tsconfig.json is NOT THEN parcel should find src/App.jsx and src/components/HelloWorld.jsx by referring to the baseUrl specified in jsconfig.json

๐Ÿ˜ฏ Current Behavior

THEN parcel complains about a missing dependency for App and components:

@parcel/core: Failed to resolve 'App' from './src/index.js'

  <REDACTED>/src/index.js:2
    1 | import { createRoot } from 'react-dom/client'
  > 2 | import App from 'App'
  >    |                            ^^^^^
    3 | 
    4 | createRoot(document.getElementById('root')).render(<App />)

@parcel/resolver-default: Cannot find module 'App'

๐Ÿ’ Possible Solution

Consider jsconfig.json for compiling JS files when TypeScript is enabled. Provide a configuration example of how to enable the native TypeScript compiler provided by parcel for JS files that will consider the jsconfig.json file.

๐Ÿ”ฆ Context

I have a real world project that is using TypeScript for type hints during development but not full TypeScript features due to the volume of code in the project that we would have to convert. We consider JS files to be TS files in the IDE only, which is triggered by our existing jsconfig.json file.

I would like to convert the codebase from CRA + Webpack + react-scripts-rewired to Parcel with minimal changes to the codebase, so prefixing every import statement with / (which standardjs reports as a violation) or ~ would exceed our "minimal changes" threshold. From the documentation, it appears that parcel SHOULD support both jsconfig.json and tsconfig.json, just not both at the same time. However, in my numerous attempts, I cannot get either the native transformer nor @parcel/transformer-typescript-tsc to recognize jsconfig.json, only tsconfig.json.

This isn't a huge blocker for us, as we can stand renaming jsconfig.json to tsconfig.json and adding the allowJs flag.

๐Ÿ’ป Code Sample

See above.

๐ŸŒ Your Environment

Software Version(s)
Parcel 2.12
Node 18.11.0
npm/Yarn 8.19.2
Operating System OS X 13.2.1
mischnic commented 1 month ago

The resolver does indeed only read tsconfig: https://github.com/parcel-bundler/parcel/blob/a2789a49b88b66c67a378b8c8813e504c77c8648/packages/utils/node-resolver-rs/src/lib.rs#L1124

The transformer reads both, but prefers tsconfig (and ignore jsconfig if both exist): https://github.com/parcel-bundler/parcel/blob/a2789a49b88b66c67a378b8c8813e504c77c8648/packages/transformers/js/src/JSTransformer.js#L204-L207