webpack-hot-middleware doesn't generate hot-update.json file - reactjs

I'm trying to get up and running my app using webpack-dev-middleware, webpack-hot-middle-ware, express and react. But when I startup my code, system doesn't give me [hash].hot-update.json file. When I change something in my code system rebuilds and give such file but with wrong hash in file name. Here is my code:
entry point for development server:
require('ignore-styles').default(undefined, (module, filename) => {
if ((['.png', '.jpg'].some(ext => filename.endsWith(ext)) )) {
module.exports = '/build/' + path.basename(filename);
}
});
require('babel-register')({
ignore: [ /(node_modules)/ ],
presets: ["env", "stage-0", "react"],
plugins: [
'dynamic-import-node',
'syntax-dynamic-import',
'react-loadable/babel'
]
});
const express = require('express');
const path = require('path');
const webpack = require('webpack');
const Loadable = require('react-loadable');
const webpackDevMiddleware = require('webpack-dev-middleware');
const serverRenderer = require('./server').default;
const config = require('../configs/webpack.common.js');
const compiler = webpack(config);
const app = express();
app.use(webpackDevMiddleware(compiler, { serverSideRender: true, publicPath: '/build/', }));
app.use(require("webpack-hot-middleware")(compiler));
app.use(serverRenderer());
Loadable.preloadAll().then(() => {
app.listen(3000, () => console.log('Development server is running on port 3000'));
}).catch(err => {
console.log(err);
});
My webpack.config.js file:
module.exports = [{
name: 'client',
mode: 'development',
target: 'web',
entry: ['webpack-hot-middleware/client', './app/index.js'],
output: {
path: path.join(__dirname, '../build'),
filename: 'client.js',
publicPath: '/build/',
hotUpdateChunkFilename: '[id].[hash].hot-update.js',
hotUpdateMainFilename: '[hash].hot-update.json',
},
devtool: 'source-map',
plugins: [
new ManifestPlugin({
writeToFileEmit: true,
}),
new WriteFilePlugin(),
new webpack.HotModuleReplacementPlugin(),
],
module: {
rules: [
{
test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpg|gif|ico|jpeg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
}
}
]
}
],
},
},
{
name: 'server',
mode: 'development',
target: 'node',
entry: './server/server.js',
externals: [nodeExternals()],
output: {
path: path.join(__dirname, '../build'),
filename: 'server.js',
libraryTarget: 'commonjs2',
publicPath: '/build/',
},
plugins: [
new WriteFilePlugin(),
],
module: {
rules: [
{
test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif|ico|jpeg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
emitFile: false
}
}
]
}
]
}
}];
My package.json file:
{
"name": "xxx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node server/development.js",
"build": "rimraf build && NODE_ENV=production webpack --config configs/webpack.production.js --progress --profile --colors",
"prod": "node server/production.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"css-loader": "^0.28.11",
"express": "^4.16.3",
"file-loader": "^1.1.11",
"ignore-styles": "^5.0.1",
"mini-css-extract-plugin": "^0.4.0",
"node-sass": "^4.9.0",
"react-hot-loader": "^4.1.2",
"rimraf": "^2.6.2",
"sass-loader": "^7.0.1",
"serialize-javascript": "^1.5.0",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.1",
"webpack-manifest-plugin": "^2.0.2",
"webpack-merge": "^4.1.2",
"webpack-node-externals": "^1.7.2",
"write-file-webpack-plugin": "^4.3.2"
},
"dependencies": {
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-helmet": "^5.2.0",
"react-loadable": "^5.3.1",
"react-redux": "^5.0.7",
"react-router-config": "^1.0.0-beta.4",
"react-router-dom": "^4.2.2",
"redux": "^4.0.0",
"redux-thunk": "^2.2.0"
}
}
and my server.js file:
import React from 'react'
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { renderRoutes } from 'react-router-config';
import { Provider } from 'react-redux'
import { Helmet } from 'react-helmet';
import Loadable from 'react-loadable';
import serialize from 'serialize-javascript';
import configureStore from '../app/store';
import routes from '../app/routes';
import template from './template';
const store = configureStore();
const normalizeAssets = (assets) => {
return Array.isArray(assets) ? assets : [assets]
};
const searchModuleFiles = (modules, assets) => {
return modules.map(module => {
let files = [`${module}.js`, `${module}.css`];
return files.map(file => ({ file: assets[file] }));
})
};
export default (stats = null) => (req, res) => {
const context = {};
const modules = [];
let devStats = [];
let mainScript = null;
const content = renderToString(
<Provider store={store}>
<StaticRouter context={context} location={req.url}>
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
{renderRoutes(routes)}
</Loadable.Capture>
</StaticRouter>
</Provider>
);
if(!stats) {
let chunks = res.locals.webpackStats.toJson().children.filter(item => item.name === 'client')[0].assetsByChunkName;
devStats = normalizeAssets(modules.map(module => chunks[module])[0]).map(item => ({ file: `/build/${item}` }));
mainScript = { file: '/build/client.js' };
} else {
mainScript = { file: stats['main.js'] };
}
let bundles = stats ? searchModuleFiles(modules, stats)[0] : devStats;
let scripts = bundles.filter(bundle => bundle.file.endsWith('.js'));
let styles = bundles.filter(bundle => bundle.file.endsWith('.css'));
const helmet = Helmet.renderStatic();
const data = serialize(store.getState());
res.status(200).send(template({ content, data, mainScript, scripts, styles, helmet }));
}
Also any help about server side rendering wanted.

