Nuxt 3 - mount nuxt app to a template file - angularjs

Goal: Inject/render a Vue app instance within another template file so that we won't bother to change any code that is written in AngularJS
eg.
angular-js-app \
> app
> views
index.hbs
> nuxt-3-app
...
> src
...
main.js
...
app.vue
> node-modules
...
package.json
readme.md
Let's say index.hbs contents are:
<!DOCTYPE html>
<html ng-app="AngularMaterial">
{{>head}}
<body ng-cloak>
...
<div id="fromNuxtApp"></div>
<script>
window.addEventListener("load", function () {
window.fromNuxtApp.mount('#fromNuxtApp');
});
</script>
...
</body>
</html>
and for main.js contents are:
import { createApp } from 'vue'
import App from './App.vue'
window.fromNuxtApp = createApp(App)
^ I know this is not how Nuxt 3 is structured, I just copied this from another project that is using Vue 3 and vite but I would like to strike the point of injecting Nuxt 3 like this
Expectations:
We'll start to develop new features inside nuxt-3-app
Migrating old features to nuxt-3-app slowly until we will move away from AngularJS
Factors & ideas:
This idea was based on another project and it's written in Vue
Beginner level on using Vue, only skimmed Nuxt 3's docs and I won't say I don't have the time but I would like to hear from experienced Nuxt 3 users if this is the best approach/practice
It is very taxing for both time & budget to rewrite the whole AngularJS app to another language or even learning AngularJS to introduce new features
Thinking of using ESI tags (<esi:include ...) inside the .hbs file but that would require another moving part that won't be utilised efficiently and this is another piece to learn since we will need Varnish.
Question/s:
What is the equivalent of createApp.mount function in Nuxt 3? Since vue is not globally exposed in Nuxt 3, I'm trying to find an article but most of them are written in Vue 3, of which, is not advisable for us to use. Reason, we are streamlining our newer projects to use Nuxt 3
What part of the Nuxt 3 Docs should I focus on when developing this? If you can point this out that would be super appreciated
Aside from overhauling/learning AngularJS, and injecting Nuxt 3 inside the old code, are there any other methods? This is very arbitrary and I won't be expecting any answers.
Ending remarks, I can handle the what-ifs of this structure when deploying or maintaining it.
I'm hoping to know that this is possible using Nuxt 3 and by not resorting to Vue 3

Related

React-Django: How to send different functional components (React) to Django Views?

So I am new to React and I can currently create different functional components when I use npx create-react-app appname but if I want to "package" these files and send them to my Django's view page, what is the best way to do this? I am having some trouble with webpack configuring everything in the methods I've attempted. I am trying to create a web app. Thank you.
Basically to "deploy" Django + React app, you need to use webpack on your react project, then you store react webpacked scripts in your staticfiles directory in django. Then, you define a view that returns index.html with attached scripts {% static 'reactscripts.js' %}. Thats basically all if you want to combine theese two on simple project.
I hope thats the answer you're looking for.
[edit] Also if you would like to deploy your project (after you've figured everything out), this article may help you to do so
https://mattsegal.dev/django-spa-infrastructure.html

Static site generator that renders React to HTML directly (no React in output)?

Can Gatsby or Jekyll or any other static site generators render a React-authored site into purely static HTML? I'm looking to host on S3/CloudFront or similar and also have little to no JS in the output.
Basically I'm looking to create a static website but would like to use React as development tool to take advantage of reusable UI components. Actual runtime interaction is minimal and can be done without React at runtime.
I looked at react-static which seems to be exactly what I'm looking for but the rendered html pages still reference and load the React library.
With my minimal needs I could probably roll my own thing to create each page as a separate React SPA and then use ReactDOMServerto render each to a static HTML file. I'm looking to see if there are simpler/better options.
You can use pupeteer to get the rendered html of any webpage, including SPA. Or use rendertron, which uses pupeteer underneath.
Another one is react-snap, which will crawl your web on build and create the html for each page.
With Gatsby, sure you can. Gatsby has a html.js that serves as a template for all generated pages. You can simply remove Gatsby's javascript from that html.
/* Generated html */
...
<body>
<div id="___gatsby">...</div>
<script src="/common.js"></script> <-- remove this
</body>
First copy the default html to your src:
cp .cache/default-html.js src/html.js
Then, edit this line:
/* src/html.js */
<body {...this.props.bodyAttributes}>
{this.props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: this.props.body }}
/>
- {this.props.postBodyComponents}
+ {process.env.NODE_ENV !== 'production' && this.props.postBodyComponents}
</body>
This ensures you can still make use of gatsby's hot reload in development, but generated htmls will not include React & webpack generated scripts.
A more meticulous approach would be to loop over postBodyComponents & only removes the script tag that link to common.js, but for most case I think it'll be fine.
This definitely defeats the purpose of Gatsby, which has its own convention & complex process just so it can generate a progressive web app. For your case, if you're not already familiar with Gatsby, maybe it'd be simpler to roll your own SSR. My answer is only to show whether it's possible with Gatsby or not.

