-
Notifications
You must be signed in to change notification settings - Fork 920
Description
That's a popular error already mentioned in other issues but I couldn't find a solution after reading them, maybe because I'm on a MVC project and not a Core project.
My environment : ASP.NET MVC 4 with latest ReactJS.NET packages (5.0.0 alpha 7) using Webpack.
React.Exceptions.ReactNotInitialisedException: 'ReactJS.NET has not been initialised correctly. Please ensure you have called services.AddReact() and app.UseReact() in your Startup.cs file.'
ReactNotInitialisedException: React has not been loaded correctly: missing (React, ReactDOM, ReactDOMServer).Please expose your version of React as global variables named 'React', 'ReactDOM', and 'ReactDOMServer', or enable the 'LoadReact'configuration option to use the built-in version of React.
The thing is I do NOT have a Startup.cs file (MVC project with no OWIN) but the error message might actually be related to Babel, not React itself.
It's a little confusing but some other people mentioned this on StackOverflow for instance (without giving a proper fix though)
I noticed neither my breakpoint in Global.asax.cs (in Application_Start()) nor the one in ReactConfig.cs (in Configure()) are hit before the error on the cshtml view here :
@Html.React("RootComponent", new { initialComments = "", page = "" })
ReactConfig.cs
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.V8;
using React;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(AVAL.FO.Web.UI.ReactConfig), "Configure")]
namespace AVAL.FO.Web.UI
{
public static class ReactConfig
{
public static void Configure()
{
ReactSiteConfiguration.Configuration
.SetReuseJavaScriptEngines(true)
.SetLoadBabel(true)
.SetLoadReact(false)
.SetBabelVersion(BabelVersions.Babel7)
.AddScriptWithoutTransform("~/Scripts/dist/components.js");
JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName;
JsEngineSwitcher.Current.EngineFactories.AddV8();
}
}
}
webpack.config.js
const path = require('path');
var WebpackNotifierPlugin = require("webpack-notifier");
var BrowserSyncPlugin = require("browser-sync-webpack-plugin");
module.exports = {
entry: {
components: './Scripts/expose-components.js',
},
output: {
filename: '[name].js',
globalObject: 'this',
path: path.resolve(__dirname, 'Scripts/dist'),
publicPath: 'dist/'
},
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
optimization: {
runtimeChunk: {
name: 'runtime', // necessary when using multiple entrypoints on the same page
},
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name: 'vendor',
chunks: 'all',
},
},
},
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
loader: 'babel-loader',
}
]
},
devtool: "inline-source-map",
plugins: [new WebpackNotifierPlugin(), new BrowserSyncPlugin()]
};
expose-components.js
// All JavaScript in here will be loaded server-side
// Expose components globally so ReactJS.NET can use them
import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";
import RootComponent from './Components/Test.jsx';
// Needed when we want to bundle React ourselves, also make sure to use SetLoadReact(false) in the ReactConfig.cs file
global.React = React;
global.ReactDOM = ReactDOM;
global.ReactDOMServer = ReactDOMServer;
// Components to expose
global.RootComponent = RootComponent;
Index.cshtml
@using React.RenderFunctions
@using React.Web.Mvc
@{
Layout = "_Layout";
}
@Html.React("RootComponent", new { initialComments = "", page = "" })
<script src="/Scripts/dist/components.js"></script>
@Html.ReactInitJavaScript()
Global.asax.cs (excerpt) (note : I don't have a Startup.cs file in my solution since I'm not in a .NET Core project)
protected void Application_Start(object sender, EventArgs e)
{
ReactConfig.Configure(); //not sure that line is useful though - same error if I remove it
...
}
Please let me know if you need more info regarding my setup, thank you.