Related

Bundling AWS Amplify UI with WebPack - Uncaught SyntaxError: Invalid or unexpected token

I am trying to use AWS Amplify UI in a React project. However, I receive the following errors after bundling the project with WebPack: Uncaught SyntaxError: Invalid or unexpected token (in Chrome) & SyntaxError: Invalid character '\u00b0' (in Safari). The error does not appear in Firefox.
This occurs when I load the bundled HTML file, after bundling with the webpack command. However, when using webpack serve, I have observed that the page renders as expected, in all the above browsers, with no errors.
package.json
{
"devDependencies": {
"#babel/core": "^7.17.9",
"#babel/preset-env": "^7.16.11",
"#babel/preset-react": "^7.17.12",
"babel-jest": "^27.5.1",
"babel-loader": "^8.2.5",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.7.1",
"eslint": "^8.14.0",
"html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^27.5.1",
"node-polyfill-webpack-plugin": "^1.1.4",
"pa11y": "^6.2.3",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
},
"dependencies": {
"#aws-amplify/ui-react": "^3.0.1",
"#fontsource/poppins": "^4.5.8",
"aws-amplify": "^4.3.26",
"jquery": "^3.6.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = (env, argv) => {
let filename = "[name]-bundle.js";
if (argv.mode == "production") {
filename = "[name]-bundle-[contenthash].js";
}
let config = {
entry: {
app: './src/app.js'
},
output: {
filename,
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
importLoaders: 1,
sourceMap: true
}
}
]
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: "index.html",
chunks: ["app"]
}),
new NodePolyfillPlugin()
],
devtool: 'inline-source-map',
devServer: {
static: './dist',
allowedHosts: "all"
}
};
return config;
};
app.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Button } from '#aws-amplify/ui-react';
import '#aws-amplify/ui-react/styles.css';
import "#fontsource/poppins/index.css";
function App() {
return (
<div>
<p>Testing</p>
<Button variation="primary">Hello world</Button>
</div>
);
}
const domContainer = document.getElementById("container");
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
This is a character encoding issue.
It worked with the WebPack DevServer because charset=utf-8 is automatically appended to the Content-Type header of the response.
Setting the character encoding in the head of the HTML file, as below, resolved this issue.
<meta charset="utf-8" />

Page is not refereshing on file change in React with Webpack & Express configuration

