Getting Started with React-Hot-Loader - node.js

I am trying to use React Hot Loader in React. I installed react hot loader by running "npm install --save-dev react-hot-loader". I tried to follow the http://gaearon.github.io/react-hot-loader/getstarted/ but couldn't understand. I am attaching my webpack.config.js and package.json. I made changes as listed in document. But I am not able to see the changes I make in components on the fly. What is wrong?
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devServer: {
inline: true,
contentBase: './src',
port: 3000
},
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./dev/js/index.js' // Your appʼs entry point
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['react-hot','babel'],
exclude: /node_modules/
},
{
test: /\.scss/,
loader: 'style-loader!css-loader!sass-loader'
}
]
},
output: {
path: 'src',
filename: 'js/bundle.min.js'
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin()
]
};
scripts from package.json
"scripts": {
"dev": "webpack",
"start": "webpack-dev-server"
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Webpack</title>
</head>
<body>
<div id="root"></div>
<script src="js/bundle.min.js"></script>
</body>
</html>

Ok, now you need to add the hot loading script to your html file, right before bundle like so:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Webpack</title>
</head>
<body>
<div id="root"></div>
<script src="http://localhost:3000/webpack-dev-server.js"></script>
<script src="js/bundle.min.js"></script>
</body>
</html>
It's under localhost:3000 because I see that in your webpack config. I usually just leave it under :8080, but I think it needs to be like this based on your config.

Related

Converting traditional js include to require JS

I want to convert below html code to requireJS. In this code, I am trying to use JQuery Querybuilder component, however I am getting issues because some of js files are older than requireJS
<!DOCTYPE html>
<html>
<head>
<title>jQuery QueryBuilder</title>
<script src="scripts/dot/doT.js"></script>
<script src="js/libs/jquery/jquery-3.4.1.js" type="text/javascript"></script>
<script src="scripts/jquery-extendext.js" type="text/javascript"></script>
<script src="scripts/bootstrap.min.js" type="text/javascript"></script>
<script src="scripts/query-builder.js" type="text/javascript"></script>
</head>
<body>
<div id="builder"></div>
<script>
var myFilters = [{
id: 'column1',
label: 'Column 1',
type: 'string'
}, {
id: 'column2',
label: 'Column 2',
type: 'double'
}, {
id: 'column3',
label: 'Column 3',
type: 'boolean'
}];
$('#builder').queryBuilder({
filters: myFilters
});
</script>
</body>
</html>
I was able to figure this out, issue was mainly with 'dot/doT' call in query-builder.js file
Below is the code that works for me:
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="js/libs/require/require.js" type="text/javascript"></script>
<script src="require_config.js" type="text/javascript"></script>
</head>
<body>
<div id="elmId">TODO write content</div>
<div id="builder">TODO write content</div>
</body>
<script>
require(['dot/doT','jquery','jquery-extendext','bootstrap','query-builder'], function (dot,$) {
console.log("loaded jquery!!!",$("#elmId"));
var myFilters = [{
id: 'column1',
label: 'Column 1',
type: 'string'
}, {
id: 'column2',
label: 'Column 2',
type: 'double'
}, {
id: 'column3',
label: 'Column 3',
type: 'boolean'
}];
$('#builder').queryBuilder({
filters: myFilters
});
});
</script>
</html>
require_config.js file contains below code:
requirejs.config({
paths: {
jquery: 'js/libs/jquery/jquery-3.4.1.min',
dot:'scripts/dot',
'jquery-extendext': 'scripts/jquery-extendext',
bootstrap:'scripts/bootstrap.min',
'query-builder': 'scripts/query-builder.min'
},
shim: {
jquery: {
exports: ['jQuery', '$']
},
//https://requirejs.org/docs/api.html#config
bootstrap : { "deps" :['jquery'] }
}
});
Hope this helps someone in future.

How do I use ejs templates/partials with webpack?

I'm trying to create a full stack app using Express and ejs, and using webpack to bundle the client side assets. When I set it up without ejs it all works perfectly. The problem has come when I've tried to change the index.html to an index.ejs that uses partials for header, footer etc. Ultimately this will be a multipage app which is why I'm using the ejs templates.
I've tried using ejs-loader (https://www.npmjs.com/package/ejs-loader), ejs-compiled-loader (https://github.com/bazilio91/ejs-compiled-loader) and ejs-html-loader (https://www.npmjs.com/package/ejs-html-loader) without any joy.
Any help would be appreciated. I'm sure it's really straightforward but for the life of me I can't work out how to link up ejs to webpack and get the templates to work.
I've included the code that works with template.html below. I need to know how to change that to use index.ejs?
My file structure looks like this:
--dist (output from webpack)
--src (containing index.ejs)
----partials (containing partials for index.ejs)
app.js
webpack.common.js
webpack.dev.js
webpack.prod.js
package.json
etc.
Index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<% include partials/head %>
</head>
<body>
<main>
<% include partials/main %>
</main>
<% include partials/footer %>
</body>
</html>
And my config files look as follows (I've only included the two that merge to make the build congfig):
webpack.common.js
const path = require("path")
module.exports = {
entry: {
main: "./src/index.js",
vendor: "./src/vendor.js"
},
module: {
rules: [
{
test: /\.html$/,
use: ["html-loader"]
},
{
test: /\.(svg|png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
name: "[name].[hash].[ext]",
outputPath: "imgs"
}
}
}
]
},
}
webpack.prod.js
const path = require("path")
const common = require("./webpack.common")
const merge = require("webpack-merge")
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].js",
path: path.resolve(__dirname, "dist")
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: "./src/template.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
}
})]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contentHash].css",
}),
new CleanWebpackPlugin(),
],
module: {
rules: [{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}]
}
});
This is my first post, if I've not included anything crucial please let me know!
Thanks!

