0
votes

I am creating a project using node, react, electron and typescript

I used the following tutorial to start the project: https://flaviocopes.com/react-electron/#add-electron

Changed a few things to setup TS:

  • npx create-react-app files --template typescript
  • npm install --save-dev ts-node
  • changed a script in the package.json: "electron-start": "ts-node src/start-react.ts"

So here is the issue

  1. I want to use TS
  2. TS must use import/export, not require
  3. package.json must use "type": "module" for import/export to work
  4. which causes this error: Unknown file extension ".ts"
  5. so, package.json must not use "type": "module" for TS to work
  6. so maybe tsconfig.json should use "module" : "CommonJS"
  7. but react keeps changing module back to "module" : "esnext"

So what can I do to get node to run my typescript start-react.ts file

./package.json

{
  "name": "files",
  "version": "0.1.0",
  "private": true,
  "homepage": "./",
  "main": "src/start.ts",
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.3",
    "@testing-library/user-event": "^12.6.0",
    "@types/jest": "^26.0.20",
    "@types/node": "^12.19.14",
    "@types/react": "^16.14.2",
    "@types/react-dom": "^16.9.10",
    "electron": "^11.2.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "typescript": "^4.1.3",
    "web-vitals": "^0.2.4"
  },
  "scripts": {
    "start": "nf start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "electron": "electron .",
    "electron-start": "ts-node src/start-react.ts",
    "react-start": "react-scripts start",
    "pack": "build --dir",
    "dist": "npm run build && build",
    "postinstall": "install-app-deps"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "electron-builder": "^22.9.1",
    "ts-node": "^9.1.1"
  },
  "build": {
    "appId": "com.electron.electron-with-create-react-app",
    "win": {
      "iconUrl": "https://cdn2.iconfinder.com/data/icons/designer-skills/128/react-256.png"
    },
    "directories": {
      "buildResources": "public"
    }
  }
}

./tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

./src/start-react.ts

import * as net from "net"
import * as childProcess from "child_process"

const port:any = process.env.PORT
process.env.ELECTRON_START_URL = `http://localhost:${port}`

const client = new net.Socket()

let startedElectron = false
const tryConnection = () =>
{
    client.connect({ port }, () =>
    {
        client.end()
        if (startedElectron) return

        startedElectron = true
        childProcess.exec("npm run electron")
    })
}

tryConnection()
client.on("error", () => setTimeout(tryConnection, 1000))

./src/start.ts

import { app, BrowserWindow } from "electron"

let mainWindow: BrowserWindow | null

function createWindow()
{
    mainWindow = new BrowserWindow(
    {
        width: 800,
        height: 800,
        webPreferences: 
        {
            nodeIntegration: true
        }
    })
    
    mainWindow.loadURL(<string>process.env.ELECTRON_START_URL)
    mainWindow.on("closed", () => mainWindow = null)
}

app.on("ready", createWindow)

app.on("window-all-closed", () => process.platform !== "darwin" ? app.quit : null)

app.on("activate", () => !mainWindow ? createWindow() : null)

P.S. Just let me know if you need more info

2
Please share slight details of file, in which you're facing error.Vinay Sharma
@VinaySharma done.Damon
@Damon did you solve this problem? I have right the same: stackoverflow.com/questions/66208121/…Raphael10
@Damon Thanks to an Electron Expert I found and solved two errors which caused me that issue. I described the solution in my "duplicated" postRaphael10
@Raphael10, I never did solve it, I will try out the solution on the duplicate postDamon

2 Answers

0
votes

Try adding "esModuleInterop": true, to tsconfig.json

-1
votes

Use Boilerplate

I would suggest you to setup app with React Boilerplate present in the official documentation of Electron JS. The boilerplates offers TypeScript support and is standing strong at 16.7k stars.

Such boilerplates helps you save time and energy in manual setup and are highly reliable as they are curated with best practices.