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):
Related
I am begining with React using Webpack to make the configuration. I made all step by step. No error message on console or browser but the h1 that I want to insert doesn't appear.
I know that React is v.18 but I am using React v.17
App.jsx
import React from 'react'
const App = () => {
return (
<h1>Holaaa</h1>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/app.jsx';
ReactDOM.render (<App/>, document.getElementById ("Hello"))
webpack.config.js
const path = require ("path");
const HtmlWebpackPlugin = require ('html-webpack-plugin')
const MiniCssExtractPlugin = require ('mini-css-extract-plugin')
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve (__dirname, 'dist'),
filename: "bundle.js"
},
mode: "development",
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}},
{test: /\html$/,
use: [
{loader: 'html-loader'}
] },
{test: /\.sa[ac]ss$/,
use: ['css-loader',
'style-loader',
'sass-loader']}
]
},
plugins: [
new HtmlWebpackPlugin ({
inject: true,
template: "./public/index.html",
filename: '/menu.html'
}), new MiniCssExtractPlugin ({
filename: "[name].css"
})
]
}
index.html
<title>Document</title>
</head>
<body>
<div id="Hello"> </div>
</body>
</html>
I found the solution. It was the filename config. Was /menu.html. So when localhost was with /menu.html, React render the h1 element.
So, to make render I only have to change /menu.html for index.html in the filename config, refresh and was done!
Webpack-dev-server is so slow in rebuilding my simple app, my app is just one component, index.js
This is config.webpack.js file:
const path = require('path');
const HTMLplugin = require('html-webpack-plugin');
const htmlplugin = new HTMLplugin({
template: './public/index.html'
});
const rules = [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader']
}
];
module.exports = {
entry: path.join(__dirname, 'src', 'index.js'),
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './build')
},
module: { rules },
plugins: [htmlplugin]
}
index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
const App = () => {
return (
<p>Hello World</p>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
I am new to webpack and i can't really understand why it is that slow although i only have one simple component in my project, i don't know if i should show my package.json file or not as i think it is not related to my problem
What am i doing wrong??
How can I use React.js in the front-end of my AdonisJs project?
I've tried to install react with npm install react I thought this will works correctly. I made a file app.js with this code:
var React = require('react');
var ReactDOM = require('react-dom');
export default class Index extends Component {
render() {
return (< h1 > hello world! < /h1>)
}
}
ReactDOM.render( < Index / > , document.getElementById('example'))
But this isn't working at all, I don't know what to do more I have searched about how to use React in Adonis but I didn't find anything interesting.
I strongly suggest you to use WebPack for this task.
create a webpack.config.js file in your root directory:
maybe your code need some changes but this is the idea:
const webpack = require('webpack');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
var pkgBower = require('./package.json');
module.exports = {
target: "web",
devtool: "source-map",
node: {
fs: "empty"
},
entry: {
'app': path.join(__dirname, 'react-app', 'Index.jsx')
},
resolve: {
modules: [__dirname, 'node_modules', 'bower_components'],
extensions: ['*','.js','.jsx', '.es6.js']
},
output: {
path: path.join(__dirname, 'public', 'src'),
filename: '[name].js'
},
resolveLoader: {
moduleExtensions: ["-loader"]
},
module: {
loaders: [
{
test: /jquery\.flot\.resize\.js$/,
loader: 'imports?this=>window'
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react', 'stage-0'],
compact: false
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.woff|\.woff2|\.svg|.eot|\.ttf/,
loader: 'url?prefix=font/&limit=10000'
},
{
test: /\.(png|jpg|gif)$/,
loader: 'url?limit=10000'
},
{
test: /\.scss$/,
loader: 'style!css!sass?outputStyle=expanded'
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new CopyWebpackPlugin([{
from: 'img',
to: 'img',
context: path.join(__dirname, 'react-app')
}, {
from: 'server',
to: 'server',
context: path.join(__dirname, 'react-app')
}, {
from: 'fonts',
to: 'fonts',
context: path.join(__dirname, 'react-app')
}]),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
mangle: true,
sourcemap: false,
beautify: false,
dead_code: true
}),
new webpack.ContextReplacementPlugin(/\.\/locale$/, 'empty-module', false, /js$/)
]
};
Then put your app in your root directory, in a folder react-app/ and your components can go inside that folder:
For example your file: [Index.jsx]
import React from 'react';
import ReactDOM from 'react-dom';
class Index extends Component {
render() {
return (< h1 > hello world! < /h1>)
}
}
ReactDOM.render( < Index / > , document.getElementById('example'));
you don't need to export this Index component in this case, but in case you need to just use export default ComponentName at the end of your component file.
The next step is in your routes file (I'm using AdonisJS 4) but is very similar for the version 3.x
Route.any("*", ({ view, response }) => (
view.render('index')
))
Then your index (.njk, or .edge) file (under resources/views) should look something like this:
<html>
<head>
<link rel="stylesheet" href="/src/styles.css">
<script type="text/javascript" src="/src/app.js"></script>
</head>
<body>
<div id="example"></div>
</body>
</html>
--
You need to install some npm/ packages with npm or yarn,
and remember to run in another terminal window or tab,
webpack -d --watch --progress
Regards.
This works. You are missing React.Component.
var React = require('react');
var ReactDOM = require('react-dom');
export default class Index extends React.Component {
render() {
return (< h1 > hello world! < /h1>)
}
}
ReactDOM.render( < Index / > , document.getElementById('example'))
Alternatively you can use import React, {Component} from 'react'; if you want to use your code structure.
For decoupled use, just build your React app and copy the build to Adonis public folder.
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>
I'm trying to use hot-react-loader in my project.
So I changed some files to work with this but I get an error when I edit a component.
Warning: React.createElement: type should not be null, undefined,
boolean, or number. It should be a string (for DOM elements) or a
ReactClass (for composite components).
[HMR] Cannot apply update. Need to do a full reload!
what am I doing wrong?
webpack.config.dev.js
var webpack = require('webpack');
var path = require('path');
// Questo il plugin di webpack che mi genera il file index.html in dist
var HtmlwebpackPlugin = require('html-webpack-plugin');
const PATHS = {
app: path.join(__dirname, 'app/index'),
build: path.join(__dirname, 'dist')
};
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3500',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
PATHS.app
],
output: {
path: PATHS.build,
filename: 'js/bundle.js'
},
// Questo serve a non specificare le estensioni
resolve: {
extensions: ['', '.js']
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{ test: /\.(png|jpg)$/, loader: "file?limit=1000&name=images/[hash].[ext]" },
{ test: /\.scss$/, loaders: [ 'style','css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]' ] }
]
},
// Porta utilizzata da webpack-dev-server
devServer: {
port: 3500
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlwebpackPlugin({
title: 'React Starter Kit',
hash: true,
inject: false,
appMountId: 'app',
template: 'jade!./app/assets/index.jade'
})
]
};
server.js
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config.dev');
new WebpackDevServer(webpack(config), {
hot: true,
historyApiFallback: true,
stats: {
colors: true
}
}).listen(3500, 'localhost', function (err) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3500');
});
index.js
import ReactDOM from 'react-dom';
import React from 'react';
import App from './app';
import { AppContainer } from 'react-hot-loader';
const root = document.getElementById('app');
ReactDOM.render(
<AppContainer>
<App />
</AppContainer>
, root);
if (module.hot) {
module.hot.accept('./app', () => {
const App = require('./app');
ReactDOM.render(
<AppContainer>
<App />
</AppContainer>
, root);
});
}
app.js
import React from 'react';
import { Router, browserHistory } from 'react-router';
import routes from './routes/routes';
const App = () => (
<Router history={browserHistory} routes={routes} />
);
export default App;
You have to modify the prototype chain of the Router component itself to force render the new stuff.
// Router
import { Router, browserHistory } from 'react-router'
if (process.env.NODE_ENV === 'production') {
// ...
} else {
// the hacky workaround
Router.prototype.componentWillReceiveProps = function (nextProps) {
let components = [];
function grabComponents(routes) {
routes.forEach((route) => {
if (route.component) {
components.push(route.component)
}
if (route.indexRoute && route.indexRoute.component) {
components.push(route.indexRoute.component)
}
if (route.childRoutes) {
grabComponents(route.childRoutes)
}
})
}
grabComponents(nextProps.routes)
components.forEach(React.createElement) // force patching
}
}
The code you see here is an adaptation of https://github.com/gaearon/react-hot-boilerplate/pull/61#issuecomment-211504531