How can I correctly use Create.js within Require.js

———————————————————————————
Trying to use requirejs with easeljs …. this works!
<head>
<title>Trial Run</title>
<link rel="stylesheet" type="text/css" href="mainStyle.css">
<script src="http://code.createjs.com/1.0.0/easeljs.min.js"></script>
<script src="http://code.createjs.com/1.0.0/tweenjs.min.js"></script>
<script data-main="js/app" src="js/lib/require.js"></script>
</head>
———————————————————————————
When I remove the underlined code and setup the ’requirejs.config’ (below),
it fails with … ‘app.html:51 Uncaught ReferenceError: createjs is not defined’
requirejs.config({
"baseUrl": "js/lib",
"paths": {
"app": "../app",
"easel": "//code.createjs.com/1.0.0/easeljs.min.js",
"tween": "//code.createjs.com/1.0.0/tweenjs.min.js"
},
"shim": {
"jquery.alpha": ["jquery"],
"jquery.beta": ["jquery"],
"easel": {
exports: 'createjs'
},
"tween": {
deps: ["easel"],
exports: "Tween"
}
}
});
// Load the main app module to start the app
requirejs(["app/main"]);
———————————————————————————
Picture of File arrangement
———————————————————————————
Syntax is wrong, this works !
requirejs.config({
"baseUrl": "js/lib",
"paths": {
"app": "../app",
"easel": 'easeljs.min',
"tween": 'tweenjs.min'
},
"shim": {
"jquery.alpha": ["jquery"],
"jquery.beta": ["jquery"],
easel: {
exports: 'createjs'
},
tween: {
deps: ['easel'],
exports: 'tween'
}
}
});
// Load the main app module to start the app
requirejs(["app/main"]);

bundle.js not found. React, Node, Webpack

