2

我里面有这个简单的函数app.tsx来呈现一个表格。标题很好看(黑底白字)。

在此处输入图像描述

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,则将呈现同一个表,但标题很难看到:

在此处输入图像描述

要复制这个:

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

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

清晰可见时的标题元素(app.tsx): 在此处输入图像描述

不是 ( app.jsx) 时的标题元素: 在此处输入图像描述

编辑:我能够通过放入(除了)来“修复<ChakraProvider theme={darkTheme}>app.jsxindex.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"
  }
}
4

1 回答 1

1

发生这种情况是因为您的包中有两个版本的@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 统计分析工具中来验证,该工具可以提供有关您的包的许多内部信息:

在此处输入图像描述 在此处输入图像描述

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


重复@chakra-ui/react包的原因是您的配置使 TypeScript 转译文件为 CommonJS 格式,而 Babel 转译文件为 ESModule 格式,而@chakra-ui/react'spackage.json有一个exports字段为不同的导入请求指定不同的文件:

// @chakra-ui/react/package.json

"exports": {
  ".": {
    "require": "./dist/cjs/index.js",
    "default": "./dist/esm/index.js"
  }
}

Webpack 关于包导出的文档,基本上,usingrequire将导入一个文件,而 usingimport将导入另一个文件)

// 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"));
// 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, null, /*#__PURE__*/React.createElement(Th, null, "A"), /*#__PURE__*/React.createElement(Th, null, "B"))), /*#__PURE__*/React.createElement(Tbody, null, /*#__PURE__*/React.createElement(Tr, null, /*#__PURE__*/React.createElement(Td, null, "a"), /*#__PURE__*/React.createElement(Td, null, "b"))));
}

(您可以使用inspect-loader调试加载程序输出)


要解决此问题,您可以更改tsconfig.json要输出的 ESModule:

// tsconfig.json

{
  "module": "ESNext",
  "moduleResolution": "node"
}
于 2021-07-19T15:59:34.490 回答