Preact shows you can use it with HTM for a no build setup here. Which works well on my phone since I haven't be able to get Vite to work because of symlinks.
MUI shows how to install and use it with Preact as well but not with HTM for a no build setup. https://mui.com/material-ui/getting-started/
I've tried import { Button } from '@mui/material/Button';
It's tried it without brackets and even importing the file directly with import { Button } from '../node_modules/@mui/material/Button.js';
Yet console still shows...
material-ui.development.js:1848 Uncaught TypeError: Cannot read properties of undefined (reading 'useLayoutEffect')
at material-ui.development.js:1848:74
at material-ui.development.js:9:78
at material-ui.development.js:10:3 (anonymous) @ material-ui.development.js:1848 (anonymous) @ material-ui.development.js:9 (anonymous) @ material-ui.development.js:10
127.0.0.1/:1 Uncaught TypeError: Failed to resolve module specifier "@mui/material/Button". Relative references must start with either "/", "./", or "../".
What can I do to get this to work with Preact and htm for a no build setup?
Here's my code...
My package.json:
{
"name": "project",
"private": true,
"version": "0.001",
"type": "module",
"scripts": {},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/material": "^5.15.19",
"@testing-library/jest-dom": "latest",
"@testing-library/react": "latest",
"@testing-library/user-event": "latest",
"htm": "^3.1.1",
"preact": "^10.22.0",
"react-scripts": "^5.0.0"
}
}
My index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Site title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, interactive-widget=resizes-content">
<script src="js/standalone.module.js" type="module"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="components/App.js"></script>
</body>
</html>
My App.js:
import { html, render } from '../js/standalone.module.js';
import { Button } from '@mui/material/Button';
function ButtonUsage() {
return html`
<${Button} variant="contained">Hello world<//>
`;
}
render(html`<${ButtonUsage} />`, document.getElementById('root'));
Before we get started, react-scripts
, along with Babel, is build tooling. This makes your question a bit unclear. You shouldn't have it in a no-build setup.
To start with, a bare import specifier like @mui/material/Button
is meant for use in Node or, somewhat recently, with import maps -- on it's own, it's an invalid specifier in the web.
Additionally, as MUI is a React lib, you need to set up aliases to preact/compat
and it will not work out-of-the-box in a Preact app (as your errors show).
Here's an example:
note: I imagine
js/standalone.module.js
ishtm/preact/standalone
, which is better extracted to this form if we're using import maps.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Site title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, interactive-widget=resizes-content">
<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/preact@10.19.2",
"preact/": "https://esm.sh/preact@10.19.2/",
"react": "https://esm.sh/preact@10.19.2/compat",
"react/": "https://esm.sh/preact@10.19.2/compat/",
"react-dom": "https://esm.sh/preact@10.19.2/compat",
"htm/preact": "https://esm.sh/htm@3.1.1/preact?external=preact",
"@mui/material": "https://esm.sh/@mui/material?external=react,react-dom"
}
}
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="components/App.js"></script>
</body>
</html>
Then in your script:
import { render } from 'preact';
import { html } from 'htm/preact';
import { Button } from '@mui/material';
function ButtonUsage() {
return html`
<${Button} variant="contained">Hello world<//>
`;
}
render(html`<${ButtonUsage} />`, document.getElementById('root'));
Hope it helps!