Import Unity file in React project - javascript

I am having trouble loading a Unity file in my React project. I thought if I add the file in index.html I would be able to use UnityLoader anywhere in the project as shown below:
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Game</title>
</head>
<body>
<div id="app">
</div>
<script src="UnityLoader.js"></script>
</body>
</html>
Unity.js
class Unity extends Component {
render() {
return (
<div id="unity">
{UnityLoader.instantiate('unity', 'unity/index.html')}
</div>
);
}
}
However, I get an error saying UnityLoader is undefined.
Do I need to use some sort of
import { UnityLoader } from 'UnityLoader'
in Unity.js? The issue is that UnityLoader is an external JS file and does not export anything.

Why not installing React-Unity via npm and then import it into your component?
import React, { Component } from 'react';
import { Unity } from 'react-unity-webgl';
export class App extends Component {
render() {
return (<div className="app">
<Unity src="Build/myGame.json" />
</div>)
}
}
Don't forget to add a script tag to load the UnityLoader.js file, exported by Unity in your base html file.
<script src="build_unity/Build/UnityLoader.js"></script>
<script src="compiled/bundle.js"></script>

Related

ASP.NET - Uncaught SyntaxError: Cannot use import statement outside a module

I am trying to use the import keyword in a .jsx file in my ASP.NET MVC 5 project. I want to be able to import other React components into another React component, however, when using the import keyword, I am getting the following error:
Uncaught SyntaxError: Cannot use import statement outside a module
Below is my code:
Index.cshtml:
#{
Layout = null;
}
<html>
<head>
<title>Hello React</title>
</head>
<body>
<div id="content"></div>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.development.js"></script>
<script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js"></script>
<script src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
</body>
</html>
Tutorial.jsx:
import Comment from '../Scripts/Comment.jsx';
class Tutorial extends React.Component {
render() {
return (
<div className="commentBox">
<h1>Homepage</h1>
<Comment />
</div>
);
}
}
ReactDOM.render(<Comment />, document.getElementById('content'));
Comment.jsx:
class Comment extends React.Component {
render() {
return (
<p>I am a comment!</p>
);
}
}
export default Comment;
If I do not have the imports or if I add the Comment class directly inside of the Tutorial.jsx, it runs fine, but that is not what I am looking for. I want to be able to have all my components in separate .jsx files and be able to import certain components into different ones. Ideas?
EDIT: Fixed export default Comment, however error is still appearing
The error "Cannot use import statement outside a module" results when a <script> element contains an import statement but the <script> element itself is not declared as an ECMAScript (or ES) module.
The import statement requires your script file Tutorial.jsx to be declared a module. Add the type attribute with the value module to the <script> tag.
See the first paragraph at the top of the page https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
The import statement cannot be used in embedded scripts unless such script has a type="module".
In your HTML page, change:
<script src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
to
<script type="module" src="#Url.Content("~/Scripts/Tutorial.jsx")"></script>
You need to export the Comment component properly. At the moment you are doing export default Test.
class Comment extends React.Component {
render() {
return (
<p>I am a comment!</p>
);
}
}
export default Comment; //<------- see here

In browser JS code that imports from ES6 module is not executed

I have an ES6 module (mymodule) and HTML page that has JS code that must be executed when a user opens the page. This is my module:
//mymodule.js
class TestClass {
getString() {
return "TestString";
}
}
export {TestClass}
And this is my page:
//page.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Page</title>
<script src="./mymodule.js" type="module"></script>
</head>
<body>
<h1>Hello World!</h1>
<script type="module">
import {TestClass} from "./mymodule";
let test = new TestClass();
console.log("OUTPUT: " + test.getString());
</script>
</body>
</html>
Page.html and mymodule.js are in the same folder, however, when I open page.html in browser I have nothing on console (no error, no output) - I use FF 62.0.3. How to fix it?
<script src="./mymodule.js" type="module"></script>
The above is not needed. You can remove it.
import {TestClass} from "./mymodule";
Browsers don't do file extension resolution the way Node.js does. (They can't, because they deal in URLs and not file systems, so there is no way to get a list of files in a directory).
You need to be explicit with the URL:
import {TestClass} from "./mymodule.js";
NB: You also need to load page.html over HTTP and not from the local file system.
You can export your class to default keyword.
class TestClass {
getString() {
return "TestString";
}
}
export default {TestClass}

NextJS having links in the _document

Working on a application which uses NextJS. Having the following problem. When I have a _document file like this:
import Document, { Head, Main, NextScript } from 'next/document';
import Header from '../components/header/header';
export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
</Head>
<body>
<Header /> // Header is custom component
<Main />
<NextScript />
</body>
</html>
)
}
}
And my Header component is as follows:
import React, { Component } from 'react';
import { withRouter } from 'next/router';
import Link from 'next/link';
class navigationMobile extends Component {
render() {
return (
<nav>
<Link href="/auth"><a>Auth</a></Link>
</nav>
);
}
}
export default withRouter(navigationMobile);
Because this link is placed outside of the file it will reload the page for some reason. This will lose the application state and ruin UX and kind off defeats the purpose of implementing something with a SPA.
When I place the Header component in a page itself the routing works fine. The problem however is that I would have to put this component in every page.
Question:
Is there a way to not reload the page and still have the header component only in one place of the application?
You can use a custom _app.js. This is the correct place where to put a custom layout.
https://github.com/zeit/next.js/tree/master#custom-app

Very Simple clock in react js

How to use setInterval function in react to repeatedly render a function in react . Please provide a very simple example . I am using Node js local environment. Here I am trying for a simple clock given in react documentation (but mine file structure is different). I don't know about didMount etc.. Just starting.
Below is my App.jsx
import React,{ Component } from 'react';
class App extends Component {
good(){
{new Date().toLocaleTimeString()}
}
render() {
return (
<p>{setInterval(()=>this.good(),500)}</p>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />, document.getElementById('app'));
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
My folder structure is like below
I suggest you to read more about React components, state and props as these are fundamental parts for which you have chosen to use React in first place. Basic steps would be:
Store time as state of your component.
Start ticking functionality as soon as your component loads (that is what componentDidMount does - it's triggered when component loads in page)
On each tick use setState to change time value (setState triggers render)
If you follow these steps you would achieve similar result to example from React site, and this is how it should really be done (if you really want to do it in React design)

webpack, process env variable in index.html

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>

Categories