Ludwig
Ludwig

Reputation: 1781

React/Typescript - semantic error TS2304: Cannot find name 'Fragment'

I have a packages folder where I am trying to build modules by running yarn build, but I get following error:

rpt2: options error TS5052: Option 'jsxFragmentFactory' cannot be specified without specifying option 'jsxFactory'.
(rpt2 plugin) Error: /Users/myUser/Desktop/Projects/my-frontend/packages/molecule-components/src/map-search/map-loader.tsx(9,12): semantic error TS2304: Cannot find name 'Fragment'.
Error: /Users/myUser/Desktop/Projects/my-frontend/packages/molecule-components/src/map-search/map-loader.tsx(9,12): semantic error TS2304: Cannot find name 'Fragment'.

This is the file map-loader.tsx:

import React, { ReactElement, ReactNode } from 'react'
import { useJsApiLoader } from '@react-google-maps/api'
import { isTechnologyDomain, isProdDomain, isQaDomain } from './app-env'

export function MapLoader(props: { fallback?: ReactNode; children: ReactNode }): ReactElement | null {
  const { isLoaded } = useJsApiLoader(mapScriptOptions)

  if (!isLoaded && props.fallback) {
    return <>{props.fallback}</>
  }

  if (!isLoaded) {
    return null
  }

  return <>{props.children}</>
}

function googleApiKey() {
  if (isTechnologyDomain()) {
    return 'randomKey1'
  } else if (isProdDomain()) {
    return 'randomKey2'
  } else if (isQaDomain()) {
    return 'randomKey3'
  } else {
    return 'randomKey4'
  }
}

const mapScriptOptions = {
  id: 'script-loader',
  channel: '55475__frontend',
  googleMapsApiKey: googleApiKey(),
  libraries: ['places'] as 'places'[],
}

This is the package.json:

{
  "name": "@myproject/molecule-components",
  "private": true,
  "version": "1.0.0",
  "sideEffects": false,
  "source": "src/index.ts",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "rimraf --no-glob ./dist && microbundle --tsconfig ./tsconfig.build.json  -f cjs,es --no-compress",
    "build-master": "yarn build",
    "lint": "run-p lint:*",
    "typescript": "tsc",
    "lint:eslint": "eslint --max-warnings 0 src",
    "lint:prettier": "prettier --check src",
    "clean": "rimraf ./dist",
    "format": "prettier --write src"
  },
  "dependencies": {
    "@myproject/entity-types": "*",
    "@myproject/ui-components": "*",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.16.0",
    "@babel/plugin-proposal-class-properties": "^7.16.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.17.3",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-transform-react-jsx-source": "^7.18.6",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.0",
    "@glow/eslint-config": "*",
    "@ladle/react": "^2.4.2",
    "@react-google-maps/api": "^2.7.0",
    "@types/react": "^17.0.17",
    "@types/react-dom": "^17.0.17",
    "@typescript-eslint/eslint-plugin": "^5.33.0",
    "@typescript-eslint/parser": "^5.36.1",
    "babel-plugin-dynamic-import-node": "^2.3.3",
    "classnames": "^2.3.1",
    "eslint": "^8.21.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-import-resolver-typescript": "^3.4.0",
    "microbundle": "0.15.0",
    "tslib": "^2.3.1",
    "typescript": "^4.7.4"
  }
}

This is the tsconfig.json:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist/", // path to output directory
    "baseUrl": "./src",
    "target": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "ESNext",
    "allowJs": false,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "importHelpers": true,
    "jsx": "react",
    "noEmit": false,
    "composite": true,
    "incremental": true
  },
  "exclude": ["**/node_modules", "**/.*/", "dist", "build"],
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}

And this is the tsconfig.build.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "target": "esnext",
    "module": "esnext",
    "jsx": "react",
    "jsxFactory": ""
  }
}

Why do I get this typescript error?

Upvotes: 4

Views: 2302

Answers (1)

Moa
Moa

Reputation: 1566

I believe that's related to this issue from microbundle Github repository:

TypeScript is unable to resolve Fragments when the jsxFactory option is set. This is a known issue for years at the TypeScript project. But the problem is that it will still break, even when you set it to the default value 🤷

Possible workarounds are:

  1. Explicitly add --jsx React.createElement flag to the build script in package.json
"build": "rimraf --no-glob ./dist && microbundle --jsx React.createElement --tsconfig ./tsconfig.build.json -f cjs,es --no-compress",
  1. Remove "jsxFactory": "" from your tsconfig.build.json as suggested in the comments
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "target": "esnext",
    "module": "esnext",
    "jsx": "react",
    // "jsxFactory": "" <- remove this
  }
}

From microbundle source code:

--jsx              A custom JSX pragma like React.createElement (default: h)
--jsxFragment      A custom JSX fragment pragma like React.Fragment (default: Fragment)

Let me know if that fixes your issue? Happy to delete this answer if it doesn't.

Cheers

Upvotes: 3

Related Questions