标题样式根据 tsx 或 jsx 扩展名而变化

问题描述

我在 app.tsx 中有这个简单的函数来呈现表格。标题清晰可见(黑底白字)。

enter image description here

import React from 'react';
import { Table,Thead,Tbody,Tr,Th,Td } from "@chakra-ui/react"

export default function App() {
  return(
    <Table variant="simple" size="sm">
      <Thead>
        <Tr>
          <Th>A</Th>
          <Th>B</Th>
        </Tr>
      </Thead>
      <Tbody>
        <Tr>
          <Td>a</Td>
          <Td>b</Td>
        </Tr>
      </Tbody>
    </Table>
  )
}

但是,如果我将文件名改为 app.jsx,将呈现同一个表,但其标题很难看到:

enter image description here

要复制这个:

git clone https://github.com/somguyth/chakra-ui-header-bug.git
cd chakra-ui-header-bug
npm install
npm run dev

然后打开 localhost:9000 并将 app.jsx 更改为 app.tsx 并观察代码重新编译后标题颜色如何变化。

标题元素(app.tsx):

enter image description here

不是 (app.jsx) 时的标题元素:

enter image description here

EDIT:我可以通过将 <ChakraProvider theme={darkTheme}> 放入 app.jsx(除了 index.tsx)来“修复”它。检查标题的元素以了解其修复原因,th 标记内的类返回到正确的 css-4v3u8n,而不是错误css-r10se1。我不知道这是什么意思或如何正确修复它(即如何修复它而不必使用 ChakraProvider 两次)。


我的index.tsx

import React from "react";
import ReactDOM from "react-dom";
import { ChakraProvider,extendTheme } from "@chakra-ui/react"


import App from "./app"

const darkTheme = extendTheme({
  config: {
    useSystemColorMode: false,initialColorMode: "dark"
  }
});


ReactDOM.render(
    <ChakraProvider theme={darkTheme}>
        <App />
    </ChakraProvider>,document.getElementById("root")
);

以及我在 webpack.config.js 中的模块规则:

module: {
  rules: [
    {
      test: /\.tsx?$/,use: "ts-loader",exclude: /node_modules/
    },{
      test: /\.m?jsx?$/,exclude: /node_modules/,use: {
        loader: 'babel-loader',options: {
          presets: ['@babel/preset-env',"@babel/preset-react"]
        }
      },resolve: {
        fullySpecified: false,},{
      test: /\.css$/,use: ['style-loader','css-loader']
    }
  ],

还有我的.babel.rc

{
  "presets": ["@babel/preset-env","@babel/preset-react"]
}

还有我的package.json

{
  "name": "test","version": "1.0.0","description": "","scripts": {
    "test": "echo \"Error: no test specified\" && exit 1","dev": "webpack serve"  
  },"keywords": [],"author": "","license": "ISC","dependencies": {
    "@chakra-ui/icons": "^1.0.14","@chakra-ui/react": "^1.6.5","@emotion/react": "^11.4.0","@emotion/styled": "^11.3.0","css-loader": "^5.2.7","framer-motion": "^4.1.17","react": "^17.0.2","react-dom": "^17.0.2","react-table": "^7.7.0","typescript": "^4.3.5"
  },"devDependencies": {
    "@babel/core": "^7.14.6","@babel/preset-env": "^7.14.7","@babel/preset-react": "^7.14.5","@types/react-dom": "^17.0.9","@types/react-table": "^7.7.2","babel-loader": "^8.2.2","html-webpack-plugin": "^5.3.2","ts-loader": "^9.2.3","webpack": "^5.45.1","webpack-cli": "^4.7.2","webpack-dev-server": "^3.11.2"
  }
}

解决方法

发生这种情况是因为您的捆绑包中有两个版本的 @chakra-ui/react 包,一个是 cjs 格式,一个是 esm 格式。在使用 React Context 时,同一个文件的两个副本会创建两个不同的 React Context(相当于在两个不同的文件中调用 React.createContext),所以一个副本中的 Consumer 无法从另一个版本的 Provider 获取值。

这可以通过运行 npx webpack build --mode production --profile --json=stats.json 并将 stats.json 文件加载到 Webpack stats analyse tool 中来验证,enter image description here 可以提供有关您的包的许多内部信息:

enter image description here Webpack's documentation on package exports

(Webpack 统计分析工具显示有两个版本的 @chakra-ui/react 包)


重复@chakra-ui/react包的原因是你的配置使TypeScript转文件为CommonJS格式,Babel转文件为ESModule格式,而@chakra-ui/react的{​​{1}}有一个{{ 1}} 字段为不同的导入请求指定了不同的文件:

package.json

(inspect-loader,基本上,使用 exports 将导入一个文件,使用 // @chakra-ui/react/package.json "exports": { ".": { "require": "./dist/cjs/index.js","default": "./dist/esm/index.js" } } 将导入另一个文件)

require
import

(您可以使用 {{3}} 调试加载器输出)


要解决此问题,您可以将 // Output of src/index.tsx just after ts-loader "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports,"__esModule",{ value: true }); var react_1 = __importDefault(require("react")); var react_dom_1 = __importDefault(require("react-dom")); var react_2 = require("@chakra-ui/react"); var app_1 = __importDefault(require("./app")); var darkTheme = react_2.extendTheme({ config: { useSystemColorMode: false,initialColorMode: "dark" } }); react_dom_1.default.render(react_1.default.createElement(react_2.ChakraProvider,{ theme: darkTheme },react_1.default.createElement(app_1.default,null)),document.getElementById("root")); 更改为输出 ESModule:

// Output of src/app.jsx just after babel-loader

import React from 'react';
import { Table,Thead,Tbody,Tr,Th,Td } from "@chakra-ui/react";
export default function App() {
  return /*#__PURE__*/React.createElement(Table,{
    variant: "simple",size: "sm"
  },/*#__PURE__*/React.createElement(Thead,null,/*#__PURE__*/React.createElement(Tr,/*#__PURE__*/React.createElement(Th,"A"),"B"))),/*#__PURE__*/React.createElement(Tbody,/*#__PURE__*/React.createElement(Td,"a"),"b"))));
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...