How to launch React App in content.js of Chrome Extension - reactjs

I have a very simple React Application that I want to load into the DOM of a page from a Chrome extension.
I'm using NPM to build the React app which runs fine under NPM.
Must tutorials show how to do this by invoking "index.html" in chrome_url_overrides => newtab.. like this:
chrome_url_overrides": {
"newtab": "index.html"
}
I have found a few tutorials showing how to do it as a content script (which is the requirement).
e.g. https://medium.com/#yosevu/how-to-inject-a-react-app-into-a-chrome-extension-as-a-content-script-3a038f611067
As described in this tutorial, I have amended my NPM build to output the js and css files in the "static" directory of the build with consistent names so that they can be referenced in the chrome manifest.
And I have added this section to my index.js file
// Add a root node to the DOM
const rt = document.createElement('div');
rt.setAttribute("id", "my-root");
document.body.appendChild(rt);
ReactDOM.render(<App />, rt);
So far, so good.
When I build the code with npm and load the unpacked directory as a chrome extension all appears well but nothing happens on the page that is loaded (which definitely matches the manifests "match" criteria).
I noticed that when it works using the index.html file, the version of that file that is built by npm includes 3 new sets of elements:
1.) The required div in the html that I'm injecting above:
<div id="loop-root"/>
2.) the following scripts:
<script src="/static/js/2.chunk.js"/> <script src="/static/js/main.chunk.js"/>
3.) between 1 and 2 some inline javascript that looks like this:
<script>!function(f){function e(e){for(var r,t,n=e[0],
.....
;var r=window["webpackJsonploop-messenger"]=window["webpackJsonploop-messenger"]||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;i()}([])</script>
Now, If I include the scripts in "2" above AND I include the inline javascript in "3" in a new js file that I reference as a content-script in the chrone manifest, then the app launches when I reloaded the given page.
Hooray!
... but there are errors in the console like this:
Uncaught (in promise) DOMException
and the app doesn't run correctly.
So, my question is:
a.) What is this inline javascript doing and why is it required in index.html?
b.) Why is it not mentioned in any of the tutorials that are doing this kind of thing?
c.) Is there a simpler way to get this working (surely there is)?

Related

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 build react js static on c panel

I have built my react js app with create-react-app configs and it works fine in development build of React.
I built that with npm build command and now i have build folder.
this web page is static (server-less), Now I want to know how to use that and where put files in Cpanel.
After the bundle realized by webpack, you can check the transpiled and minified version inside the build folder. You should upload all the content to your public_html or another folder.
And the meaning of server-less is totally different than you're using. Check this article to understand what it is: What is serverless.
I do not use CRA boilerplate since i have my own but in your case, you should find where your js bundle is. You can find the bundle location in the webpack config. Then append that to your html somehow like this:
<div id="root"></div>
<script src='your-js-bundle'></script>
Assuming that somewhere in your code, you are appending your js code into a div like this:
const element = <h1>Hello, world</h1>; // assuming element is your entry point
ReactDOM.render(element, document.getElementById('root'));
That works if its just simple react project your working on (No SSR and such)

How to compile sticky state plugin for Angular 1

I need the Sticky States feature for my project.
I'm using UI Router 1.0.0-rc.1 so i can't use the ui-router-extras library (that was designed for 0.xxx)
Recently the author ported that feature for the 1.xx router
https://github.com/ui-router/sticky-states
This release comes only with .ts sources.
My project is written in plain ES5 js, so i tried to build myself the final js to be used in browser with <script src="..." type="text/javascript">
I have npm install all dependancies and then npm run build
What i got are two folders 'lib' and 'lib-esm' that contains each more than one js files that i don't understand how to reference them from .html file (files are index.js & stickyStates.js)
Also tried to run webpack but what i get is a huge file with more than 8K lines of code (probabile also ui-router get bundled within..)
NOTE: Author has already been asked for that by someone but he didn't provided a solution yet:
https://github.com/ui-router/sticky-states/issues/4
Thank you very much

AngularJS blank page on Safari iOS but runs fine everywhere else

I wrote a small AngularJS app that seems to run fine everywhere except in Safari (iOS) where I only see a blank page. If I hook up the phone to my mac and run Web Inspector I can see that there are no javascript errors (in fact the app runs fine and by looking at the DOM I see that scope variables are properly evaluated and replaced in the templates). What I DO see are many CSS errors. If I remove the offending CSS styles (Bootstrap 3) the errors go away yet the page remains blank. I tried removing all CSS and most trivial JS libs to no avail.
I'm using the following JS/CSS (in order of appearance on index.html):
bootstrap.min.css (v3.3.6)
bootstrap-theme.min.css (v3.3.6)
app.css (my own stylesheet which literally has two trivial style definitions)
angular.js (v1.4.9)
angular-route.js (v1.4.9)
ui-bootstrap.js (v1.1.2)
ui-bootstrap-tpls.js (v1.1.2)
lodash.js (v4.5.0)
moment.js (v2.11.2)
app.js (my own app)
Backend: Node 0.10 (running on a free OpenShift account) with Express v4. Files are served via the static middleware. No manual uploading is being done; deployment happens straight from the git repo after doing a push.
EDIT: Completely removed all CSS but problem persists. App fully works everywhere and still showing a blank screen on Safari iOS.

How to run AngularJS example

I've done as described here: http://docs.angularjs.org/tutorial/step_00 but can't run the phonecat example as AngularJS. It runs like a bunch of html files. For example, the app/index-async.html page gives me following error in Chrome's console:
Uncaught Error: No module: myApp
This file contains
angular.bootstrap(document, ['myApp']);
The bootstrap part needs to be called after the element you're bootstrapping to is loaded. You can either put the bootstrap code at the end of your html, or you can use something like document ready from JQuery.
I had the same problem. When loading angular with reguirejs, you have to remove the ng-app directive from the html and add it after calling angular.bootstrap(document, ['myApp']) like this:
$(html).addClass('ng-app');
Check this seed project out: https://github.com/tnajdek/angular-requirejs-seed specifically index.html and app/js/main.js
Make sure your web server is running.
If you are running node.js:
1. Run node scripts\web-server.js to start the web server
2. In your browser, navigate to http://localhost:8000/app/index.html
If you are running some other http server: (I used WAMP for the AngularJS tutorial you listed):
1. Make sure the /angular-phonecat repository was cloned into your wamp/www folder.
2. Navigate in your browser to http://localhost:[port-number]/angular-phonecat/app.
TIPS:
To change directories using WINDOWS COMMAND LINE -
cd /d c:\wamp\www
To change directories using GIT BASH -
$ cd /c/wamp/www
Additional note: In Git Bash, to display the directory you're currently in, use $ pwd

Resources