Reputation: 12843
I want to ship a kind of chat/support box (built with React and MUI) through a single script tag on other peoples web sites like so:
<script src="myserver.com/support/123456789/app.js"></script>
This should insert a div and build the UI on their web site.
When developing the UI, I'm using whatever I'm given from npx create-react-app, i.e the index.html
, with a <div id="root"/>
, where my <App>
gets inserted via ReactDOM.render
in index.js
.
However, I'm unable to figure out what exactly my app.js will be referring to, since I don't understand what is happening behind the scenes when react-scripts
is running my application locally.
It hurts my ego to have to ask a question in this non-specific way, so please help me refine my question.
Upvotes: 2
Views: 972
Reputation: 12843
I'll answer my own question with what seems to work so far. I ended up re-creating parts of the create-react-app functionality using webpack. Perhaps I can make this work with "react-scripts build" once I understand how it works.
index.html, this is an imaginary website that wants to use my script, so they include my code via a script-tag
<html>
<head></head>
<body>
<script src="bundle.js" defer></script>
</body>
</html>
./src/index.js, mounts or injects the app into the document from which it was loaded.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
// Dynamically create and append a DIV element to the bodytag.
const div = document.createElement("div")
div.id = "root";
// Then, render the app onto that div.
document.body.appendChild(div);
ReactDOM.render(<App/>,div);
./src/App.js, a dummy app that maintains a click-counter
import React, {useState} from 'react'
// My React app
const App = () => {
const [count,setCount] = useState(0);
const handleClick = () => {
setCount(count+1);
}
return(
<div>
<h1>#{count}</h1>
<button onClick={handleClick}>ClickMe</button>
</div>
)
}
export default App;
package.json, the only "real" dependencies are react and react-dom. The others are only needed for development.
{
"main": "index.js",
"scripts": {
"dev": "webpack serve --mode=development --open --hot",
"build": "webpack --mode=production"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
"babel-loader": "^8.2.3",
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.64.3",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.5.0"
}
}
./webpack.config.js, follow the dependencies from index.js and convert, transpile and do magic. Then, cobble everything together in one file called bundle.js. This is the file that gets included via scripts tag.
const path = require('path');
module.exports = {
entry: path.join(__dirname, "src", "index.js"),
output: {
path:path.resolve(__dirname, "dist"),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
]
}
}
Upvotes: 1