Ionic React Typescript with pug.js, 'Uncaught ReferenceError: React is not defined' when use tsx but not jsx
Ionic React Typescript with pug.js, 'Uncaught ReferenceError: React is not defined' when use tsx but not jsx
问题:react-app-rewired start
适用于 App.jsx(也适用于 .js)但不适用于 App.tsx(也适用于 .ts)
步骤
- 我用
ionic start my-app blank --type=react --capacitor
创建了一个样板应用程序
- 在 package.json 上,我相应地更换并重新安装(删除 package.lock.json、
npm i
)
{
"name": "my-app",
"version": "0.0.1",
"private": true,
"scripts": {
- "start": "ionic serve",
+ "start": "react-app-rewired start",
- "build": "ionic build",
+ "build": "react-app-rewired build",
"test": "react-scripts test"
},
"dependencies": {
"@capacitor/android": "^2.4.3",
"@capacitor/core": "2.4.3",
"@ionic/react": "^5.0.7",
"@ionic/react-router": "^5.0.7",
"ionicons": "^5.0.0",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
+ "babel-plugin-transform-react-pug": "^7.0.1",
+ "customize-cra": "^1.0.0",
+ "react-app-rewired": "^2.1.6",
},
"devDependencies": {
"@capacitor/cli": "2.4.3",
"@ionic/cli": "6.12.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^8.0.3",
"@types/jest": "^24.0.25",
"@types/node": "^12.12.24",
"@types/react": "^16.9.17",
"@types/react-dom": "^16.9.4",
"@types/react-router": "^5.1.4",
"@types/react-router-dom": "^5.1.3",
"react-scripts": "3.4.0",
"typescript": "3.8.3"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"description": "An Ionic project"
- 在项目的根文件夹中添加
config-overrides.js
文件
const { override, disableEsLint, addBabelPlugin } = require('customize-cra')
module.exports = override(
disableEsLint(),
addBabelPlugin('transform-react-pug'),
)
- 将App.tsx替换为
import React from 'react'
import {
IonApp,
IonContent,
IonHeader,
IonTitle,
IonToolbar,
} from '@ionic/react'
declare const pug: any
const App: React.FC = () => {
return pug`
IonApp
IonHeader
IonToolbar
IonTitle My App
IonContent.ion-padding Add some content here…
`
}
export default App
- 在
tsconfig.json
上设置 "strict": false
npm start
(或react-app-rewired start
)在项目根文件夹
终端 ('Compiled successfully!') 上没有错误,chrome 屏幕是空白的,在 chrome 控制台上:
Uncaught ReferenceError: React is not defined
at App (main.chunk.js:33)
...
奇怪的是,如果我将应用扩展名改为 .jsx 或 .js 而不是 .tsx 或 .ts
在设置 CRA typescript 应用程序而不是 ionic start --type=react --capacitor
应用程序时,哈巴狗设置也有效
编辑:
这是 working/not 工作仓库 https://github.com/calvindio/template-ionic-react-ts-pug
的 github
问题
看起来问题出在 tsc
删除了未使用的导入,最终导致了问题。
例如,这一行 import React from 'react'
不会包含在编译代码中,因为您没有 return 作为 jsx
格式。
同样,所有像import { IonApp, ... } from '@ionic/react';
这样的导入也不会包含在编译后的代码中。这就是 webpack
无法映射 React
正确导入的原因。
解决方案
据我了解,我还知道 tsc
的任何选项仍会在构建代码中保留未使用的导入。如果你能找到那个选项就太好了。
但是现在,您可以通过使用 require
关键字来解决问题,它仍然可以导入:
App.tsx
const React = require('react');
const { IonApp, ... } = require('@ionic/react');
// ...
问题:react-app-rewired start
适用于 App.jsx(也适用于 .js)但不适用于 App.tsx(也适用于 .ts)
步骤
- 我用
ionic start my-app blank --type=react --capacitor
创建了一个样板应用程序
- 在 package.json 上,我相应地更换并重新安装(删除 package.lock.json、
npm i
)
{
"name": "my-app",
"version": "0.0.1",
"private": true,
"scripts": {
- "start": "ionic serve",
+ "start": "react-app-rewired start",
- "build": "ionic build",
+ "build": "react-app-rewired build",
"test": "react-scripts test"
},
"dependencies": {
"@capacitor/android": "^2.4.3",
"@capacitor/core": "2.4.3",
"@ionic/react": "^5.0.7",
"@ionic/react-router": "^5.0.7",
"ionicons": "^5.0.0",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
+ "babel-plugin-transform-react-pug": "^7.0.1",
+ "customize-cra": "^1.0.0",
+ "react-app-rewired": "^2.1.6",
},
"devDependencies": {
"@capacitor/cli": "2.4.3",
"@ionic/cli": "6.12.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^8.0.3",
"@types/jest": "^24.0.25",
"@types/node": "^12.12.24",
"@types/react": "^16.9.17",
"@types/react-dom": "^16.9.4",
"@types/react-router": "^5.1.4",
"@types/react-router-dom": "^5.1.3",
"react-scripts": "3.4.0",
"typescript": "3.8.3"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"description": "An Ionic project"
- 在项目的根文件夹中添加
config-overrides.js
文件
const { override, disableEsLint, addBabelPlugin } = require('customize-cra')
module.exports = override(
disableEsLint(),
addBabelPlugin('transform-react-pug'),
)
- 将App.tsx替换为
import React from 'react'
import {
IonApp,
IonContent,
IonHeader,
IonTitle,
IonToolbar,
} from '@ionic/react'
declare const pug: any
const App: React.FC = () => {
return pug`
IonApp
IonHeader
IonToolbar
IonTitle My App
IonContent.ion-padding Add some content here…
`
}
export default App
- 在
tsconfig.json
上设置"strict": false
npm start
(或react-app-rewired start
)在项目根文件夹
终端 ('Compiled successfully!') 上没有错误,chrome 屏幕是空白的,在 chrome 控制台上:
Uncaught ReferenceError: React is not defined
at App (main.chunk.js:33)
...
奇怪的是,如果我将应用扩展名改为 .jsx 或 .js 而不是 .tsx 或 .ts
在设置 CRA typescript 应用程序而不是 ionic start --type=react --capacitor
应用程序时,哈巴狗设置也有效
编辑: 这是 working/not 工作仓库 https://github.com/calvindio/template-ionic-react-ts-pug
的 github问题
看起来问题出在 tsc
删除了未使用的导入,最终导致了问题。
例如,这一行 import React from 'react'
不会包含在编译代码中,因为您没有 return 作为 jsx
格式。
同样,所有像import { IonApp, ... } from '@ionic/react';
这样的导入也不会包含在编译后的代码中。这就是 webpack
无法映射 React
正确导入的原因。
解决方案
据我了解,我还知道 tsc
的任何选项仍会在构建代码中保留未使用的导入。如果你能找到那个选项就太好了。
但是现在,您可以通过使用 require
关键字来解决问题,它仍然可以导入:
App.tsx
const React = require('react');
const { IonApp, ... } = require('@ionic/react');
// ...