webpack, process env variable in index.html - javascript

I have a react app which has an entrypoint of my app.jsx and I am adding segment.io to my build, however I would like to set it's API key as an process.env variable. I am having trouble with how to do this with webpack because my entry point is not the index.html.
I am trying to see if there is a way so I can (on the index.html) do something like this
<script type="text/javascript">
..segment script loading here + (process.env.MY_SEGMENT_KEY)}();
</script>
But I am not sure how to get it so I can process env variables at the index.html level.
In app.jsx I am toggling the code like :
if (process.env.MY_SEGMENT_KEY) {
....
}
and this works fine because I have access to the vars at this point. I would like to also conditionally load the script on the index.html. Anyone know if this is possible? Thanks!

Just load analytics in your JSX file as follow:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
if (process.env.MY_SEGMENT_KEY) {
window.analytics.load(process.env.MY_SEGMENT_KEY);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Your index.html file should look like that:
<!DOCTYPE html>
<html>
<head>
...
<title>My App</title>
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0";
}}();
</script>
</head>
<body>
<div id="root">
</div>
</body>
</html>

Related

Can I run index.html with React without npm start and npx create-react-app?

I am self-learning react and I am just confused about a lot of things.
I thought that if I add React to my index.html via a script like the below:-
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bill Details</title>
</head>
<body>
<div id="billTable"></div>
<script src="BillTable.js" type="text/javascript"></script> ------------- Problem Line 1
</script>
</body>
</html>
and this is my js file where I am trying to return react component
//BillTable.js
import React from "react";
import ReactDOM from "react-dom";
function BillTable() {
return <h1>HELLO TABLE</h1>;
}
ReactDOM.render(<BillTable/>, document.getElementById("billTable"));
when I try to open index.html directly in firefox or through express server I get the below error in console:-
Uncaught SyntaxError: import declarations may only appear at top level of a module.
I then got rid of this error by changing the script type in problem line 1 in index.html to
<script src="BillTable.js" type="text/babel"></script>
but then also my webpage is completely blank and even console is not showing any errors.
Please suggest how to solve this issue. I am right now trying to learn React with functional approach only, so if any changes are required to be done on the react side, please make them in the functional approach.
I don't think you have included the correct packages to handle React components and JSX yet. These packages react, react-dom, etc. are usually in a package.json and are required to tell the browser what tools will be used to run the code. These packages handle the "script" or components you create and places the elements constructed in your components to the DOM. You can solve this by loading react with additional script tags before your component's script tag. This will let the browser know how and what to use to run your react component. Also, in your function, it does not know that it is a React Component. Check out an explanation for why you would have to use React.createElement I have attached an example of using only an index.html page here:
example of using an index.html page
Your Component file:
"use strict";
function BillTable() {
return React.createElement("h1", "", "HELLO TABLE");
}
const domContainer = document.querySelector("#billTable");
const root = ReactDOM.createRoot(domContainer);
root.render(React.createElement(BillTable));
and your index.html:
<body>
<div id="billTable"></div>
<!-- Load your React packages -->
<script
src="https://unpkg.com/react#18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"
crossorigin
></script>
<!-- Load your React component. -->
<script src="BillTable.js"></script>
</body>

Vue: Mount Component Directly to Body

I have a component that I want to mount directly to the body but not override the app HTML.
index.html (Basic boilerplate)
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
main.js
import { createApp } from "vue";
import App from "./App.vue";
import BodyComponent from "./BodyComponent.vue";
createApp(App).mount("#app");
createApp(BodyComponent).mount("body");
When I do this, it seems like the mount is greedy and it completely wipes out what was previously on the body (example)... I simply want to append the component to the body. I know that in the index.html file I can add a div with an ID that I want to mount my BodyComponent to, but I want to mount it on the body, nothing else. Is this possible?

import React from "react"; resulting in Uncaught SyntaxError: Unexpected identifier