I have created an react application from scratch with the help of webpack and express server. However, everthing is working fine except page is not reloading whenever i do some changes in my react component. Can you please tell me what could be issue with my webpack config or express or package.json file ?
server.js
const express = require("express");
const app = express();
const path = require("path");
const PORT = process.env.PORT || 3000;
// static server
app.use(express.static(path.join(__dirname, "dist")));
// route
app.get("/", (req, res) => {
res.sendFile(__dirname, "/dist/index.html");
});
if (process.env.NODE_ENV !== "production") {
const webpack = require("webpack");
const webpackConfig = require("./webpack.config");
const compiler = webpack(webpackConfig);
app.use(require("webpack-dev-middleware")(compiler));
app.use(
require("webpack-hot-middleware")(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath,
})
);
}
app.listen(PORT, () => {
console.log("listening at localhost:3000");
});
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
mode: "development",
entry: {
app: "./src/hello.jsx",
},
module: {
rules: [
{ test: /\.(js|jsx)$/, use: ["babel-loader"] },
{ test: /\.(css)$/, use: ["style-loader", "css-loader"] },
{ test: /\.(jpg|png|jpeg)$/, use: ["file-loader"] },
{ test: /\.(html)$/, use: ["html-loader"] },
],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: "./src/hello.html",
filename: "index.html",
chunks: ["app"],
}),
],
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
package.json
{
"name": "webpack-react",
"version": "1.0.0",
"description": "react and webpack",
"main": "server.js",
"keywords": [
"react",
"webpack"
],
"author": "james",
"license": "ISC",
"dependencies": {
"express": "^4.18.0",
"react": "^18.1.0",
"react-dom": "^18.1.0"
},
"scripts": {
"start": "node server.js"
},
"devDependencies": {
"#babel/cli": "^7.17.10",
"#babel/core": "^7.18.2",
"#babel/polyfill": "^7.12.1",
"#babel/preset-env": "^7.18.2",
"#babel/preset-react": "^7.17.12",
"babel-loader": "^8.2.5",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-hot-middleware": "^2.25.1"
}
}
hello.jsx
import React from "react";
import ReactDOM from "react-dom";
import "./hello.css";
const Hello = () => {
return (
<div>
<h2>Hello React</h2>
</div>
);
};
if (module.hot) {
module.hot.accept();
}
ReactDOM.render(<Hello />, document.getElementById("root"));

asp.net react webpack 4 Hmr failing with 500 response

