I have a Typescript react component/library
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Image, Shimmer } from 'react-shimmer';
function App() {
return (
<div>
<Image
src="https://source.unsplash.com/random/800x600"
fallback={<Shimmer width={800} height={600} />}
/>
</div>
);
}
const render = (id: string) => ReactDOM.render(<App />, document.getElementById(id));
export default render;
I want it to be compiled to UMD format, to be consumed in HTML
// index.html
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
<script type="text/javascript" src="./compiled.js">
render('app');
</script>
</body>
</html>
Preferably I want to use a modern bundler like tsup. Because webpack just scares me.
Is this possible?
Related
I just want to link the files but it's not working. I am not sure what I am doing wrong. Could you please let me know. This is my first day using react. So, please forgive. I am following this gatsby tutorial.
gatsbyjs.com/docs/tutorial/part-2/
js
import * as React from 'react'
import { Link } from 'gatsby'
const IndexPage = () => {
return (
<main>
<title>Home Page</title>
<h1>Welcome to my Gatsby site!</h1>
<Link to="/about">About</Link>
<p>I'm making this by following the Gatsby Tutorial.</p>
</main>
)
}
export default IndexPage
js second page
import * as React from 'react'
import { Link } from 'gatsby'
const AboutPage = () => {
return (
<main>
<title>About Me</title>
<h1>About Me</h1>
<Link to="/">Back to Home</Link>
<p>Hi there! I'm the proud creator of this site, which I built with Gatsby.</p>
</main>
)
}
export default AboutPage
Try import React from 'react' instead
I'm working on my first Material UI - CSS Modules - Next.js project.
Problem:
When I disable JS in my chrome dev tools, the style is not applied.
Now, I don't understand if this has something to do with Material UI? Or maybe with the way I'm importing styles?
I couldn't find any answer by now. Any help is appreciated. Thanks a lot!!
Here is some relevant code:
//pages/_document.js
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '#material-ui/core/styles';
import theme from './_theme';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
MyDocument.getInitialProps = async (ctx) => {
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
};
//pages/_app.js
import React from "react";
import "../styles/global.css";
import { ThemeProvider } from "#material-ui/core/styles";
import theme from "./_theme";
import CssBaseline from "#material-ui/core/CssBaseline";
function MyApp({ Component, pageProps }) {
React.useEffect(() => {
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<>
<ThemeProvider theme={theme}>
<CssBaseline>
<Component {...pageProps} />
</CssBaseline>
</ThemeProvider>
</>
);
}
export default MyApp;
//componentXYZ.js -> I import styles like this
import Input from "#material-ui/core/Input"; //from material ui
import styles from "./componentXYZ.module.css //other styles
The problem is not related to your code
The Next.js docs states this :
"If you disable JavaScript the CSS will still be loaded in the production build (next start). During development, we require JavaScript to be enabled to provide the best developer experience with Fast Refresh."
Doc reference
I'm essentially trying to write a JavaScript plugin that can go embed on sites written in react. My issue is I need to be able to render components in DOM elements on different pages without using routing. Here is my code so far..
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Products from './Products';
const app = (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
)
const products = (
<ApolloProvider client={client}>
<Products />
</ApolloProvider>
)
ReactDOM.render(app, document.getElementById('root'));
ReactDOM.render(products, document.getElementById('products'));
Then when this code is bundled and placed on html page..
Index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
Products
<div id="root"></div>
<script src="main.f043f60e.js"></script>
</body>
</html>
Products.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
Home
<div id="products"></div>
<script src="main.f043f60e.js"></script>
</body>
</html>
The contents of my components are not shown. It only works if I have both DOM elements (products and root) on each page, but that defeats the purpose. How can I accomplish this without having all root elements present on a page?
Presumably, the reason your .render's aren't working unless you have both app and products included as DOM elements is due to an error. i.e. ReactDOM.render(app, document.getElementById('root')); can't find an element with ID root.
This should work if you continue with the proposed structure:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Products from './Products';
const app = (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
)
const products = (
<ApolloProvider client={client}>
<Products />
</ApolloProvider>
)
const rootElement = document.getElementById('root');
if (rootElement) {
ReactDOM.render(app, rootElement);
}
const productsElement = document.getElementById('products');
if (productsElement) {
ReactDOM.render(products, productsElement);
}
This is not an ideal set up you're looking for when implementing React.
But you can do conditional render logic inside your script :
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Products from './Products';
const app = (
<ApolloProvider client={client}>
{window.location.href === "https://www.example.com/app.html " ? <App /> : ''}
{window.location.href === "https://www.example.com/products.html " ? <Products/> : ''}
</ApolloProvider>
)
ReactDOM.render(app, document.getElementById('root'));
And then change <body> in both html ( in app.html and products.html ) to :
<body>
Products
<div id="root"></div>
<script src="main.f043f60e.js"></script>
</body>
Ps. Approach not recommended while using React.
I wonder if it is possible to pass an argument to a react entry point.
My entry point looks like this:
module.exports = {
entry: "./js/components/Application.js",
output: {
path: "./dist",
filename: "bundle.js"
},
// ...
}
My Application.js:
import React from 'react';
import ReactDOM from 'react-dom';
import AnotherComponent from './AnotherComponent';
ReactDOM.render(<AnotherComponent />, document.getElementById('content'));
Not I bundle my application with webpack and include this bundle in another application. This application provides a div with id "content":
<body>
<div id="content"></div>
<script src="bundle.js" />
</body>
I know that I can do something like
<script src="bundle.js" myargument="somevalue" />
but how can I get this value for passing it to the react component AnotherComponent as a property?
What about
<script id="bundle" src="bundle.js" myargument="somevalue" />
and then
const myScript = document.getElementById('bundle');
ReactDOM.render(<AnotherComponent
myArgument = {myScript.getAttribute('myargument')}
/>, document.getElementById('content')
);
In ReactJS file src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
window.MyReactApp = {
init: (selector, myData) => {
selector = selector.substring(1);
const renderComponent = (<homeComponent mydata={myData} />);
ReactDOM.render(renderComponent, document.getElementById(selector));
},
};
Now load the ReactJs App where you want to load.
<script type="text/javascript" src="bundle.min.js"></script>
<div id="load-myreactapp"></div>
<script type="text/javascript">
const myData = {};
MyReactApp.init('#load-myreactapp', myData);
</script>
I'm new to react, and I am having trouble with multiple components.
This is the error I get Uncaught ReferenceError: require is not defined
Code that I'm using.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xtf1/t39.3284-6/11057100_835863049837306_1087123501_n.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="js/layout.js"></script>
</body>
</html>
layout.js
import React from "react";
import ReactDOM from "react-dom";
import Header from "./header";
class Layout extends React.Component {
render() {
return(
<div>
<Header/>
</div>
);
}
}
const app = document.getElementById("app");
ReactDOM.render(<Layout/>, app);
And header.js
import React from "react";
import ReactDOM from "react-dom";
export default class Header extends React.Component {
render() {
return(
<h1>Hello header</h1>
);
}
}
Babel handles only the transpilation part (i.e. converts es2015 and jsx syntax into valid ES5). But you still need to use either a bundler (webpack, browserify) or a module loader (systemjs or jspm) to load modules.
Here is an example using SystemJS. Example.
Configure systemjs loader to load libs from cdn
System.config({
transpiler: 'babel',
baseURL: '',
map: {
babel: 'https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js',
react: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js',
'react-dom': 'https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js'
}
});
// load application
System.import('script.js');
Import local files
// inside script.js
import React from "react";
import ReactDOM from "react-dom";
import Header from "./header.js"; //note extension
class Layout extends React.Component {