I am not seeing any output on the screen, but I am also not getting any errors. I will post what I can think of being needed. I am starting a new project and trying things a little differently so some help is needed.
Update: Here is how I launch the app. I run npm run server in the console from root directory and this is the script "server": "nodemon --watch server --exec babel-node -- server/index.js"
webpack.config:
import path from 'path';
import webpack from 'webpack';
export default {
devtool: 'eval-source-map',
entry: [
'webpack-hot-middleware/client',
path.join(__dirname, './client/index.js')
],
output: {
filename: 'bundle.js',
path: '/',
publicPath: '/'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [
{
test: /\.js$/,
include: path.join(__dirname, 'client'),
loaders: [ 'react-hot-loader', 'babel-loader' ]
}
]
},
resolve: {
extensions: ['*', '.js']
}
}
index.js:
import React from 'react';
import { render } from 'react-dom';
import App from './components/App';
render(<App />, document.getElementById('app'));
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
</head>
<body>
<div id="app"></div>
<scrip src="bundle.js" type="text/javascript"></scrip>
</body>
</html>
App:
import React from 'react';
class App extends React.Component {
render() {
return (
<h1>!Hello from react!</h1>
)
}
}
export default App;
Server index.js:
import express from 'express';
import path from 'path';
import webpack from 'webpack';
import webpackMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import webpackConfig from '../webpack.config.dev';
const app = express();
const compiler = webpack(webpackConfig);
app.use(webpackMiddleware(compiler));
app.use(webpackHotMiddleware(compiler, {
hot: true,
publicPath: webpackConfig.output.publicPath,
noInfo: true
}));
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, './index.html'));
});
app.listen(3000, () => {
console.log('listening on port 3000');
});
Typo in <scrip src="bundle.js" type="text/javascript"></scrip>
<script> instead <scrip>
Related
I'm curently building a React JS app and I've this error when I go on the '/' of my project :
"Uncaught Error: Target container is not a DOM element."
In my project I've some components and few pages, and when I run my server with "npm start" I can't access to my main page.
My app was build without webpack, I added it after all my components were done.
webpack.config.js :
const path = require('path');
module.exports = {
devServer: {
historyApiFallback: true
},
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader',
],
}
]
}
};
index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>React 101</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
.babelrc :
{"presets": ["#babel/preset-env", "#babel/preset-react"]}
main.js :
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
ReactDom.render(<App />, document.getElementById('app'));
index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import '../src/assets/css/bootstrap/css/bootstrap-theme.min.css';
import '../src/assets/css/bootstrap/css/bootstrap.min.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
I have this app which I'm rendering on the server side. Everything was working fine until I tried to add Material UI to it.
My directory structure is this:
app/
build/ * This is created by webpack
server_bundle.js
public/
client_bundle.js
fonts/
images/
src/
client/
Client.tsx
server/
server.tsx
shared/
App.tsx
routes.tsx
webpack.config.js
And here are my files content:
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
target: 'node',
entry: {
server: path.resolve(__dirname, 'src/server/server.tsx'),
"public/client": path.resolve(__dirname, 'src/client/client.tsx')
},
output: {
filename: '[name]_bundle.js',
path: path.resolve(__dirname, 'build'),
publicPath: '/build'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
module: {
rules: [{
test: /\.(tsx|ts)?$/,
loader: 'awesome-typescript-loader',
options: {
jsx: 'react'
}
},
{
test: /\.(scss|sass|css)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
]
},
{
test: /\.(ico)$/,
loader: 'file-loader',
options: { outputPath: '/public', publicPath: '/public', name: '[name].[ext]' }
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
loader: 'file-loader',
options: { outputPath: '/public/images', publicPath: 'images' }
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options: { outputPath: '/public/fonts', publicPath: 'fonts' }
},
]
},
optimization: {
},
plugins: [
new MiniCssExtractPlugin({
filename: 'public/styles_bundle.css',
chunkFilename: "public/styles/[id].css"
})
]
}
server.tsx
import * as express from "express";
import * as bodyParser from "body-parser";
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import {StaticRouter} from "react-router";
import { matchPath } from "react-router-dom";
import {Helmet} from "react-helmet";
import App from "../shared/App";
import routes from '../shared/routes';
const app = express();
const PORT = process.env.PORT || 3000;
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.static("build/public"));
app.get('*', (req, res, next) => {
const activeRoute = routes.find(route => !!matchPath(req.url, route)) || {path: "/"};
const now = new Date();
console.log(`GET ${now} - ${req.url}`);
const context = {}
const content = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
const helmet = Helmet.renderStatic();
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
${helmet.title.toString()}
${helmet.meta.toString()}
<link rel="stylesheet" href="styles_bundle.css">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
</head>
<body>
<div id="root" style="overflow-x: hidden; width: 100%; margin: 0;">${content}</div>
<script src="client_bundle.js"></script>
</body>
</html>
`;
res.send(html);
});
app.listen(PORT, () => {
console.log(`App is running on port ${PORT}`)
})
Client.tsx
import * as React from "react";
import * as ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import App from "../shared/App";
// Because it's already been rendered, we only need to hydrate event
// handlers and wire things up.
ReactDOM.hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.querySelector("#root")
);
App.tsx
import * as React from 'react';
import routes from "../shared/routes";
import { Helmet } from 'react-helmet';
import { Switch, Route } from "react-router";
import 'typeface-roboto';
class App extends React.Component {
render() {
return (
<React.Fragment>
<Switch>
{routes.map(({path, exact, component: C}) => {
return <Route
path={path}
exact={exact}
render={(props) => <C {...props}/> }
/>
})}
</Switch>
</React.Fragment>
)
}
}
export default App;
And finally, routes.tsx
import * as React from 'react';
import { Button } from '#material-ui/core';
const routes = [
{
name: "Home",
exact: true,
path: "/",
component: (props:any) => {return (
<Button variant="contained" color="primary">
Hello World
</Button>
)}
}
];
export default routes;
I get this error in my browser console and obviously no material ui styles whatsoever:
client_bundle.js:44 Uncaught ReferenceError: global is not defined
at Object.<anonymous> (client_bundle.js:44)
at n (client_bundle.js:1)
at Object.<anonymous> (client_bundle.js:1)
at n (client_bundle.js:1)
at Object.<anonymous> (client_bundle.js:17)
at n (client_bundle.js:1)
at Object.<anonymous> (client_bundle.js:17)
at n (client_bundle.js:1)
at Object.<anonymous> (client_bundle.js:36)
at n (client_bundle.js:1)
That part of the client_bundle.js looks like this:
... __esModule",{value:!0});global.CSS;t.default=function(e){return e}} ...
What do you think might be happenning here??
try this workaround in your
plugins: [
new webpack.DefinePlugin({
'global': {} // webpack workaround
}),
new MiniCssExtractPlugin({
filename: 'public/styles_bundle.css',
chunkFilename: "public/styles/[id].css"
})
]
I am developing in a windows environment for the first time (coming from OS).
I have built the basic foundation for a react app, and webpack builds without errors, but only the raw HTML renders. I.e., the ReactDOM process seems to fail or something because my app component doesn't render at all. Note that I leveraged code from an app I built in OS, wondering if that has something to do with it.
See code below. Thank you for having a look.
First my webpack.config.js file:
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');
const SRC_DIR = path.join(__dirname, '/client/src');
const DIST_DIR = path.join(__dirname, '/client/dist');
module.exports = {
entry: `${SRC_DIR}\\index.js`,
output: {
path: path.resolve(__dirname, 'client/dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.jsx?/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['syntax-dynamic-import'],
},
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
include: SRC_DIR,
},
],
},
resolve: {
extensions: ['.js', '.jsx']
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
}),
new ExtractTextPlugin("styles.css"),
// ,
// new UglifyJSPlugin(),
],
};
Next my html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="https://orig00.deviantart.net/15e4/f/2011/116/f/4/color_wheel_dock_icon_by_andybaumgar-d3ezjgc.png">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<title>SysAdmin Microservices</title>
</head>
<body>
<h1>Node Microservices Server Documentation</h1>
<div id="root"></div>
</body>
</html>
My index.js file with the ReactDOM.render call:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/App.jsx';
ReactDOM.render( <App />, document.getElementById('root'));
Last of all my App.js file:
import React from 'react';
class App extends React {
render() {
console.log('app render has been invoked <-- this never logs to the console ');
return (
<h1>This is the text that does not render in the browser.</h1>
)
}
}
export default App;
You need to have your bundle.js referenced from the index page, else it won't load any of your JS. Will vary based on your folder structure, but something along the lines of this should work:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="dist/bundle.js"></script>
</body>
</html>
Or you could use a Webpack plugin like html-webpack-plugin to inject your bundled JS as a part of your build process.
You can add the script to your bundle manually or use html-webpack-plugin.
This plugin will handle inserting scripts/style to the index html (and more) automatically.
Steps:
Install the plugin: npm install --save-dev html-webpack-plugin
Require it in webpack config: const HtmlWebpackPlugin = require('html-webpack-plugin')
Add the plugin to the plugin config:
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
}),
new ExtractTextPlugin("styles.css"),
// ,
// new UglifyJSPlugin(),
]
I'm a backend guy that has decided to learn some frontend, but it seems that I'm pretty far from learning since I can't even configure the environment.
My goal is to setup Webpack with Babel 6, React, react-hot and HotModuleReplacementPlugin. I also want the app to have express.js server. So here're my configs:
server.js:
var webpack = require('webpack')
var webpackDevMiddleware = require('webpack-dev-middleware')
var webpackHotMiddleware = require('webpack-hot-middleware')
var config = require('./webpack.config')
var app = new (require('express'))()
var port = 4000
var compiler = webpack(config)
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }))
app.use(webpackHotMiddleware(compiler))
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html')
})
app.listen(port, function(error) {
if (error) {
console.error(error)
} else {
console.info("==> http://localhost:%s/", port)
}
})
webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:4000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
preLoaders: [
{ test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ }
],
loaders: [
{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react,plugins[]=transform-runtime'],
include: path.join(__dirname, 'src')
}
]
}
}
public/index.html
<html>
<head>
<title>React setup</title>
</head>
<body>
<div id='root'>
</div>
<script src='bundle.js'></script>
</body>
</html>
src/App.js
import React, { Component } from 'react';
export default class App extends Component {
render() {
return (
<h1>Hello, world!</h1>
);
}
}
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
And here's what I've got in my console (the error is looped):
I’m trying to get react router dynamic routing to work by following this example: https://github.com/rackt/react-router/tree/master/examples/huge-apps
Here’s my setup:
webpack.config.js:
module.exports = {
devtool: 'inline-source-map',
entry: './js/app.js',
output: {
path: '../public',
filename: 'test-app.js',
chunkFilename: '[id].chunk.js',
publicPath: '/public/'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: [
'es2015',
'react'
]
}
}
]
}
./js/app.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { createHistory, useBasename } from 'history';
import { Router } from 'react-router';
const history = useBasename(createHistory)({
basename: '/'
});
const rootRoute = {
component: 'div',
childRoutes: [{
path: '/',
component: require('./components/App')
}]
};
ReactDOM.render(
<Router history={history} routes={rootRoute} />,
document.getElementById('root')
);
./components/App.js:
import React from 'react';
console.log('testing');
export default class App extends React.Component {
render() {
console.log('App');
return (
<div>
App!
</div>
)
}
}
index.html:
<!doctype html>
<html>
<head>
<title>Test App</title>
</head>
<body>
Hello
<div id="root"></div>
<script src="public/test-app.js"></script>
</body>
</html>
When I run the server, I see Hello displayed from index.html, I also see console.log('testing') from App.js, but the actual App.js component does not render. Any ideas why?
Thanks!
EDIT:
If I change ./components/App.js to ES5 syntax below, it works! Why is that? Does react router's component: require('./components/App') not work with ES6?
var React = require('react');
var App = React.createClass({
render: function() {
return (
<div>
App!
</div>
)
}
});
module.exports = App;
I think, you are using Babel 6, where they changed commonjs require syntax.
Now, you need to add the default:
component: require('./components/App').default
I had the same problem, finally found how to make it work.