After updating to webpack 4.19 Hmr stoped working and throws an error everythime I change something in a code.
project setup:
asp.net core 2.0
react
Web-pack
Recently I've updated from Webpack 2.5 to 4.19 as this kinda big update, I might be missing some configuration, after googling I came here to ask for help.
If I am missing anything, please just ask, I will provide any additional info.
Error I review after updating code:
Project folders/files structure
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const bundleOutputDir = './wwwroot/dist';
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
mode: isDevBuild ? "development" : "production",
entry: {
'main': './ClientApp/boot.tsx',
},
output: {
path: path.join(__dirname, bundleOutputDir),
filename: 'main.js',
publicPath: isDevBuild ? 'dist/' : ""
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
},
module: {
rules: [{
test: /\.tsx?$/,
include: /ClientApp/,
use: 'awesome-typescript-loader?silent=true'
},
{
test: /\.js$/,
include: /ClientApp/,
use: 'source-map-loader',
enforce: 'pre'
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff2|eot|woff|ttf)$/,
use: 'url-loader?limit=25000'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
optimization: isDevBuild ? {} : {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
]
},
plugins: [
new CheckerPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat([
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
]),
externals: {
Config: JSON.stringify(isDevBuild ? require('./appsettings.Development.json') : require('./appsettings.json'))
}
}];
};
webpack.config.vendor.js
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
mode: isDevBuild ? "development" : "production",
stats: {
modules: false
},
resolve: {
extensions: ['.js']
},
module: {
rules: [{
test: /\.(png|jpg|jpeg|gif|svg|woff2|eot|woff|ttf)$/,
use: 'url-loader?limit=25000'
},
{
test: /\.css(\?|$)/,
use: [MiniCssExtractPlugin.loader, 'css-loader?minimize']
},
]
},
optimization: isDevBuild ? {} : {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
]
},
entry: {
vendor: ['bootstrap', 'bootstrap/dist/css/bootstrap.css', 'event-source-polyfill', 'isomorphic-fetch', 'react', 'react-dom', 'react-router-dom', 'jquery'],
},
output: {
path: path.join(__dirname, 'wwwroot', 'dist'),
publicPath: 'dist/',
filename: '[name].js',
library: '[name]_[hash]',
},
plugins: [
new MiniCssExtractPlugin({
filename: "vendor.css",
chunkFilename: "vendor.css"
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
// Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.DllPlugin({
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
name: '[name]_[hash]'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"'
})
]
}];
};
package.json
{
"name": "name",
"private": true,
"version": "0.0.0",
"devDependencies": {
"#types/enzyme": "^3.1.9",
"#types/history": "4.6.0",
"#types/jest": "^22.2.0",
"#types/react": "^16.4.14",
"#types/react-dom": "^16.0.7",
"#types/react-hot-loader": "^4.1.0",
"#types/react-router": "4.0.12",
"#types/react-router-dom": "4.0.5",
"#types/webpack-env": "^1.13.6",
"aspnet-webpack": "^3.0.0",
"aspnet-webpack-react": "^3.0.0",
"awesome-typescript-loader": "3.2.1",
"bootstrap": "3.3.7",
"css-loader": "^0.28.11",
"enzyme": "^3.3.0",
"enzyme-adapter-react-15": "^1.0.5",
"event-source-polyfill": "0.0.9",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.11",
"isomorphic-fetch": "2.2.1",
"jest": "^22.4.2",
"jest-mock-axios": "^1.0.21",
"jquery": "3.2.1",
"json-loader": "^0.5.4",
"mini-css-extract-plugin": "^0.4.3",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-hot-loader": "^3.1.3",
"react-router-dom": "4.1.1",
"react-test-renderer": "^15.6.2",
"react-transition-group": "^2.2.1",
"style-loader": "^0.18.2",
"typescript": "^3.0.3",
"url-loader": "^0.5.9",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^3.3.0",
"webpack-hot-middleware": "^2.24.1"
},
"dependencies": {
"#types/chart.js": "^2.7.25",
"#types/node": "^10.10.3",
"axios": "^0.17.1",
"babel-polyfill": "^6.26.0",
"chart.js": "^2.7.2",
"classnames": "^2.2.5",
"font-awesome": "^4.7.0",
"linq": "^3.1.0",
"moment": "^2.22.2",
"primeicons": "^1.0.0-beta.9",
"primereact": "^1.6.2",
"tslint": "^5.9.1",
"tslint-react": "^3.4.0",
"uglifyjs-webpack-plugin": "^2.0.1"
},
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"build": "./node_modules/.bin/webpack",
"tslint": "tslint -p tsconfig.json",
"debug": "node --debug-brk --inspect ./node_modules/jest/bin/jest -i"
},
"jest": {
"setupFiles": [
"<rootDir>/test-shim.js",
"<rootDir>/test-setup.js"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(ts|tsx)$": "<rootDir>/test-preprocessor.js"
},
"testMatch": [
"**/__tests__/*.(ts|tsx|js)"
]
}
}
entry class - boot.tsx
// tslint:disable-next-line:no-var-requires
require("react-hot-loader/patch");
import "./css/site.css";
import "bootstrap";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { AppContainer } from "react-hot-loader";
import "babel-polyfill";
import { BrowserRouter } from "react-router-dom";
import * as RoutesModule from "./routes";
import
{ AppConfig } from "./appconfig";
import axios, { AxiosRequestConfig } from "axios";
// Import PrimeReact required files and selected theme
import "primereact/resources/primereact.min.css";
import "font-awesome/css/font-awesome.css";
import "primeicons/primeicons.css";
import "primereact/resources/themes/ludvig/theme.css";
import "./css/custom.css";
let routes = RoutesModule.routes;
axios.defaults.headers.common.Authorization = "Basic " + window.btoa(AppConfig.testUser + ":" + AppConfig.testPassword);
function renderApp() {
// This code starts up the React app when it runs in a browser. It sets up the routing
// configuration and injects the app into a DOM element.
const baseUrl = document.getElementsByTagName("base")[0].getAttribute("href")!;
ReactDOM.render(
<AppContainer>
<BrowserRouter children={routes} basename={baseUrl} />
</AppContainer>,
document.getElementById("react-app"),
);
}
renderApp();
// Allow Hot Module Replacement
if (module.hot) {
module.hot.accept("./routes", () => {
routes = require<typeof RoutesModule>("./routes").routes;
renderApp();
});
}
Startup.cs
namespace name
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
//ReactHotModuleReplacement = true,
//HotModuleReplacementEndpoint = "/__webpack_hmr"
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
}
Solved. !
By simply adding babel-loader with all additional dependencies and updating webpack.config.js with
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
babelrc: false,
presets: [
[
"#babel/preset-env",
{
targets: {
browsers: "last 2 versions"
}
}
],
"#babel/preset-typescript",
"#babel/preset-react"
],
plugins: [
["#babel/plugin-proposal-decorators", {
legacy: true
}],
["#babel/plugin-proposal-class-properties", {
loose: true
}],
"react-hot-loader/babel"
]
}
}
},