Embedding full react application into an existing web page

I'm looking to embed my react application into an existing plain html / javascript website. What I've found so far is that you are only able to embed individual components into existing websites, not entire react applications.
Naturally I have an app component which contains the entire application. Am I able to embed the full application by embedding this component? My concern is all the modules I'm using (e.g. axios, bootstrap) will break.
I've been looking for a good tutorial on how to do this but I'm not finding many examples of trying to embed the entire application into an existing page.
My understanding of how to do this, is to reference the react javascript source links in the html page head, possibly also babel although its unclear to me if babel will work. Then we can use the renderDom method like we normally would.
On page load can I run my index.js file to insert my react app component into the dom? If this would work, are there any issues with file structure, file updates I would need to take care of?
If I'm driving off path out into the wilderness and there is a better way to handle it I'm open to suggestions. I'm just looking to see if someone else has experience doing this before I start down a bad path.
I was able to embed my full react application by doing the following...
I built my react app production files with npm run build
I copied those files into the existing web project at the root level
Then I opened the index.html file generated from npm run build and copied the scripts in the head and body sections to the page I wanted to drop in my application
Finally I added a div with the id root (this is what my renderDOM method is looking for) where I wanted my application to appear on the existing web page.
That was it. Super easy, thanks for the help!
Just wanted to add a quick additional approach here.
If you already have a Flask app and you're trying to put React components or an app (so the base component of an app) onto an existing HTML page in the Flask app, basically the only thing that you need is Babel, unless you are able to write React components without using JSX (so in plain Javascript) in which case you'd need nothing.
Step 1: To attach Babel to your project, you'll have to grab the Babel node modules which means your project will be associated with NPM for the sole purpose of using the Babel functions. You can do this by running the following commands in your project root directory (Node.js must be installed):
npm init -y
npm install babel-cli#6 babel-preset-react-app#3
Step 2: Once Babel is attached to your project, you'll have to actually transpile the existing React component .js files from JSX into plain Javascript like so:
npx babel --watch (jsdirectory) --out-dir (outputdirectory) --presets react-app/prod
where (jsdirectory) is the path to the directory where your React component files written using JSX are, and (outputdirectory) is where you want your translated files to show up--use . for (outputdirectory) to have transpiled files appear in your root directory.
Step 3: After the plain Javascript versions of your React files appear, make sure they are linked to your HTML page instead of the original JSX-utilizing files (replace the original script tag's .js file)
Step 4: Make sure the HTML page in question is linked to the .CSS files you want (they will modify the transpiled Javascript in the same manner as they did the JSX files in a project made using Create-React-App because the class names are the same) as well as the required React resources:
<script src="https://unpkg.com/react#16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js" crossorigin></script>
After you do those quick steps your React components should render no problem on that page in your Python-Flask application.

How to integrate a react application in drupal 8, using drupal custom module?

I am very new to react and drupal 8. I know to create custom modules in drupal and react SPAs, but I m not able to call my react app using a drupal8 controller .
Can someone please make me clear of the flow and the correct way to integrate react app in drupal 8?
So there isn't really a good means of calling a React application from within the regular Drupal controller layer or in the twig templates of Drupal 8.
There are two ways people usually connect a React Application to D8.
Option 1 - Progressively decoupled sites - This is where Drupal still uses the TWIG engine to generate the vast majority of the site views, and can use React for some small part of the site while communicating with Drupal through a Drupal based webservice. Check out this project for more information - https://www.drupal.org/project/pdb. This is a nice option if you just want to add a small React based widget, but want to keep the bulk of your site in using standard TWIG.
Option 2 - Fully decouples sites - This is where you render 100% of your applications view layer using React, and just use Drupal as a CMS that provides a web service. There are multiple options for the webservice portion including https://www.drupal.org/project/graphql and https://www.drupal.org/docs/8/api/restful-web-services-api/restful-web-services-api-overview. So an example of this would be serving a create-react-app on a static server and communication with D8 through a web service.
Here is some additional information that might help guide your decision.
https://dri.es/how-to-decouple-drupal-in-2018
Best of luck!
Long post with some assumptions(but it works):
I was seeking to achieve the same (Drupal 8 and react decoupled block), and I searched and searched, I found myself returning to this page more than once, so I will leave the little thing I discovered here.
My Assumptions:
you have created a custom block that has it's own twig template.
you have defined your libraries in your libraries file (we will review this)
you have created your react app in the root folder of your module with npx create-react-app my-app.
create-react-app my-app creates a react app inside my-app folder, my-app contains all the react code and configs. To get our app(custom react js library) to play well with drupal we will need to override somethings, like scripts to rename our files (build command),to something drupal can identify(recognize) and load.
Run yarn add react-app-rewired --dev, to download react app rewire, that let's us override the default react-app configs without having to eject our app.
In the root of your react-app folder, create a file named config-overrides.js that should contain the below code
module.exports = function override(config, env) {
config.optimization.runtimeChunk = false;
config.optimization.splitChunks = {
cacheGroups: {
default: false
}
};
return config;
};
and edit the scripts in in the package.json to
"build": "react-app-rewired build && yarn run build:dist",
"build:dist": "cd build && copy static\\js\\*.js main.js && copy static\\css\\*.css main.css",
NB: I have edited the build command and added the build:dist script (however if not on windows please
replace copy with cp and \\ with / in the build:dist). This will make sure every time you run the build script, your build files will be renamed to main.js and main.css without the filename..js/css which we can then reference in our libraries.yml file.
my modulename.libraries.yml looks like this (filename = modern_js_drupal.libraries.yml)
react_local:
version: 1.x
js:
my-app/build/main.js: {}
css:
layout:
my-app/build/main.css: {}
and my block.html.twig
<div class="row">
<div id="root">
<h4>React App</h4>
</div>
{{ attach_library('modern_js_drupal/react_local') }}
The reason I named my div 'root' and not anything else if because react app uses the same id when rendering your app.
Look into react_js/public/index.html and react_js/src/index.js. index.html provides the div to hook our app into and index.js renders the app on the div provided ( ReactDOM.render(<App />, document.getElementById('root'));), The advantage of this during development is, you get to create your app and view the changes instantly on your app (http://localhost:3000/) and you can later run yarn build to view the most recent changes on your drupal 8 site.

Embedding an angular 1.3 app in a Angular 2 app

I am trying to build and app using Angular 2 which has several tabs. I want one of these tabs to be as the already created angular 1.3.17 app. More specifically, I want to embed Netflix Vector into one of my tabs. My Angular 2 app is uploaded here (at the moment does nothing) here. Would this be possible?
I don't intend to have any interaction between the Angular 2 components and Angular 1.x. I simply want to embed it.
I also tried the following:
The way to run Netflix Vector is simply doing a gulp build and then running a simple server inside the dist directory.
So, to ease the way of embedding such a large application, I tried to put the dist directory inside my angular 2 component directory and then just modifying the index.html to remove the inclusion of scripts and css. I loaded those scripts and css through my main index.html.
Then I loaded index.html through my angular 2 component. I have made sure that the angular libraries and all other js files are loaded. However, it doesnt seem to work just by providing a ng-app directive inside index.html

Resources