Change the entry point in Asp.Net Core's React + Redux starter template to a controller - reactjs

I have successfully installed and run the React + Redux starter template that is provided with .Net Core 2.1 (I'm talking about the project created withdotnet new reactredux).
Now I would like to change my entry point from index.html to my own controller inside the Asp.Net.Core project.
Since the create-react-app is configured to use index.html as an entry point, I've had to:
Delete the index.html file
"Eject" the dependencies (npm run eject) in order to modify the configuration file for webpack (I removed the InterpolateHtmlPlugin and HtmlWebpackPlugin plugins from webpack config, as well as all references to index.html in build.js and start.js
Add a HomeController.cs to the project:
namespace ReactReduxSpa.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
Add the corresponding Index.cshtml file to my project with pretty much the same content as the former index.html file, except that I now manual insert the generated script bundle:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<base href="~/" />
<link rel="manifest" href="~/manifest.json">
<link rel="shortcut icon" href="~/favicon.ico">
</head>
<body>
<div id="root"></div>
<script src="~/static/js/bundle.js" asp-append-version="true"></script>
</body>
</html>
In Startup.cs I changed app.UseMvc(…) to:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
My home controller is now executed when accessing the site and the site itself works as intended. However, I'm getting thousands of errors in the console for these requests:
Looking at the response, I see that the server simply served the content of my Index.cshtml view instead of letting these requests through. I assume these are used for development to sync the site and the sources.
To sum it up: I don't think that I'm doing it the right way, but I don't know how to do it differently. My goal is simply to replace the static index.htm with some dynamic content (some bits need to be generated on server side).

Related

loading script in react components which is in same folder

This might be simple question but I couldn't figure out how to load the external script which is in the same folder using relative path. Below is the src folder snapshot.
Here I am trying to import draggable.js inside the DesignScreen.js components. Here the defined components.
import React from 'react'
import './decorate.css'
const DesignsScreen = () => {
React.useEffect(() => {
const LoadExternalScript = () => {
const externalScript = document.createElement('script')
// externalScript.onerror = loadError;
externalScript.id = 'external'
externalScript.async = true
externalScript.type = 'text/javascript'
externalScript.setAttribute('crossorigin', 'anonymous')
document.body.appendChild(externalScript)
externalScript.src = './draggable.js'
}
LoadExternalScript()
}, [])
return (
<>
<div
id='draggable'
draggable='true'
style={{ backgroundPosition: '0px 0px' }}
></div>
</>
)
}
export default DesignsScreen
I want to load draggable.js without using full path like this: externalScript.src = './draggable.js'. I have googled it for the solution without success. So, I turned up here looking for answer.
If you make your project with CRA, you could just add your external script to public/index.html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<-- Add your script here -->
<title>React App</title>
</head>
externalScript.src = '/src/screens/draggable.js' once try this in our project we are importing script files like this.
Remember that if you are working with external scripts, then the ./ in your externalScript.src is the public directory. After you build your React app there won't be a src folder anymore, just the public folder.
src/screens/ProductBase/DesignsScreen.js file:
let externalScript = document.createElement('script');
externalScript.src = './draggable.js';
externalScript.async = true;
document.body.appendChild(externalScript);
public/draggable.js file:
window.addEventListener('load', () => console.log("Hello World!"));
I tested this sample code and it works. When the browser loads the page the console logs "Hello World!".

Load config in the global window object

I would like to load a configuration file to be used as a global object in various parts of the application.
I do not want to import because I want to keep separate from the bundle.js to be able to change it in the future without touching the app.
I came with this solution, and it works, it is correct? Can I encounter problems attaching the configuration to the window object?
// index.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<script src="appconfig.js" type="text/javascript"></script>
<script src="myAppBundle.js" type="text/javascript"></script>
</head>
<body>
...................
// appconfig.js
var GlobalAppConfig = (function () {
return {
pictures: "https://www.example.com/pictures",
videos: "https://www.example.com/videos",
}
})();
.......................
// App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
pictures: window.GlobalAppConfig.pictures
videos: window.GlobalAppConfig.videos
}
}
A drawback to this technique is that window may not be available in every context, such as a test environment.
Environmental variables would be a conventional solution. You could define them at build time (assuming a Yarn build step):
$ PICTURES_URL='https://www.example.com/pictures' yarn build
Then in your code:
const picturesURL = process.env.PICTURES_URL || '';
Rebuild after changing the environmental variable.

Index.html doesn't load css nor script on nested url