React minified copy error on production site

I keep getting a React minification warning when opening up my application.
I setup my webpack, package.json and redux store to settings that I thought would disable this warning, but it is still appearing.
Any help would be appreciated. I am copying over the code from my webpack, package.json and redux store. I am hosting my application on heroku.
Store
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers/root_reducer';
const middlewares = [thunk];
if (process.env.NODE_ENV !== 'production') {
const logger = require('redux-logger');
middlewares.push(logger.createLogger());
}
const configureStore = (preloadedState = {}) => (
createStore(
rootReducer,
preloadedState,
applyMiddleware(...middlewares)
)
);
export default configureStore;
Webpack
var path = require('path');
var webpack = require("webpack");
var plugins = [];
var devPlugins = [];
var prodPlugins = [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: true
}
})
];
plugins = plugins.concat(
process.env.NODE_ENV === 'production' ? prodPlugins : devPlugins
)
module.exports = {
entry: './frontend/gym_bump.jsx',
output: {
path: path.resolve(__dirname, 'app', 'assets', 'javascripts'),
filename: './bundle.js',
},
module: {
loaders: [
{
test: [/\.jsx?$/],
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '*']
}
};
package.json
"dependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"chart.js": "^2.6.0",
"jquery": "^3.2.1",
"moment": "^2.18.1",
"react": "^15.6.1",
"react-chartjs-2": "^2.6.1",
"react-dom": "^15.6.1",
"react-infinite-scroll-component": "^2.4.0",
"react-redux": "^5.0.6",
"react-router-dom": "^4.1.2",
"react-simple-charts": "0.0.19",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"salad-ui": "^1.1.50",
"time-input": "^1.5.1",
"webpack": "^3.5.5",
"webpack-uglify-js-plugin": "^1.1.9"
},
"description": "This README would normally document whatever steps are necessary to get the application up and running.",
"version": "1.0.0",
"main": "index.js",
"directories": {
"doc": "docs",
"lib": "lib",
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"webpack": "webpack --watch",
"postinstall": "webpack"
},
"engines": {
"node": "8.2.1",
"npm": "5.3.0"
},
"devDependencies": {
"bundle-collapser": "^1.3.0",
"envify": "^4.1.0",
"uglify-js": "^3.0.28",
"uglify-js-brunch": "^2.10.0",
"uglifyify": "^4.0.3",
"redux-logger": "^3.0.6"
}
}
I fixed this, silly mistake. I was missing plugins: plugins, in my webpack.
module.exports = {
entry: './frontend/gym_bump.jsx',
output: {
path: path.resolve(__dirname, 'app', 'assets', 'javascripts'),
filename: './bundle.js',
},
**plugins: plugins,**
module: {
loaders: [
{
test: [/\.jsx?$/],
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '*']
}
};

Webpack large Bundle Size

I am facing issue due to large webpack bundle size.
The size of my bundle size is nearby 166 kb. I am running webpack with -p flag. Most of the size is due to bundling of react module in my bundle file. So, what I am trying to do is that I am making two bundles: one which contain my app specific code and the other one which contains minified version of the npm which do not change frequently.
My bundle size is now 20 Kb.
Here is my webpack config file :
var path = require('path');
var webpack = require("webpack");
var node_modules_dir = path.resolve(__dirname, 'node_modules');
var config = {
entry: path.resolve(__dirname, 'index.js'),
output: getOutput(),
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
})
],
devtool: process.env.NODE_ENV === 'production' ? false : "eval",
module: {
loaders: [
{
test: /\.scss$/,
include: /src/,
loaders: [
'style',
'css',
'autoprefixer?browsers=last 3 versions',
'sass?outputStyle=expanded'
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'url?limit=8192',
'img'
]
},
{
test: /\.jsx?$/,
exclude: (node_modules_dir),
loaders: [
'react-hot',
'babel-loader?presets[]=stage-0,presets[]=react,presets[]=es2015',
]
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
}
};
module.exports = config;
function getOutput() {
if (process.env.NODE_ENV === 'production') {
return {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
} else {
return {
publicPath: 'http://localhost:3000/',
filename: 'dist/bundle.js'
}
}
}
and here is my code :
import {connect, Provider} from 'react-redux';
import React from "react"
import {createStore, combineReducers} from 'redux';
import reducers from "./reducers";
import {increment} from "./actions/App.js";
var store = createStore(
combineReducers({
...reducers
})
);
class App extends React.Component {
render() {
return <div>
<span>Value is : {this.props.value}</span>
<div onClick={this.props.increment}><span>Increment</span></div>
</div>
}
}
App = connect((state)=> {
return {value: state.app.value}
}, {increment})(App);
module.exports = React.createClass({
render: ()=> {
return <Provider store={store}><App /></Provider>
}
});
and here is my package.json file
{
"name": "Sample App",
"version": "0.0.1",
"private": true,
"scripts": {
"webpack-server": "webpack-dev-server --hot --progress --colors --port 3000",
"serve-web": "npm run webpack-server",
"deploy": "NODE_ENV=production webpack -p --optimize-minimize"
},
"dependencies": {
"babel-core": "6.9.0",
"babel-loader": "6.2.4",
"babel-plugin-transform-runtime": "6.9.0",
"babel-preset-es2015": "6.9.0",
"babel-preset-react": "6.5.0",
"babel-preset-stage-0": "6.5.0",
"babel-relay-plugin": "^0.9.1",
"babel-runtime": "6.9.0",
"css-loader": "^0.23.0",
"file-loader": "^0.8.5",
"http-server": "^0.8.0",
"img-loader": "^1.3.1",
"node-fetch": "^1.5.3",
"postcss-loader": "^0.8.0",
"react": "15.3.2",
"react-dom": "^15.1.0",
"react-hot-loader": "^1.2.8",
"react-redux": "^4.4.5",
"redux": "^3.6.0",
"source-map-loader": "^0.1.5",
"url-loader": "^0.5.7",
"webpack": "1.13.1",
"webpack-dev-server": "1.14.1"
},
"jest": {
"preset": "jest-react-native"
},
"devDependencies": {
"babel-cli": "6.9.0",
"babel-core": "^6.9.0",
"babel-loader": "^6.2.4"
},
"engines": {
"npm": ">=3"
}
}
So, I have changed
module.exports = require('./lib/React');
to
module.exports = window.React;
in react.js file of react module as other npm like redux is also using react npm.
Is it a good thing to apply this patch in react.js file of react npm?
Is it a good thing to make two bundles like this?
You can use source map explorer to detect what is the problem.
https://www.npmjs.com/package/source-map-explorer

Resources