Я реализую приложение Preact и хотел бы использовать MUI. Кажется, что в VSCode все ссылается правильно, но когда я пытаюсь получить к нему доступ в браузере, ничего не отображается, и появляется эта ошибка консоли:
react-jsx-runtime.development.js:87 Warning: Failed prop type: Invalid prop `children` supplied to `InnerThemeProvider`, expected a ReactNode.
at InnerThemeProvider (http://localhost:8080/main.js:54463:70)
printWarning @ react-jsx-runtime.development.js:87
error @ react-jsx-runtime.development.js:61
checkPropTypes @ react-jsx-runtime.development.js:631
validatePropTypes @ react-jsx-runtime.development.js:1164
jsxWithValidation @ react-jsx-runtime.development.js:1284
jsxWithValidationDynamic @ react-jsx-runtime.development.js:1301
ThemeProvider @ ThemeProvider.js:34
M @ preact.js:1
I @ preact.js:1
b @ preact.js:1
I @ preact.js:1
b @ preact.js:1
I @ preact.js:1
N @ preact.js:1
(anonymous) @ main.tsx:24
(anonymous) @ main.tsx:24
(anonymous) @ main.tsx:24
Я пробовал возиться с webpack и tsconfig, но, честно говоря, если я не могу найти его в Интернете, я просто предполагаю, и не похоже, что у кого-то еще есть такая же проблема. Я думаю, что это должно быть псевдонимом, так как он упоминает реагирующие вещи.
Структура файла такова:
.
├── index.ts
├── main.pug
├── main.tsx
├── package.json
├── tsconfig.json
└── webpack.config.js
Интересует всего 6 маленьких файлов (я их урезал, насколько умею):
import express = require("express");
import { Server } from 'http';
import { Application, Request, Response } from "express";
const PORT = 8080;
const setupServer: () => Promise<void> = async () => {
let app = express();
const http = new Server(app);
app.use(express.json());
app.use(express.static(__dirname));
// setup pug template engine
app.engine("pug", require("pug").__express);
app.set("views",__dirname);
app.get("*", async (req: Request, res: Response) => {
res.render("./main.pug");
});
// console.info that your server is up and listening
http.listen(PORT, function() {
console.info(`Listening on port ${PORT}`);
});
};
setupServer();
import { h, render } from "preact";
import { Button, createTheme, ThemeProvider } from '@mui/material';
import { red } from '@mui/material/colors';
const theme = createTheme({
palette: {
primary: {
main: red[500],
},
},
});
function Main() {
return (
<ThemeProvider theme = {theme}>
<Button variant = "contained">Hello World</Button>
</ThemeProvider>
);
};
render(<Main />, document.body);
"use strict";
const { merge } = require('webpack-merge');
const nodeExternals = require('webpack-node-externals');
module.exports = env => {
// shared by all bundle configs
const baseConfig = {
mode: "development",
devtool: "source-map",
resolve: {
extensions: [".js", ".json", ".ts", ".tsx"],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
};
// client config
const clientMainBundleConfig = merge(baseConfig,{
name: 'main',
entry: { 'main': __dirname + "/main.tsx" },
target: 'web',
output: {
path: __dirname,
filename: "[name].js"
},
resolve: {
alias: {
"preact/hooks": require.resolve('preact/hooks'),
"preact": require.resolve('preact')
}
}
});
// the config for the index file on server side
const serverBundleConfig = merge(baseConfig,{
target: 'node',
name: 'index',
externals: [nodeExternals()],
entry: { 'index': __dirname + "/index.ts" },
output: {
path: __dirname,
filename: "[name].js"
},
});
return [serverBundleConfig,clientMainBundleConfig];
};
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"baseUrl": "./",
"target": "es6",
"module": "commonjs",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"sourceMap": true,
"paths": {
"react": ["./node_modules/preact/compat"],
"react-dom": ["./node_modules/preact/compat"]
},
},
"exclude":[
"./node_modules"
]
}
{
"name": "preact-mui",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --stats-error-details",
"start": "node ./index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@emotion/core": "^11.0.0",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/material": "^5.11.0",
"@types/express": "^4.17.15",
"@types/express-session": "^1.17.5",
"@types/node": "^18.11.15",
"express": "^4.18.2",
"http": "^0.0.1-security",
"preact": "^10.11.3",
"preact-cli": "^3.4.1",
"preact-render-to-string": "^5.2.6",
"preact-router": "^4.1.0",
"pug": "^3.0.2",
"ts-loader": "^9.4.2",
"typescript": "^4.9.4",
"webpack-cli": "^5.0.1",
"webpack-merge": "^5.8.0",
"webpack-node-externals": "^3.0.0"
}
}
<!DOCTYPE html>
html(lang = "en")
head
meta(charset = "utf-8")
meta(http-equiv = "X-UA-Compatible", content = "IE=edge")
meta(name = "viewport", content = "width=device-width, initial-scale=1")
body.container-fluid
div#mainDiv
script(type='text/javascript', src = "./main.js").
Я попытался совместить реакцию и реакцию-дом с preact/compat, надеясь, что, поскольку он упоминает реакцию, если я просто перенаправлю его обратно на preact, тогда он автоматически исправит себя, но низко и вот, это не сработало. Затем я попытался обновить tsconfig.json, включив в него следующее в соответствии с руководством mui:
"compilerOptions": {
"lib": ["es6", "dom"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
...
Но все равно ничего не изменилось.
На самом деле ничего не отображается в google/SO, поэтому не знаю, куда идти дальше.
Похоже, вы неправильно поняли, что такое псевдоним.
Псевдоним дает X, когда запрашивается Y. В вашем коде вы присваиваете preact
и preact/hooks
псевдонимы самим себе, что вообще ничего не делает.
Теперь вам нужно использовать псевдоним, поскольку компоненты React и Preact имеют разную форму; вы не можете передать компонент React в Preact без возникновения ошибок (или наоборот). Однако preact/compat
— это слой перевода, который облегчает это.
Вам нужно добавить это в свою базовую конфигурацию:
resolve: {
alias: {
"react": "preact/compat",
"react-dom/test-utils": "preact/test-utils",
"react-dom": "preact/compat", // Must be below test-utils
"react/jsx-runtime": "preact/jsx-runtime"
}
}
https://preactjs.com/guide/v10/getting-started#aliasing-in-webpack