I have generated bundle.js file but it is not available when I run server.
Same thing is for style.css.
Probably error is small but I can't find it.
build
NODE_ENV='production' webpack -p
start
NODE_ENV=production NODE_PATH=./src node server.js
server.js
require('babel-core/register');
['.css', '.less', '.sass', '.ttf', '.woff', '.woff2'].forEach((ext) => require.extensions[ext] = () => {});
require('babel-polyfill');
require('server.js');
webpack.config.js
global.Promise = require('bluebird');
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const publicPath = './public';
const cssName = 'styles.css';
const jsName = 'bundle.js';
const plugins = [
new webpack.DefinePlugin({
'process.env': {
BROWSER: JSON.stringify(true),
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
}
}),
new ExtractTextPlugin(cssName)
];
if (process.env.NODE_ENV === 'production') {
plugins.push(
new CleanWebpackPlugin([ './public/' ], {
root: __dirname,
verbose: true,
dry: false
})
);
plugins.push(new webpack.optimize.DedupePlugin());
plugins.push(new webpack.optimize.OccurenceOrderPlugin());
}
module.exports = {
entry: ['babel-polyfill', './src/client.js'],
debug: process.env.NODE_ENV !== 'production',
resolve: {
root: path.join(__dirname, 'src'),
modulesDirectories: [ 'node_modules' ],
extensions: ['', '.js', '.jsx']
},
plugins,
output: {
path: `${__dirname}/public/`,
filename: jsName,
publicPath
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader!less-loader')
},
{ test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif' },
{ test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg' },
{ test: /\.png$/, loader: 'url-loader?limit=10000&mimetype=image/png' },
{ test: /\.svg/, loader: 'url-loader?limit=26000&mimetype=image/svg+xml' },
{ test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' },
{ test: /\.jsx?$/, loader: process.env.NODE_ENV !== 'production' ? 'react-hot!babel!eslint-loader' : 'babel', exclude: /node_modules/ },
{ test: /\.json$/, loader: 'json-loader' }
]
},
eslint: {
configFile: '.eslintrc'
},
devtool: process.env.NODE_ENV !== 'production' ? 'source-map' : null,
devServer: {
headers: { 'Access-Control-Allow-Origin': '*' }
}
};
src/server.js
...
const assetUrl = process.env.NODE_ENV !== 'production' ? 'http://localhost:8050' : '';
function renderHTML(componentHTML, initialState) {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello React</title>
<link rel="stylesheet" href="${assetUrl}/public/styles.css">
<script type="application/javascript">
window.REDUX_INITIAL_STATE = ${JSON.stringify(initialState)};
</script>
</head>
<body>
<div id="react-view">${componentHTML}</div>
<script type="application/javascript" src="${assetUrl}/public/bundle.js"></script>
</body>
</html>
`;
}
...
any guesses?
In your file you have given the src of the css and bundle.js file to start with http://localhost:8050, but src is always given with relative to the file you are in
you should use
<link rel="stylesheet" href="../public/styles.css">
and
<script type="application/javascript" src="../public/bundle.js"></script>
The path comes from the assumption that public directory is directly outside the src directory.

Local area network visit node server with webpack-dev-server

I build a app with Express, React and Webpack. I used webpack-dev-server and react-hot-loader to live-loding.
The Express server is on port 3000 and the webpack-dev-server servers files on localhost:8080.
Now I want to visit the app from another client in the local area network. I can visit the development machine IP:3000, but can not access the localhost:8080
My webpack.config.dev.js file is:
var webpack = require('webpack');
module.exports = {
devtool: 'inline-source-map',
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./src/client/entry',
],
output: {
path: __dirname + '/public/js',
filename: 'app.js',
publicPath: 'http://localhost:8080/public/js',
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
],
resolve: {
extensions: ['', '.js', '.jsx', '.css']
},
module: {
loaders: [{
test: /\.jsx?$/,
loader: 'react-hot',
exclude: /node_modules/
}, {
test: /\.jsx?$/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
compact: false
},
exclude: /node_modules/
}, {
test: /\.css$/,
loader: 'style-loader!css-loader',
exclude: /node_modules/
}, ]
}
}
and the HTML is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="public/css/bootstrap.min.css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<div id="app">{{ content|safe }}</div>
<script src="http://localhost:8080/public/js/app.js"></script>
</body>
</html>
the webpack-dev-server is
import WebpackDevServer from "webpack-dev-server";
import webpack from "webpack";
import config from "../../webpack.config.dev";
var server = new WebpackDevServer(webpack(config), {
// webpack-dev-server options
publicPath: config.output.publicPath,
hot: true,
stats: { colors: true },
headers: { "Access-Control-Allow-Origin": "*" }
});
server.listen(8080, "localhost", function() {});
I hope I can keep live-reloading on my local development machine and other computer or mobile phone can access the server and static files via development machine IP:3000
I am not familiar with webpack. I just followed some tutorials to build the development environment.
How should I change the config?
If you want to accept connections from other machines other than localhost you need to configure the hostname parameter in your server.listen call. In your case you are just allowing connections on "localhost":
server.listen(8080, "localhost", function() {});
For example, to accept connections on any address just remove that parameter:
server.listen(8080, function() {});
Check server.listen for more info.

Resources