I am new to ReactJS and all the solutions I found for this problem used npm cli and suggested to use babel-plugin-transform-es2015-modules-amd. However I am using CDN and here is my code:-
1] Here is my index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="js/react.production.min.js"></script>
<script src="js/react-dom.production.min.js"></script>
<script src="js/browser.min.js"></script>
</head>
<body>
<div id="root"></div>
</body>
<script src="js/components/hello.jsx"></script>
</html>
where browser.min.js is actually babel
and the other two react files are of version 16.5.2
2] And hello.jsx:-
import React from "react";
import { render } from "react-dom";
class App extends React.Component {
render() {
return (
<div>
<h1>Hello!</h1>
</div>
);
}
}
render(<App />, document.getElementById("root"));
This code throws an error at line 1 in hello.jsx saying "Uncaught SyntaxError: Unexpected identifier"
Any help is much appreciated. Thanks!
Since hello.jsx is JSX. You need to indicate this to the browser by setting the script attribute.
This is done by setting the script type attribute to text/babel e.g.
<script type="text/babel" src="js/components/hello.jsx"></script>
The babel standalone script traverses the DOM for scripts with this attribute and replaces them with their transpiled equivalents.
Edit
A couple of changes to hello.jsx
Remove the import statements
ReactDOM and React are globals in the context of window object.
Replace
render(<App />, document.getElementById("root"));
with
ReactDOM.render(<App />, document.getElementById("root"));

How to use RequireJs to load React then ReactDom Sequentially?

ReactDOM depends on React to be loaded before it is loaded, in a sequential manner.
I have to load scripts with requirejs, as I cannot change the synchronous loading of js.
I have tried creating a test app but I keep getting the following error: Error: Script error for "react", needed by: helper/react-dom.min
after hello is printed
What I have tried...
Index.html
<!DOCTYPE html>
<html>
<head>
<title>My Sample Project</title>
<!-- data-main attribute tells require.js to load
scripts/main.js after require.js loads. -->
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
<h1>My Sample Project</h1>
</body>
</html>
main.js
require(['helper/react-loader'], function(){
// do something with the loaded modules
console.log('hello);
});
react-loader.js
require(['helper/react.min','helper/react-dom.min'], function(){
// do something with the loaded modules
console.log('react loaded');
});
ReactDOM uses define(['react'], f) to define module (see), so you have to define React module's name equals to react, which means you config requirejs like below:
require.config({
paths: {
'react': 'helper/react.min',
}
});

React.render() is giving error when we create component in one js file and render it in another js file

I am new to Reactjs. I have downloaded the latest bundle of JS files from: https://facebook.github.io/react/docs/getting-started.html
I set path for the JavaScript files in my HTML file and started working on it.
When I create a component in the same file and render the component in same JavaScript file it works fine. But when I create a component in one JavaScript file and render it in another JavaScript file by importing, it is giving me error.
Below is the sample code, which is working:
var FindEmp= React.createClass({
render:function(){
return(
<p>EMPID <input type='text'/></p>
);
}
});
React.render(<FindEmp/> , document.getElementById('content'))
and if write this in 2 files like below its not working
app.js
'use strict';
var React = require('react');
var React = require('react/addons');
var FindEmp= require('./components/FindEmp.react');
React.render(<FindEmp/> , document.getElementById('content')); //This Line is giving me error saying
FindEmp.react.js
var React = require('react');
var ReactPropTypes = React.PropTypes;
var FindEmp = React.createClass({
render:function(){
return(
<p>EMP ID <input type='text'/></p>
);
}
});
module.exports = FindEmp;
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script src="lib/JSXTransformer.js"></script>
<script src="lib/react.js"></script>
<script src="lib/react-with-addons.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="lib/marked.min.js"></script>
</head>
<body>
<script type="text/jsx" src="js/app.js"></script>
<script type="text/jsx">
</script>
</body>
</html>
You did missed
<div id="content"></div>
so
document.getElementById('content')
cant find anything.
And its important to put it above reference to your app.js.
For this sample I was using react.js file . Removed the js file and started using npm react tools and web pack. This solved my problem.
I have gone through the following site for a sample..
http://jmfurlott.com/tutorial-setting-up-a-single-page-react-web-app-with-react-router-and-webpack/

Categories