React Plugin Architecture with dynamic loading - javascript

I want to build a SPA on the client site, which supports a plugin concept.
You should be able to copy a package inside a specific folder and the server should load this component after a restart. This plugin should work without any information stored inside the base program.
I need to dynamically load a component by name. I do not have a map of all possible components. How can I load a component by only knowing its name?

you can check out React.lazy. This helps with dynamic loading components which you want, but with this you need to wrap it to Suspense, because component will load not immediately.
// This component is loaded dynamically
const SomeComponent = React.lazy(() => import('./SomeComponent'));
<Suspense fallback={<Spinner/>}><SomeComponent/></Suspense>

Related

Laravel vue files requiring hard-refresh even when caching implemented

this issue has been plaguing my large production website for a while now.
My app.js (compiled by webpack) has multiple Vue components in it:
Vue.component(
'product-import',
() => import(
/* webpackChunkName: "product-import" */
'./components/product_import/ProductImport.vue'
)
);
Whenever I add a new component to this file, and push my code to production... every single Vue module appears blank. The only way to solve this issue is to either:
1: Every user hard refresh the browser's cache (Ctr, Shift, R)
2: Rename EVERY SINGLE vue componenets (let's say from <clock></clock> to <clock2></clock2>) referenced in every file on my website.
I have versioning enabled mix.js('resources/assets/js/app.js', 'public/js/app2.js').version();
And I've even tried renaming the app.js file, yet each time I add a new component it requires a hard refresh from every one of our users for them to be able to see any Vue module again on our site.
This deters me from adding new Vue components, as I have to rename every single component (and sub-component) referenced in all files. Does anyone have a fix for this?

Transpile React app to make it appear in a modal

I've got a (small) React app (vanilla create-react-app), that I would like to appear in a modal (bootstrap or similar) on another site. Is there a library that will simplify this process?
Specifically, the entire use case is that if my Javascript file is loaded (and just one javascript file), it will insert a "Click Me" type call to action, and when clicked my App component will be loaded into a new modal. It will need the CSS (for the app) to be included in some form as well.
I think all of this (excluding the call-to-action which is fairly simple) could be done during Babel/Webpack transpilation but I can't find anything off-the-shelf that seems to do this.
This functionality is built into ReactDOM.render. Simply add an id to your element.
For example:
<!-- index.html -->
<script src="url/to/react/build/asset" as="script" />
<div id="button-and-modal"></div>
Then to render your react app inside the div:
// index.js
import { render } from 'react-dom';
import App from './App'
function renderReact() {
const element = document.getElementById('button-and-modal');
render(<App/>, element)
}
document.addEventListener('DOMContentLoaded', renderReact);
Then your react app would look something like this:
const App = () => (
<div>
<Button/>
<Modal/>
</div>
)
You can also code the button and modal outside of the react app and only have the modal content rendered by react. If you want to do that, then follow the same directions but add the javascript for the button+modal inside the renderReact function.
You can use for example https://direflow.io/ to build your react app as a web component that you can render anywhere on any site.
Using your current project you can do
direflow create
cd <project-name>
npm install
and then
copy your whole app in folder into direflow-components so your project tree would look like:
/public
/src
/direflow-components
/<project-name>
// leave here only index.ts from example and copy all your project files here
index.ts
component-exports.ts
index.ts
react-app-env.d.ts
.eslintrc
...
If needed you can change
...
component: App,
configuration: {
tagname: 'example-component',
},
...
to your component that you want to render and tagname by which app will be accessible.
After all that you just do
npm run build
copy direflowBundle.js from build folder to your website
and render your app on some website like so:
<body>
<script src="./direflowBundle.js"></script>
<awesome-component></awesome-component>
</body>
I feel like I deal with this issue at every Front End job. It's definitely not easy, but I've found a number of ways to do it. I've tried the bundling idea you suggested but that one gave me the hardest time. The easiest way imo without a lot of hassle is to host your react app on a blank web page, then load it into an iframe where you need it.
At my last job, we wanted to migrate our shopify website to react, but with the way the shopify architecture was set up at the time, it made it difficult to us host a server-side rendered react app. So we built the web pages using Next.js and then deployed it to Vercel. We then inserted this as an iframe into the shopify website. It worked beautifully.

Run JS onLoad of React-DOM

I am using RESTool (https://github.com/dsternlicht/RESTool) as an API-UI and I need to run a js-script after React has rendered everything. window.onload and $(document).ready do not work.
I am assuming you are using react function components.
For every side effect happening after rendering use the useEffect-hook (have a read in the docs if you dont know it, you will need it very often). Then you can dynamically import your script and use it in the hook. In the I have included a network request to load the script in case you dont serve it by your own.
function Component() {
useEffect(() => {
// This happens after rendering with a script requested from an API
makeAPIRequest.then((script) => script.doThisAndThat())
// This assumes you have your script locally, then you can import it dynamically to speed up initial render. Note that when dynamically importing you must default export the script
import('./myScriptThatShouldExecuteAfterRender').then((script) => script.doThis())
})
render(
<SomeThing />
)
}
You can also just import your script normally and then execute it in the useEffect. The dynamic import is just to load the script after you have rendered something to the user and to improve UX.

Load ReactJS App from another server and execute

Let's assume we have a website, that should show a reactjs application.
The following points are necessary:
The ReactJS application should be embedded by using a short snippet (script / html)
The ReactJS app should be updated without changing the snippet itself
The ReactJS app is hosted on a completely different server
It should not be an iFrame if possible
So what I want to achieve is similary to a Google Map for instance. You have a small snippet and you can show an application on your side.
What are the best practices to do so ? What do I have to take into consideration ?
"Micro frontends":
https://medium.com/#tomsoderlund/micro-frontends-a-microservice-approach-to-front-end-web-development-f325ebdadc16
I came across this idea only recently. So, I don't have much to tell you regarding your requirements. But it looks promising. But also may be an overkill.
And by following links you'll be able to find some code examples.
E.g. https://single-spa.js.org/docs/examples/
simple example without iframe
<script>
(function(window,document, id, scriptUrl, appId){
// create container where to render app
var containerDiv = document.createElement("DIV");
containerDiv.id=appId
document.getElementById(id).appendChild(node);
// add script tag
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = scriptUrl;
document.body.appendChild(scriptTag);
// also you may need to send you app info about where should render (id)
window.MY_WIDGET_ID = appId
})(window,document, 'where-to-render-app-id', 'script-url', 'app-id');</script>
<script >
// inside your react app you should add
render( document.getElementById(window.MY_WIDGET_ID ))
A regular React application is a set of JS(let's ignore the CSS, images, other assets this time) files. And there is a file called the entry which mounts the entire application to a specific dom. You might be familiar with the below code.
ReactDOM.render(<App/>, document.getElementById('app'))
The above code is auto executed usually once the entry is loaded onto a predefined dom. We can expose it as an initial handler of the application.
window.apps = {} // This better be executed in a script hosted by the website
window.apps['my-app'] = dom => ReactDOM.render(<App/>, dom)
The script hosted by the website then is able to start the application by calling the function above.
window.apps['my-app'](document.getElementById('root'))
In this way, the website takes the control of initial a React application, at any time, onto any dom, or even any instance.
ps. Ignore type checks, null checks. You should add it as you need to make sure no runtime error happens.
As an other option, you could wrap your react app into web component. Here's the example. But it could be overengineering, from case to case, mpc's approach could be more reasonable easily.
you can create a shell app that will load your remote code and run it.
btw, check out fronty, it is a micro-frontend tool that can help you with that with no hassle.
This is one of the feature React offers. If you take the Basic files provided by React it is an HTML page with a <div id="root"></div>. By default, React is built as a single page App. In fact, you can edit directly this HTML file (located in Public folder) and the React will still run.
So to achieve what you are looking for, build your React project include it to your HTML project (The same include present in the public/index.html -> <script src="/static/js/main.******.chunk.js"></script>.
In the React project, you add the same render condition:
if (document.getElementById("root")) {
ReactDOM.render(
<App />
document.getElementById("root")
);
}
Wrapping the ReactDom.render in an if is to make sure the desired ID is present in your dom.
That's it, it should be working.
Have fun.

how to add custom js file to reactjs which is in public

I have a js file which animated some html attribute using ids, which located in public folder of react project
is there any way to get those animations using react by loading this js file to react components ?
Finally I found my my solution. It just load entire js file before component mount
componentWillMount = () => {
loadjs('/js/file.js');
}
For more details

Categories

Resources