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

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.

Related

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!

Babel import css syntax error

I want to be able to use import in my react application for not only js/jsx files but also for css files. From what I've read, the best way to do that is to use the extract-text-webpack-plugin which will take your imported css files and bundle them together.
I've set it up so that its generating my bundled css file, but for some reason every time I load my page I get a syntax error:
SyntaxError: MyWebpage/views/global.css: Unexpected token, expected ; (1:5)
> 1 | body {
| ^
2 | margin: 0;
3 | }
My setup looks like this:
webpack.config.js
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const config = {
entry: ['babel-polyfill', './views/Index.jsx'],
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/public'
},
module: {
rules: [
{ test: /\.(jsx|js)$/, exclude: /node_modules/ , use: 'babel-loader' },
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]
};
module.exports = config;
The entry point ./views/Index.js is where I'm importing my css file:
Index.js
import React from 'react';
import Layout from './Layout.jsx';
import PageContent from './PageContent.jsx';
import './global.css';
class Index extends React.Component {
render() {
return (
<Layout title={this.props.title}>
<PageContent />
</Layout>
);
}
}
export default Index;
Inside the imported ./Layout.jsx file I'm using a <link> to include the bundled css file in my page:
Layout.jsx
import React from 'react';
class Layout extends React.Component {
render() {
return (
<html>
<head>
<title>{this.props.title}</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="root">
{this.props.children}
</div>
<script type="text/javascript" src="./bundle.js"></script>
</body>
</html>
);
}
}
export default Layout;
I'm pretty confused because it seems like my app is building fine, but when I try to access my webpage I keep getting a syntax error.
Can anyone please help me understand what I'm doing wrong?
It seems problem with loaders below is example of webpack.config.js file working for jsx and css loaders :
module.exports = {
entry: './app/index.js',
output: {
path: __dirname,
filename: 'dist/bundle.js'
},
devServer: {
inline: true,
port: 3000
},
module: {
loaders: [{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react', 'react-hmre']
}
},
{
test: /\.scss$/,
loaders: [ 'style', 'css', 'sass' ]
}]
}
};
it seems like babel or webpack is not loading the loaders.
This variant helps me with it (just include into webpack.config.js):
require.extensions['.css'] = () => {
return;
};
More here... [link]

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.

Getting Started with React-Hot-Loader

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.

React not loading from babel.rc file

I am receiving a "module parse failed" error when trying to load my react app with Babel6 Stage-1. We initially ran browserify but I am now trying to port us completely to Babel6.
babel.rc file
{
"presets": ["stage-1", "react"],
"env": {
"development": {
"presets": ["react-hmre"]
}
}}
webpack config
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'eventsource-polyfill', // necessary for hot reloading with IE
'webpack-hot-middleware/client',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.jsx?/,
loaders: ['babel'],
include: path.join(__dirname, 'src'),
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style!css'
}]
}
};
I have tried reading the documentation on Babel6 and it seems like I need to include react in my presets along with Stage-1.
I have done both and npm installed:
babel preset stage 1, babel preset react, and babel preset react hmre
Any ideas on how I can get react loading again?
Fixed by adding es2015 to the babel.rc file

Resources