Typescript、React、Electron:不能在模块外使用 import 语句

Posted

技术标签:

【中文标题】Typescript、React、Electron:不能在模块外使用 import 语句【英文标题】:Typescript, React, Electron: Cannot use import statement outside a module 【发布时间】:2021-04-22 00:40:26 【问题描述】:

我正在使用 node、react、electron 和 typescript 创建一个项目

我使用以下教程启动项目:https://flaviocopes.com/react-electron/#add-electron

更改了一些设置 TS 的内容:

npx create-react-app files --template typescript npm install --save-dev ts-node 更改了 package.json 中的脚本:"electron-start": "ts-node src/start-react.ts"

问题来了

    我要使用 TS TS 必须使用导入/导出,而不是要求 package.json 必须使用 "type": "module" 才能进行导入/导出工作 导致此错误:Unknown file extension ".ts" 所以,package.json 不能使用 "type": "module" 来让 TS 工作 所以也许 tsconfig.json 应该使用"module" : "CommonJS" 但反应不断将模块改回"module" : "esnext"

那么我该怎么做才能让节点运行我的打字稿start-react.ts 文件

./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)

附:如果您需要更多信息,请告诉我

【问题讨论】:

请分享您遇到错误的文件的一些细节。 @Damon 你解决了这个问题吗?我也一样:***.com/questions/66208121/… @Damon 感谢一位电子专家,我发现并解决了两个导致我出现该问题的错误。我在我的“重复”帖子中描述了解决方案 @Raphael10,我从来没有解决过,我会在重复的帖子上尝试解决方案 我只是回到了 JS 【参考方案1】:

尝试将"esModuleInterop": true, 添加到 tsconfig.json

【讨论】:

嗨,我看到在我的 tsconfig 中,esModuleInterop 已经设置为 true。【参考方案2】:

使用样板

我建议您使用 Electron JS 的 official documentation 中的 React Boilerplate 设置应用程序。样板提供 TypeScript 支持,并且在 16.7k 颗星上表现强劲。

此类样板可帮助您在手动设置中节省时间和精力,并且高度可靠,因为它们采用了最佳实践。

【讨论】:

嘿,我很欣赏这个建议,我相信它会起作用,但是由于这是一个用于学习目的的项目,它会破坏使用样板为我开始一切的目的。 @Damon 所以,我建议你分享一个code sandbox。 @VinaySharma 我遇到了同样的问题。你会这么好心看看吗?提前致谢:***.com/questions/66208121/… @Raphael10 提出重复的问题无济于事。我的建议还是一样。 @VinaySharma 感谢一位电子专家,我发现并解决了两个导致我出现该问题的错误。我在我的“重复”帖子中描述了解决方案

以上是关于Typescript、React、Electron:不能在模块外使用 import 语句的主要内容,如果未能解决你的问题,请参考以下文章

Rollup、TypeScript、Electron、React 设置

不能在模块 Electron React Typescript 之外使用 import 语句

require 没有在带有 ipcRenderer.on 的 Electron-React-Webpack-Typescript 应用程序中定义

Electron结合React和TypeScript进行开发

在Electron的预装脚本中使用typescript

Electron 和 TypeScript (electron-builder):“不能在模块外使用 import 语句”