The start point of my React app is:
localhost:3000/Admin
So when i am typing in the url this:
localhost:3000/admin/dashboard/
It works all right. But when I write the next nested url:
localhost:3000/admin/dashboard/new
the index.html doesn’t load my script and css. When I change in the index.html the src url from ./js/admin-app.js to ../../js/admin-app.js it works but not more on the other urls.
Localhost:3000/admin/dashboard
I have tried to set in the index.html base href="./" but it doesn't work.
I can’t find the problem .
my server.js:
app.use('/admin', express.static(path.join(__dirname, 'admin/server/static/')));
app.use('/', express.static(path.join(__dirname, 'server/static/')));
app.get('/admin/*', function(req, res) {
res.sendFile(path.join(__dirname, 'admin/server/static/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
});
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'server/static/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
});
Index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base href="./" />
<title>AdminPage</title>
<link rel="stylesheet" href="css/admin_style.css">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div id="admin-app"></div>
<script src="js/admin_app.js"></script>
</body>
</html>
Solution
My App runs at
Localhost:3000/admin/
Instead of
src="js/admin_app.js" or src="./js/admin_app.js"
i try this
src="/admin/js/admin_app.js"
and it works perfectly
There are a couple of things that we can try.
When setting the index.html, leave the file relative to the base url.
So, instead of:
<script src="js/admin_app.js"></script>
use:
<script src="/js/admin_app.js"></script>
This means that the browser will always search for the file in a url relative to the base app, for example:
http://localhost/js/admin_app.js
or something like:
http://myurl.com/js/admin_app.js
So your admin_app.js file HAS to be in that folder (js). In your case, you have a static folder structure like this:
server/static
so the file has to be in:
server/static/js/admin_app.js
This is because in your server you are routing all the requests to / into the folder server/static/.
Basically, you must point to the correct file using your folder structure. You also have a folder called admin, so if the files are in admin/server/static then the relative url should be:
<script src="/admin/js/admin_app.js"></script>
So, it all depends on where the files exactly are in your folder structure.
Do the same for the css:
<link rel="stylesheet" href="/css/admin_style.css">
or
<link rel="stylesheet" href="/admin/css/admin_style.css">
Remove this from your index.html file (you don't need it):
<base href="./" />

yeoman add twitter bootstrap

I am trying to use Yeoman for the first time.
And I want to use Bootstrap for CSS styling.
I've added it to the dependencies and I've npm installed it. It exist it node_modules.
Now I wonder if there is a smart way to require or include it to my project, or should I just go into index.html and reference it from modules?
index.js
var angular = require('angular');
var test = require('./app/controllers/main');
require('angular-ui-router');
var routesConfig = require('./routes');
require('./index.scss');
var app = 'app';
module.exports = app;
angular
.module(app, ['ui.router'])
.config(routesConfig)
.component('app', test);
index.html
<!doctype html>
<html>
<head>
<base href="/">
<meta charset="utf-8">
<title>Crossfit</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="icon" type="image/png" href="http://fountainjs.io/assets/imgs/fountain.png" />
</head>
<body ng-app="app">
<ui-view></ui-view>
</body>
</html>
Yeoman is a scaffolding tool used for webApps' creation : meaning it helps you with the creation of the basic skeleton (libs,code architecture and file organization ).
As for dependencies use inside your project, you need to implement it manually and according to your needs.
Since it's not a repetitive task, you don't need to automate it.

React: Use environment variables

How can I use environment variables defined in .bash_profile in a React application? I have two React apps in production (they're the same project, so they have the same code), but they need to request to different API hosts, and I figured env variables could do the trick.
Use webpack.DefinePlugin. Say you exported FOO and BAR in your .bash_profile, then your webpackconfig should look like:
const config = {
entry: 'somescript',
// ...
module: {
// ...
},
// ...
plugins: [
// ... your plugins
new webpack.DefinePlugin({
'process.env':{
'FOO': process.env.FOO,
'BAR': process.env.BAR
}
})
],
// ...
}
You will be able to access those in your js at compile time via process.env.FOO & process.env.BAR
Resource: https://github.com/topheman/webpack-babel-starter
Store the environment variables in the index.html!
if you treat the index.html like a deployment manifest that contains environment-specific values, you can use the same versioned assets (js, css) in every environment!
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="https://assets.myapp.com/favicon.ico">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="https://assets.myapp.com/manifest.json">
<title>React App</title>
<script>
env = {
// Add your environment variables here
api: "https://staging-api.myapp.com"
};
</script>
<link href="https://assets.myapp.com/static/css/main.6bd13355.chunk.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
<script src="https://assets.myapp.com/static/js/1.a700ff87.chunk.js"></script>
<script src="https://assets.myapp.com/static/js/main.3ec5cdc6.chunk.js"></script>
</body>
</html>
In your code reference the values directly: myApi = window.env.api;
Read more documentation for this methodology at https://immutablewebapps.org

Resources