I've been using React 16.x.x and Jqwidgets 6.2.0 and React Boilerplate 3.7.0. My whole project was mounted over the React Boilerplate scaffold with its own configuration of webpack. I set jqwigets-scripts as a npm dependency and I tried excluding node_modules but including jqwidgets-scripts/jqwidgets-react through a regular expression as I read in some github. This is my current webpack.base.babel.js file:
...
module: {
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with Babel
exclude: /node_modules\/(?!(jqwidgets-scripts\/jqwidgets-react)\/).*/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
...
With this configuration webpack compiles with no warnings and no errors like a charm, that is to say npm start. The big deal comes out to stage if I say npm run-script build, if so it complains with this:
Hash: 7b0feef0f8bbac0c9421
Version: webpack 4.27.1
Time: 41489ms
Built at: 2019-01-24 08:13:05
251 assets
Entrypoint main = runtime~main.43b100be02c6a9dbfc5a.js vendor.4d1e1f30cd3a7c98cfd8.chunk.js main.5ce13ffd96704eeb6b0d.chunk.js
ERROR in ./node_modules/jqwidgets-scripts/jqwidgets-react/react_jqxgrid.js 1216:12
Module parse failed: Unexpected token (1216:12)
You may need an appropriate loader to handle this file type.
| render() {
| return (
> <div id={this.state.id}>{this.props.value}{this.props.children}</div>
| )
| };
# ./app/modules/MyModule_1/index.js 43:0-70 954:37-44
# ./app/modules/MyModule_2/Loadable.js
# ./app/modules/MyModule_3/_nav.js
# ./app/modules/MyModule_4/index.js
# ./app/modules/MyModule_5/Loadable.js
# ./app/containers/MainLayout/_nav.js
# ./app/containers/MainLayout/index.js
# ./app/containers/MainLayout/Loadable.js
# ./app/containers/App/index.js
# ./app/app.js
# multi ./node_modules/react-app-polyfill/ie11.js ./app/app.js
I tried changing my webpack configuration as recommended in the official jqwidgets page (https://www.jqwidgets.com/community/topic/webpack-module-parse-failed/) like this:
module: {
rules: [
{
test: /\.js$/,
exclude: '/node_modules',
include: '/node_modules/jqwidgets-scripts/jqwidgets-react',
use: {
loader: 'babel-loader',
options: options.babelQuery
}
},
Then the complain is this while running npm start:
webpack built be60767d46a99fe48e6b in 1353ms
✖ 「wdm」:
ERROR in ./app/app.js 80:4
Module parse failed: Unexpected token (80:4)
You may need an appropriate loader to handle this file type.
| const render = messages => {
| ReactDOM.render(
> <AppContainer>
| <Provider store={store}>
| <LanguageProvider messages={messages}>
# multi ./node_modules/react-app-polyfill/ie11.js webpack-hot-middleware/client?reload=true ./app/app.js main[2]
Also, this is my babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
modules: false,
},
],
'#babel/preset-react',
],
plugins: [
'styled-components',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-syntax-dynamic-import',
],
env: {
production: {
only: ['app'],
plugins: [
'lodash',
'transform-react-remove-prop-types',
'#babel/plugin-transform-react-inline-elements',
'#babel/plugin-transform-react-constant-elements',
],
},
test: {
plugins: [
'#babel/plugin-transform-modules-commonjs',
'dynamic-import-node',
],
},
},
};
My package.json:
{
"name": "react-boilerplate",
"version": "3.7.0",
"description": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices",
"repository": {
"type": "git",
"url": "git://github.com/react-boilerplate/react-boilerplate.git"
},
"engines": {
"npm": ">=5",
"node": ">=8.10.0"
},
"author": "Max Stoiber",
"license": "MIT",
"scripts": {
"analyze:clean": "rimraf stats.json",
"preanalyze": "npm run analyze:clean",
"analyze": "node ./internals/scripts/analyze.js",
"extract-intl": "node ./internals/scripts/extract-intl.js",
"npmcheckversion": "node ./internals/scripts/npmcheckversion.js",
"preinstall": "npm run npmcheckversion",
"prebuild": "npm run build:clean",
"build": "cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
"build:clean": "rimraf ./build",
"start": "cross-env NODE_ENV=development env-cmd .env node server",
"start:tunnel": "cross-env NODE_ENV=development ENABLE_TUNNEL=true node server",
"start:production": "npm run test && npm run build && npm run start:prod",
"start:prod": "cross-env NODE_ENV=production node server",
"presetup": "npm i chalk shelljs",
"setup": "node ./internals/scripts/setup.js",
"clean": "shjs ./internals/scripts/clean.js",
"clean:all": "npm run analyze:clean && npm run test:clean && npm run build:clean",
"generate": "plop --plopfile internals/generators/index.js",
"lint": "npm run lint:js",
"lint:css": "stylelint './app/**/*.js'",
"lint:eslint": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts",
"lint:eslint:fix": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts --fix",
"lint:js": "npm run lint:eslint -- . ",
"lint:staged": "lint-staged",
"pretest": "npm run test:clean && npm run lint",
"test:clean": "rimraf ./coverage",
"test": "cross-env NODE_ENV=test jest --coverage",
"test:watch": "cross-env NODE_ENV=test jest --watchAll",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"prettify": "prettier --write"
},
"lint-staged": {
"*.js": [
"npm run lint:eslint:fix",
"git add --force"
],
"*.json": [
"prettier --write",
"git add --force"
]
},
"pre-commit": "lint:staged",
"resolutions": {
"babel-core": "7.0.0-bridge.0"
},
"dependencies": {
"#coreui/coreui": "^2.1.4",
"#coreui/coreui-plugin-chartjs-custom-tooltips": "^1.2.0",
"#coreui/icons": "^0.3.0",
"#coreui/react": "^2.1.1",
"ajv": "^6.6.1",
"babel-polyfill": "^6.26.0",
"block-ui": "^2.70.1",
"bootstrap": "^4.1.3",
"chalk": "^2.4.1",
"chart.js": "^2.7.3",
"classnames": "^2.2.6",
"compression": "^1.7.3",
"connected-react-router": "^4.5.0",
"core-js": "^2.6.0",
"env-cmd": "^8.0.2",
"exports-loader": "^0.7.0",
"flag-icon-css": "^3.2.1",
"font-awesome": "^4.7.0",
"fontfaceobserver": "2.0.13",
"history": "^4.7.2",
"hoist-non-react-statics": "3.0.1",
"immutable": "^3.8.2",
"intl": "^1.2.5",
"invariant": "^2.2.4",
"ip": "^1.1.5",
"is-url-external": "^1.0.3",
"isnumeric": "^0.3.3",
"jquery": "^3.3.1",
"jqwidgets-scripts": "^6.2.0",
"loadable-components": "^2.2.3",
"lodash": "^4.17.11",
"minimist": "1.2.0",
"moment": "^2.22.2",
"numeral": "^2.0.6",
"prop-types": "^15.6.2",
"react": "^16.6.3",
"react-chartjs-2": "^2.7.4",
"react-dom": "^16.6.3",
"react-helmet": "^5.2.0",
"react-hot-loader": "^4.6.3",
"react-intl": "^2.7.2",
"react-loadable": "^5.5.0",
"react-redux": "^5.1.1",
"react-router-dom": "^4.3.1",
"react-sizeme": "^2.5.2",
"reactstrap": "^6.5.0",
"redux": "^4.0.1",
"redux-immutable": "^4.0.0",
"redux-saga": "^0.16.2",
"reselect": "4.0.0",
"resize-sensor": "0.0.6",
"sanitize.css": "4.1.0",
"simple-line-icons": "^2.4.1",
"styled-components": "^4.1.2",
"warning": "^4.0.2"
},
"devDependencies": {
"#babel/cli": "7.1.2",
"#babel/core": "7.1.2",
"#babel/plugin-proposal-class-properties": "7.1.0",
"#babel/plugin-proposal-export-namespace-from": "^7.2.0",
"#babel/plugin-syntax-dynamic-import": "7.0.0",
"#babel/plugin-transform-modules-commonjs": "7.1.0",
"#babel/plugin-transform-react-constant-elements": "7.0.0",
"#babel/plugin-transform-react-inline-elements": "7.0.0",
"#babel/polyfill": "^7.0.0",
"#babel/preset-env": "7.1.0",
"#babel/preset-react": "7.0.0",
"#babel/register": "7.0.0",
"add-asset-html-webpack-plugin": "3.1.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.1",
"babel-loader": "8.0.4",
"babel-plugin-dynamic-import-node": "2.2.0",
"babel-plugin-lodash": "3.3.4",
"babel-plugin-react-intl": "3.0.1",
"babel-plugin-react-transform": "3.0.0",
"babel-plugin-styled-components": "1.8.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.19",
"circular-dependency-plugin": "5.0.2",
"compare-versions": "3.4.0",
"compression-webpack-plugin": "2.0.0",
"copy-webpack-plugin": "^4.6.0",
"coveralls": "3.0.2",
"cross-env": "^5.2.0",
"css-loader": "1.0.0",
"enzyme": "3.7.0",
"enzyme-adapter-react-16": "1.6.0",
"enzyme-to-json": "3.3.4",
"eslint": "5.7.0",
"eslint-config-airbnb": "17.1.0",
"eslint-config-airbnb-base": "13.1.0",
"eslint-config-prettier": "3.1.0",
"eslint-import-resolver-webpack": "0.10.1",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-prettier": "3.0.0",
"eslint-plugin-react": "7.11.1",
"eslint-plugin-redux-saga": "0.9.0",
"express": "^4.16.4",
"file-loader": "2.0.0",
"html-loader": "0.5.5",
"html-webpack-plugin": "3.2.0",
"http-proxy-middleware": "^0.19.1",
"image-webpack-loader": "^4.6.0",
"imports-loader": "0.8.0",
"jest-cli": "23.6.0",
"jest-styled-components": "6.2.2",
"lint-staged": "7.3.0",
"ngrok": "3.1.0",
"node-plop": "0.16.0",
"node-sass": "^4.11.0",
"null-loader": "0.1.1",
"offline-plugin": "5.0.5",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"plop": "2.1.0",
"pre-commit": "1.2.2",
"prettier": "1.14.3",
"react-app-polyfill": "0.1.3",
"react-test-renderer": "16.6.0",
"rimraf": "2.6.2",
"sass-loader": "^7.1.0",
"shelljs": "^0.8.3",
"style-loader": "0.23.1",
"stylelint": "9.6.0",
"stylelint-config-recommended": "2.1.0",
"stylelint-config-styled-components": "0.1.1",
"stylelint-processor-styled-components": "1.5.0",
"svg-url-loader": "2.3.2",
"terser-webpack-plugin": "1.1.0",
"uglifyjs-webpack-plugin": "^2.0.1",
"url-loader": "1.1.2",
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "3.4.0",
"webpack-hot-middleware": "2.24.3 ",
"webpack-pwa-manifest": "3.7.1",
"whatwg-fetch": "3.0.0"
}
}
My webpack.prod.babel.js:
// Important modules this config uses
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const OfflinePlugin = require('offline-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = require('./webpack.base.babel')({
mode: 'production',
// In production, we skip all hot-reloading stuff
entry: [
require.resolve('react-app-polyfill/ie11'),
path.join(process.cwd(), 'app/app.js'),
],
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
warnings: false,
compress: {
comparisons: false,
},
parse: {},
mangle: true,
output: {
comments: false,
ascii_only: true,
},
},
parallel: true,
cache: true,
sourceMap: true,
}),
],
nodeEnv: 'production',
sideEffects: true,
concatenateModules: true,
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 10,
maxInitialRequests: 3,
name: true,
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
},
main: {
chunks: 'all',
minChunks: 2,
reuseExistingChunk: true,
enforce: true,
},
},
},
runtimeChunk: true,
},
plugins: [
// Minify and optimize the index.html
new HtmlWebpackPlugin({
template: 'app/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
inject: true,
}),
// Put it in the end to capture all the HtmlWebpackPlugin's
// assets manipulations and do leak its manipulations to HtmlWebpackPlugin
new OfflinePlugin({
relativePaths: false,
publicPath: '/',
appShell: '/',
// No need to cache .htaccess. See http://mxs.is/googmp,
// this is applied before any match in `caches` section
excludes: ['.htaccess'],
caches: {
main: [':rest:'],
// All chunks marked as `additional`, loaded after main section
// and do not prevent SW to install. Change to `optional` if
// do not want them to be preloaded at all (cached only when first loaded)
additional: ['*.chunk.js'],
},
// Removes warning for about `additional` section usage
safeToUseOptionalCaches: true,
}),
new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8,
}),
new WebpackPwaManifest({
name: 'React Boilerplate',
short_name: 'React BP',
description: 'My React Boilerplate-based project!',
background_color: '#fafafa',
theme_color: '#b1624d',
inject: true,
ios: true,
icons: [
{
src: path.resolve('app/images/icon-512x512.png'),
sizes: [72, 96, 128, 144, 192, 384, 512],
},
{
src: path.resolve('app/images/icon-512x512.png'),
sizes: [120, 152, 167, 180],
ios: true,
},
],
}),
new HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 20,
}),
],
performance: {
assetFilter: assetFilename =>
!/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename),
},
});
My webpack.dev.babel.js:
/**
* DEVELOPMENT WEBPACK CONFIGURATION
*/
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
module.exports = require('./webpack.base.babel')({
mode: 'development',
// Add hot reloading in development
entry: [
require.resolve('react-app-polyfill/ie11'),
'webpack-hot-middleware/client?reload=true',
path.join(process.cwd(), 'app/app.js'), // Start with js/app.js
],
// Don't use hashes in dev mode for better performance
output: {
filename: '[name].js',
chunkFilename: '[name].chunk.js',
},
optimization: {
splitChunks: {
chunks: 'all',
},
},
// Add development plugins
plugins: [
new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
new HtmlWebpackPlugin({
inject: true, // Inject all files that are generated by webpack, e.g. bundle.js
template: 'app/index.html',
}),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/, // exclude node_modules
failOnError: false, // show a warning when there is a circular dependency
}),
],
// Emit a source map for easier debugging
// See https://webpack.js.org/configuration/devtool/#devtool
devtool: 'eval-source-map',
performance: {
hints: false,
},
});
And finally my webpack.base.babel.js:
/**
* COMMON WEBPACK CONFIGURATION
*/
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const config = require('../../server/config');
// Remove this line once the following warning goes away (it was meant for webpack loader authors not users):
// 'DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic,
// see https://github.com/webpack/loader-utils/issues/56 parseQuery() will be replaced with getOptions()
// in the next major version of loader-utils.'
process.noDeprecation = true;
module.exports = options => ({
mode: options.mode,
entry: options.entry,
output: Object.assign(
{
// Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
},
options.output,
), // Merge with env dependent settings
optimization: options.optimization,
module: {
rules: [
{
test: /\.js$|\.jsx$/, // Transform all .js files required somewhere with Babel
exclude: /node_modules\/(?!(jqwidgets-scripts\/jqwidgets-react)\/).*/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
// {
// test: /\.js$|\.jsx$/,
// exclude: '/node_modules',
// include: '/jqwidgets-scripts/jqwidgets-react',
// use: {
// loader: 'babel-loader',
// options: options.babelQuery
// }
// },
{
// Preprocess our own .css files
// This is the place to add your own loaders (e.g. sass/less etc.)
// for a list of loaders, see https://webpack.js.org/loaders/#styling
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
// Preprocess 3rd party .css files located in node_modules
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(eot|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
// Inline files smaller than 10 kB
limit: 10 * 1024,
noquotes: true,
},
},
],
},
{
test: /\.(jpg|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// Inline files smaller than 10 kB
limit: 10 * 1024,
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
enabled: false,
// NOTE: mozjpeg is disabled as it causes errors in some Linux environments
// Try enabling it in your environment by switching the config to:
// enabled: true,
// progressive: true,
},
gifsicle: {
interlaced: false,
},
optipng: {
optimizationLevel: 7,
},
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
// Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
// inside your code for any environment checks; Terser will automatically
// drop any unreachable code.
/* new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}), */
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(config.env),
HOST: JSON.stringify(config.server_host),
PORT: JSON.stringify(config.server_port)
},
}),
new webpack.NamedModulesPlugin(),
new CopyWebpackPlugin([{ from: 'static' }]),
]),
resolve: {
modules: ['node_modules', 'app'],
extensions: ['.js', '.jsx', '.react.js'],
mainFields: ['browser', 'jsnext:main', 'main'],
alias: {
moment$: 'moment/moment.js',
},
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});
My question is, how to configure webpack in order to work properly in production mode?
Related
What is the problem with my project? I receive an empty page after successful deployment to vercel.
package.json:
{
"name": "currency-converter",
"version": "1.0.0",
"description": "template for react application with typescript",
"main": "index.js",
"homepage": ".",
"license": "MIT",
"scripts": {
"start": "webpack serve --config webpack/webpack.config.js --env env=dev",
"build": "webpack --config webpack/webpack.config.js --env env=prod",
"lint": "eslint \"./src/**/*.{js,jsx,ts,tsx,json}\"",
"lint:fix": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\"",
"prettier": "prettier \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"prettier:fix": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
},
"dependencies": {
"babel-loader": "^8.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"#babel/core": "^7.18.5",
"#babel/plugin-transform-runtime": "^7.18.6",
"#babel/preset-env": "^7.18.2",
"#babel/preset-react": "^7.17.12",
"#babel/preset-typescript": "^7.17.12",
"#babel/runtime": "^7.18.6",
"#pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"#types/estree": "^0.0.52",
"#types/react": "^18.0.14",
"#types/react-dom": "^18.0.5",
"#typescript-eslint/eslint-plugin": "^5.30.0",
"#typescript-eslint/parser": "^5.30.0",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.1",
"eslint": "^8.18.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"html-webpack-plugin": "^5.5.0",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
"react-refresh": "^0.14.0",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"typescript": "^4.7.4",
"webpack": "^5.74.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.2",
"webpack-merge": "^5.8.0"
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json}": [
"eslint --fix"
],
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
webpack (common config):
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, '..', './src/index.tsx'),
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: 'asset/resource',
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline',
},
],
},
output: {
path: path.resolve(__dirname, '..', './build'),
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '..', './public/index.html'),
}),
new CopyPlugin({
patterns: [{ from: 'src', to: 'dest' }],
}),
],
};
webpack (config):
const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
module.exports = ({ env }) => {
const envConfig = require(`./webpack.${env}.js`);
const config = merge(commonConfig, envConfig);
return config;
};
webpack (prod config):
module.exports = {
mode: 'production',
devtool: 'source-map',
};
webpack (dev config):
const ReactRefreshWebpackPlugin = require('#pmmmwh/react-refresh-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
hot: true,
open: true,
},
plugins: [new ReactRefreshWebpackPlugin()],
};
Browser console of deployment:
Warning: DevTools failed to load source map: Could not load content for chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/browser-polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND
I have a problem when i updated in my project the webpack package to V5.x.
Here is the error :
webpack-hot-client: entry Object values must be an Array or Function. Please check your webpack config.
Here is my package.json :
"*.css",
"*.scss",
"*.sass" ], "main": "index.js", "scripts": {
"analyze": "bnr clean:build && bnr analyze",
"build:all": "bnr clean:build && bnr build:client && bnr build:server",
"build:client": "bnr clean:build && bnr build:client",
"build:server": "bnr clean:build && bnr build:server",
"clean": "bnr clean:build",
"dev": "bnr dev",
"docker": "yarn docker:build && yarn docker:start && yarn docker:status",
"docker:build": "docker-compose build --no-cache",
"docker:start": "docker-compose up -d",
"docker:status": "docker-compose logs -f -t",
"flow": "bnr flow",
"flow:stop": "bnr flow:stop",
"lint": "npm-run-all lint:js lint:style lint:json",
"lint:js": "bnr lint:js",
"lint:style": "bnr lint:style",
"lint:json": "bnr lint:json",
"prod": "bnr build:client && bnr build:server && bnr start",
"start": "bnr start",
"sitemap": "node sitemap-generator.js" }, "betterScripts": {
"analyze": {
"command": "npx webpack -p --progress --hide-modules --config ./tools/webpack/production.client.babel.js",
"env": {
"NODE_ENV": "analyze"
}
},
"build:client": {
"command": "npx webpack --hide-modules --config ./tools/webpack/production.client.babel.js && npx gulp --gulpfile
tools/gulpfile.js",
"env": {
"NODE_ENV": "production"
}
},
"build:server": {
"command": "npx babel ./src -d ./dist --copy-files && npx webpack --hide-modules --config
./tools/webpack/production.server.babel.js",
"env": {
"NODE_ENV": "production"
}
},
"clean:build": {
"command": "rimraf ./public/assets && rimraf ./public/webpack-assets.json"
},
"dev": {
"command": "nodemon ./index.js",
"env": {
"NODE_PATH": "./src",
"NODE_ENV": "development",
"PORT": 3000
}
},
"flow": {
"command": "npx flow"
},
"flow:stop": {
"command": "npx flow stop"
},
"lint:js": {
"command": "npx eslint --fix ./src ./tools ./index.js"
},
"lint:json": {
"command": "npx prettier --write src/**/**/*.json"
},
"lint:style": {
"command": "npx stylelint --fix ./src/**/*.css, ./src/**/*.scss"
},
"start": {
"command": "node ./index.js",
"env": {
"NODE_PATH": "./dist",
"NODE_HOST": "0.0.0.0",
"NODE_ENV": "production",
"PORT": 8080
}
} }, "husky": {
"hooks": {
"pre-commit": "lint-staged"
} }, "lint-staged": {
"*.{js,jsx}": "eslint --fix",
"*.{json,md}": "prettier --write",
"*.{scss,sass}": "stylelint --syntax=scss" }, "nodemonConfig": {
"watch": [
"src/server.js",
"src/handler.js",
"src/utils/renderHtml.js",
"src/theme/variables.scss"
] }, "browserslist": [
"> 1%",
"last 3 versions" ], "eslintIgnore": [
"tools/flow",
"public/assets" ], "dependencies": {
"#babel/cli": "^7.14.5",
"#babel/plugin-proposal-export-namespace-from": "^7.5.2",
"#fortawesome/fontawesome-free": "^5.15.1",
"#hapi/address": "^4.1.0",
"#koa/router": "^10.1.1",
"#loadable/component": "^5.10.2",
"#loadable/server": "^5.10.2",
"#tweenjs/tween.js": "^18.3.1",
"ansi-regex": "^6.0.1",
"axios": "^0.23.0",
"bootstrap": "^5.1.3",
"chalk": "^4.1.2",
"classnames": "^2.2.6",
"d3-ease": "^3.0.1",
"del": "^6.0.0",
"esm": "^3.2.25",
"glob-parent": "^6.0.2",
"gulp": "^4.0.2",
"gulp-cache": "^1.1.3",
"gulp-imagemin": "^8.0.0",
"gulp-postcss": "^9.0.0",
"gulp-rename": "^2.0.0",
"i18next": "^21.3.2",
"i18next-browser-languagedetector": "^6.1.2",
"i18next-node-fs-backend": "^2.1.3",
"i18next-resource-store-loader": "^0.1.2",
"i18next-xhr-backend": "^3.1.2",
"imagemin-mozjpeg": "^9.0.0",
"imagemin-pngquant": "^9.0.2",
"koa": "^2.8.1",
"koa-bodyparser": "^4.2.1",
"koa-compress": "^5.1.0",
"koa-favicon": "^2.0.1",
"koa-helmet": "^6.1.0",
"koa-i18next-detector": "^0.7.2",
"koa-i18next-middleware": "^1.1.12",
"koa-i18next-middleware-fixed": "^1.1.10-b3",
"koa-morgan": "^1.0.1",
"koa-mount": "^4.0.0",
"koa-router": "^10.1.1",
"koa-static": "^5.0.0",
"koa-webpack": "^6.0.0",
"koa-webpack-server": "^0.2.4",
"micro-dash": "^8.1.0",
"moment": "^2.24.0",
"p-min-delay": "^4.0.1",
"pm2": "^5.1.2",
"qs": "^6.8.0",
"rc-animate": "^3.1.1",
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.6.1",
"rc-tween-one": "^2.6.3",
"react": "^17.0.2",
"react-bootstrap": "^1.0.0-beta.8",
"react-dom": "npm:#hot-loader/react-dom#^16.8.6",
"react-global-configuration": "^1.4.1",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-i18next": "^11.12.0",
"react-icons": "^4.3.1",
"react-motion": "^0.5.2",
"react-player": "^2.9.0",
"react-pose": "^4.0.8",
"react-router": "^5.0.1",
"react-router-config": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-router-last-location": "^2.0.1",
"react-router-sitemap": "^1.2.0",
"react-spring": "^9.3.0",
"react-tilt": "^0.1.4",
"react-typist": "^2.0.5",
"react-youtube": "^7.9.0",
"sass-resources-loader": "^2.0.1",
"serialize-javascript": "^6.0.0",
"styled-components": "^5.3.1",
"terser-webpack-plugin": "^5.2.4" }, "devDependencies": {
"#babel/core": "^7.6.0",
"#babel/node": "^7.14.5",
"#babel/plugin-proposal-class-properties": "^7.5.5",
"#babel/plugin-proposal-export-default-from": "^7.5.2",
"#babel/plugin-proposal-optional-chaining": "^7.6.0",
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"#babel/preset-env": "^7.14.5",
"#babel/preset-flow": "^7.0.0",
"#babel/preset-react": "^7.14.5",
"#babel/register": "^7.6.0",
"#babel/runtime": "^7.6.0",
"#loadable/babel-plugin": "^5.10.0",
"#loadable/webpack-plugin": "^5.7.1",
"asset-require-hook": "^1.2.0",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-plugin-istanbul": "^6.1.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"babel-plugin-transform-remove-console": "^6.9.4",
"better-npm-run": "^0.1.1",
"compression-webpack-plugin": "^9.0.0",
"core-js": "3",
"css-loader": "^6.4.0",
"css-modules-require-hook": "^4.2.3",
"cssnano": "^5.0.8",
"eslint": "^8.0.1",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-plugin-flowtype": "^6.1.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^4.2.0",
"file-loader": "^6.2.0",
"flow-bin": "^0.162.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-minifier": "^4.0.0",
"husky": "^7.0.2",
"imagemin-webpack-plugin": "^2.4.2",
"lint-staged": "^11.2.3",
"mini-css-extract-plugin": "^2.4.2",
"nodemon": "^2.0.13",
"normalize.css": "^8.0.1",
"npm-run-all": "^4.1.5",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss": "^8.3.9",
"postcss-loader": "^6.2.0",
"postcss-preset-env": "^6.7.0",
"prettier": "^2.4.1",
"react-dev-utils": "^11.0.4",
"react-hot-loader": "^4.12.13",
"react-router-sitemap-generator": "^0.0.8",
"react-test-renderer": "^17.0.2",
"rimraf": "^3.0.0",
"sass": "^1.43.2",
"sass-loader": "^12.2.0",
"static-site-generator-webpack-plugin": "^3.4.2",
"stylelint": "^13.13.1",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended-scss": "^4.3.0",
"stylelint-config-standard": "^22.0.0",
"stylelint-scss": "^3.10.1",
"url-loader": "^4.1.1",
"webpack": "^5.58.2",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "4.9.1",
"webpack-dev-middleware": "^5.2.1",
"webpack-hot-middleware": "^2.25.0",
"webpack-manifest-plugin": "^4.0.2",
"webpack-merge": "^5.8.0",
"webpack-node-externals": "^3.0.0" }, "engines": {
"node": ">=8",
"npm": ">=5" } }```
Here is my base.config.js of webpack :
import webpack from 'webpack'
import { WebpackManifestPlugin } from 'webpack-manifest-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import LoadablePlugin from '#loadable/webpack-plugin'
import config from './config'
const nodeEnv = process.env.NODE_ENV || 'development'
const isDev = nodeEnv === 'development'
const getPlugins = () => {
const plugins = [
new WebpackManifestPlugin({
fileName: path.resolve(process.cwd(), 'public/webpack-assets.json'),
filter: file => file.isInitial
}),
new MiniCssExtractPlugin({
filename: `${config.cssFileName}.css`,
chunkFilename: `${config.cssChunkFileName}.css`,
ignoreOrder: true
}),
// Setup environment variables for client
new webpack.EnvironmentPlugin({ NODE_ENV: JSON.stringify(nodeEnv) }),
// Setup global variables for client
new webpack.DefinePlugin({
__CLIENT__: true,
__SERVER__: false,
__DEV__: isDev
}),
new LoadablePlugin({ filename: '../loadable-stats.json', writeToDisk: true })
]
if (isDev) {
plugins.push(new FriendlyErrorsWebpackPlugin())
}
return plugins
}
// Webpack configuration
module.exports = {
mode: isDev ? 'development' : 'production',
devtool: isDev ? 'eval-source-map' : 'hidden-source-map',
context: path.resolve(process.cwd()),
entry: ['webpack-hot-middleware/client','./src/index.js'],
optimization: {
splitChunks: {
chunks: 'async'
}
},
output: {
path: path.resolve(process.cwd(), 'public/assets'),
publicPath: '/assets/',
filename: `${config.fileName}.js`,
chunkFilename: `${config.chunkFileName}.js`,
pathinfo: isDev
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
options: { cacheDirectory: isDev }
},
{
test: /\.css$/,
include: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css',
options: {
importLoaders: 1,
modules: false,
sourceMap: true
}
},
{ loader: 'postcss', options: { sourceMap: true } }
]
},
{
test: /\.(scss|sass)$/,
exclude: path.resolve(__dirname, '..', '..', 'src/theme/'),
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: isDev,
reloadAll: true
}
},
{
loader: 'css',
options: {
importLoaders: 2,
modules: {
localIdentName: config.cssModulesIdentifier,
context: path.resolve(process.cwd(), 'src')
},
sourceMap: true
}
},
{ loader: 'postcss', options: { sourceMap: true } },
{
loader: 'sass',
options: {
sassOptions: {
outputStyle: 'expanded'
},
sourceMap: true
}
},
{
loader: 'sass-resources',
options: {
resources: path.resolve(process.cwd(), 'src/theme/_include.scss')
}
}
]
},
{
test: /\.(scss|sass)$/,
include: path.resolve(__dirname, '..', '..', 'src/theme/'),
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: isDev,
reloadAll: true
}
},
{
loader: 'css',
options: {
importLoaders: 2,
modules: false,
sourceMap: true
}
},
{ loader: 'postcss', options: { sourceMap: true } },
{
loader: 'sass',
options: {
sassOptions: {
outputStyle: 'expanded'
},
sourceMap: true
}
}
]
},
{
test: path.resolve(process.cwd(), 'src/locales'),
loader: 'i18next-resource-store-loader'
},
{
test: /\.(woff2?|ttf|eot|svg|otf)$/,
loader: 'url',
options: { limit: 10240, name: config.staticFilesName }
},
{
test: /\.(gif|png|jpe?g|webp)$/,
// Any image below or equal to 10Kb will be converted to base64
loader: 'url',
options: { limit: 10240, name: config.staticFilesName }
},
{
test: /\.(mp3|mp4|ogv)$/,
loader: 'file',
options: { name: config.staticFilesName }
}
]
},
plugins: getPlugins(),
resolveLoader: {
mainFields: ['loader']
},
resolve: {
modules: ['src', 'node_modules'],
descriptionFiles: ['package.json'],
extensions: ['.js', '.jsx', '.json'],
fallback:{
fs: false,
vm: false,
net: false,
tls: false
}
},
cache: isDev,
stats: { children: false }
I tried a lot of things and i fixed a lot of issues but for me the entry is an Array, so i don't know why i got this error.
Here there is my server.js (he launches all the programs) :
import logger from 'koa-morgan'
import Koa from 'koa'
import bodyParser from 'koa-bodyparser'
import compression from 'koa-compress'
import helmet from 'koa-helmet'
import querystring from 'qs'
import Router from '#koa/router'
import favicon from 'koa-favicon'
import axios from 'axios'
import chalk from 'chalk'
import mount from 'koa-mount'
import serve from 'koa-static'
import Backend from 'i18next-node-fs-backend'
import i18n from 'i18next'
import i18nextMiddleware from 'koa-i18next-middleware-fixed'
import LanguageDetector from 'koa-i18next-detector'
import c from './config'
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0
const app = new Koa()
const router = new Router()
const sendMessage = body =>
new Promise((resolve, reject) => {
const config = {
maxRedirects: 0,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios
.post(
'https://go.pardot.com/l/138941/2019-07-22/2h6dgb',
querystring.stringify({ ...body, privacy: true }),
config
)
.then(result => {
resolve(result.status === 200)
})
.catch(e => {
reject(new Error(e))
})
})
const lngDetector = new LanguageDetector()
i18n
.use(Backend)
.use(lngDetector)
.init(
{
debug: false,
fallbackLng: 'fr',
saveMissing: false,
react: {
useSuspense: false
},
detection: {
order: ['path', 'navigator']
},
interpolation: {
escapeValue: false,
formatSeparator: ',',
format: (value, format) => {
if (format === 'uppercase') return value.toUpperCase()
return value
}
},
preload: ['fr'],
load: 'languageOnly',
ns: [
'global',
'landing_references',
'landing_expertises',
'home',
'references',
'expertises',
'contact',
'about',
'partners',
'team'
],
defaultNS: 'global',
backend: {
loadPath: `${path.resolve(process.cwd(), 'src')}/locales/{{lng}}/{{ns}}.json`
}
},
async () => {
// Use helmet to secure Express with various HTTP headers
app.use(helmet())
app.use(bodyParser())
// Compress all requests
app.use(compression())
// Use for http request debug (show errors only)
app.use(logger('dev', { skip: ctx => ctx.status < 400 }))
app.use(favicon(path.resolve(process.cwd(), 'public/favicon.ico')))
app.use(i18nextMiddleware.getHandler(i18n, { locals: 'lng' }))
// Docker serve static trough nginx for better performance
if (!__DOCKER__) {
console.log(chalk.magenta('==> 🐌 Serve statics with koa'))
app.use(mount('/locales', serve(path.resolve(process.cwd(), 'src/locales'))))
app.use(serve(path.resolve(process.cwd(), 'public')))
}
if (__DEV__) {
app.use(mount('/images', serve(path.resolve(process.cwd(), 'src/images'))))
/* Run express as webpack dev server */
const webpack = require('webpack')
const webpackConfig = require('../tools/webpack/base.config')
const compiler = webpack(webpackConfig)
const koaWebpack = require('koa-webpack')
new webpack.ProgressPlugin().apply(compiler)
const options = {
compiler,
devMiddleware: {
publicPath: webpackConfig.output.publicPath,
headers: { 'Access-Control-Allow-Origin': '*' },
hot: true,
writeToDisk: false,
quiet: true, // Turn it on for friendly-errors-webpack-plugin
noInfo: true,
stats: 'minimal',
serverSideRender: true
}
}
const middleware = await koaWebpack(options)
app.use(middleware)
}
router
.post('/contact', async ctx => {
try {
await sendMessage(ctx.request.body)
ctx.body = {
message: 'Votre message a bien été envoyé'
}
ctx.status = 200
} catch (e) {
ctx.body = {
message: 'Une erreur est survenue'
}
ctx.status = 500
}
})
.get('/', async ctx => {
ctx.status = 302
return ctx.redirect(`/${ctx.request.language}`)
})
.get('*', async (ctx, next) => {
return require('./render')(ctx, next)
})
app.use(router.routes()).use(router.allowedMethods())
if (c.port) {
app.listen(c.port, c.host, err => {
const url = `http://${c.host}:${c.port}`
if (err) console.error(chalk.red(`\n==> Error happen ${err}`))
console.info(chalk.green(`\n==> 🌎 Listening at ${url}`))
})
} else {
console.error(chalk.red('\n==> Error : No PORT environment variable has been specified'))
}
}
)
UPDATE :
I put some console.log in the compiler file :
for (const key of Object.keys(entry)) {
const value = entry[key];
console.log(entry)
console.log(value)
console.log(Array.isArray(Object.values(value)))
if (!Array.isArray(value)) {
throw new TypeError(
'webpack-hot-client: `entry` Object values must be an Array or Function. Please check your webpack config.'
);
Console.log return this :
main: { import: [ 'webpack-hot-middleware/client', './src/index.js' ] }
}
{ import: [ 'webpack-hot-middleware/client', './src/index.js' ] }
true
So i think that there is a problem with the declaration of variable, because we have to do an Object.values() to get the array.
So idk what can i do to resolve the problem, i will not change the dependencies files...
Thx for your time and your response!
Regards
It might not be the right example to your situation, but they made some internal changes to the webpack structure:
entry: {} allows an empty object now (to allow to use plugins to add entries)
here's one of the newer examples I found:
module.exports = {
entry: {
about: { import: './about.js', filename: 'pages/[name][ext]' },
},
};
Source: Webpack v5 internal changes: Entry
I found the error. WebPack Hot Client is not update for the last version of webpack (5.x). If you use Webpack Hot Client, you have to use version 4 of Webpack.
Regards
I've got a react app (latest React version) with a NodeJS backend.
That runs so far locally. But now I want to use this React App (together with its NodeJS backend) with other devices in my home network.
How to do that?
That is my package.json of the React App:
{
"name": "dionysiscontrolcenter",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/plugin-transform-runtime": "^7.5.5",
"#babel/preset-env": "^7.4.5",
"#babel/preset-react": "^7.0.0",
"#babel/runtime": "^7.5.5",
"#hot-loader/react-dom": "^16.8.6",
"babel-eslint": "^10.0.2",
"babel-loader": "^8.0.6",
"babel-plugin-import": "^1.12.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-preset-es2015": "^6.24.1",
"copy-webpack-plugin": "^5.0.3",
"css-hot-loader": "^1.4.4",
"eslint": "5.15.3",
"eslint-config-airbnb": "^17.1.0",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": "2.18.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "7.14.2",
"file-loader": "^4.0.0",
"node-sass": "^4.12.0",
"prettier": "^1.18.2",
"sass-loader": "^7.1.0",
"webpack": "^4.35.0",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"antd": "^3.15.2",
"babel-plugin-transform-runtime": "^6.23.0",
"css-loader": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^5.0.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hot-loader": "^4.12.10",
"react-scripts": "2.0.0",
"react-string-replace": "^0.4.1",
"socket.io-client": "^2.2.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2"
},
"scripts": {
"dev": "webpack-dev-server --hot --env.mode=development",
"build": "webpack --colors --profile --progress --env.mode=production",
"build:analyze": "webpack --colors --profile --progress --env.mode=production --env.analyze=true",
"lint": "eslint ./src/ --ext .js,.jsx"
}
}
My webpack.config.js:
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = (env = {}) => {
const config = {
entry: ['./src/main.less', './src/main.jsx'],
output: {
path: path.resolve(__dirname, `./html/${env.branch || 'master'}`),
filename: 'dionysiscontrolcenter.js',
library: 'dionySisControlCenter',
libraryExport: 'default',
libraryTarget: 'umd',
},
mode: env.mode || 'development',
devtool: 'eval',
resolve: {
extensions: ['.js', '.jsx', '.css', '.less'],
},
plugins: [
new HtmlWebpackPlugin({ hash: false, template: './index.hbs' }),
new CopyWebpackPlugin([
{ from: 'dev/static/', to: 'static/' },
'dev/index.html',
]),
],
module: {
rules: [
{
test: [/\.js$/, /\.jsx$/],
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.css$/i,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.less$/i,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
options: {
sourceMap: true,
import: false,
},
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
sourceMap: true,
javascriptEnabled: true,
},
},
],
},
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
gifsicle: {
interlaced: false,
},
optipng: {
optimizationLevel: 7,
},
},
},
{
loader: 'file-loader',
},
],
},
{
test: /\.(svg)$/i,
use: [
{
loader: 'file-loader',
},
],
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'file-loader',
},
],
},
{
test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: 'file-loader',
},
],
},
watchOptions: {
poll: 1500,
},
devServer: {
contentBase: path.resolve(__dirname, './dev/'),
watchContentBase: true,
disableHostCheck: true,
// host: '0.0.0.0',
inline: true,
port: 8000,
// public: process.env.webpack_public_address || null,
overlay: true,
},
};
if (env.mode === 'development') {
// blabla alias
config.entry.unshift(
'webpack/hot/only-dev-server',
'react-hot-loader/patch'
);
config.resolve.alias = { 'react-dom': '#hot-loader/react-dom' };
config.module.rules.unshift({
enforce: 'pre',
test: [/\.js$/, /\.jsx$/],
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
failOnError: env.mode === 'production',
},
});
}
if (env.analyze === 'true') {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
})
);
}
return config;
};
What I tried so far:
Commented in host: '0.0.0.0' in the webpack.config.js
Added the line: "dev": "webpack-dev-server --hot --env.mode=development --host 0.0.0.0", to scripts attribute in the package.json
Removed --hot parameter in the scripts attribute of "dev" command
Can someone help here?
try to add HOST=0.0.0.0 to script object
"scripts": {
"dev": "HOST=0.0.0.0 webpack-dev-server --hot --env.mode=development",
"build": "HOST=0.0.0.0 webpack --colors --profile --progress --env.mode=production",
"build:analyze": "webpack --colors --profile --progress -- env.mode=production --env.analyze=true",
"lint": "eslint ./src/ --ext .js,.jsx"
}
I'm trying to make a production version about my client side code to deploy later in AWS. When I compile and build my web application in development enviromet, everything works fine. But when I try to do it in production enviroment I've got a warning because I've got files bigger than 244KB.
To fix this problem, I have been following the indications of Dynamic Imports But, how you can see in this screen cap, I'm still getting a file very big:
My application use Node.js, React.js and webpack 4. This is my package.json
{
"name": "basketmetrics3",
"version": "1.0.0",
"description": "Basketball advanced stats",
"main": "server.js",
"scripts": {
"dev-webpack": "webpack-dev-server --hot --mode development",
"clean": "rm -rf ./dist",
"dev": "npm run build-dev && cross-env NODE_ENV=development nodemon --exec babel-node src/server/server.js --ignore ./src/client",
"build-dev": "npm run clean && npm run compile-dev",
"compile-dev": "NODE_ENV=development webpack -d --config ./webpack.config.babel.js --progress",
"compile": "NODE_ENV=production webpack -p --config ./webpack.config.babel.js --progress",
"build": "npm run clean && npm run compile",
"start": "npm run build && node ./dist/assets/js/main.bundle.js",
"heroku-postbuild": "webpack -p"
},
"dependencies": {
"#babel/polyfill": "^7.4.4",
"#material-ui/core": "^3.9.3",
"#material-ui/icons": "^3.0.2",
"bootstrap": "^4.3.1",
"cors": "^2.8.5",
"create-react-app": "^3.0.1",
"cross-env": "^5.2.0",
"d3": "^5.9.7",
"dotenv": "^7.0.0",
"express": "^4.17.1",
"express-graphql": "^0.7.1",
"graphql": "^14.4.2",
"jquery": "^3.4.1",
"morgan": "^1.9.1",
"mysql2": "^1.6.5",
"popper.js": "^1.15.0",
"react": "^16.8.6",
"react-bootstrap": "^1.0.0-beta.10",
"react-bootstrap-table-next": "^3.1.7",
"react-bootstrap-table2-paginator": "^2.0.7",
"react-dom": "^16.8.6",
"react-multi-language": "^0.4.2",
"react-router-dom": "^5.0.1",
"react-simple-tooltip": "^2.6.1",
"sequelize": "^4.44.2",
"validator": "^10.11.0"
},
"devDependencies": {
"#babel/cli": "^7.5.5",
"#babel/core": "^7.5.5",
"#babel/node": "^7.5.5",
"#babel/preset-env": "^7.5.5",
"#babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-register": "^6.26.0",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.5.0",
"nodemon": "^1.19.1",
"path": "^0.12.7",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.38.0",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
}
}
To run my application in development enviroment I do it with this command: npm run dev and to run my application in production environment I do it with npm run start.
And this is my webpack.config.babel.js:
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
const devMode = process.env.NODE_ENV !== "production";
console.log("devMode: " + devMode);
module.exports = {
entry: "./src/client/index.js", //set entry file
// Resolve to output directory and set file
output: {
path: path.resolve("dist/assets"),
filename: "js/[name].bundle.js",
chunkFilename: "js/[name].bundle.js",
publicPath: "/assets" //It's mandatory to define this publicPath to get access to the website when we reload pages
//or we access to them directly with url's which have directories of second level like
//http://localhost:4000/directory-level-1/directory-level-2
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/client/index.html", //where is our template
filename: "../index.html", //where we are going to put our index.html inside the output directory
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
}),
new MiniCssExtractPlugin({
filename: "css/bundle.css",
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}
})
],
//It help us to detect errors.
devtool: "source-map",
// Set dev-server configuration
devServer: {
inline: true,
contentBase: './dist',
port: 3000
},
// Add babel-loader to transpile js and jsx files
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
loader: "babel-loader",
query: {
presets: [
"#babel/preset-react"
]
}
}
]
},
{
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader"],
test: /\.css$/
},
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "saas-loader",
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: "url-loader",
options: {
limit: 10000,
publicPath: "/assets/images/",
outputPath: "./images/"
}
},
{
test: /\.(eot|ttf|woff|woff2)$/,
loader: "url-loader",
options: {
limit: 10000,
publicPath: "/assets/fonts/", //It's mandatory to get access to the fonts when we reload pages or access directly
outputPath: "./fonts/"
}
}
]
}
}
How can I split my code in files smaller than the file that I've got in this moment?
Edit I (solved):
One possible solution to split the client code in files with a size smaller than 244Kb could be adding this entry to webpack.config.babel.js file:
optimization: {
splitChunks : {
chunks: "all",
minSize: 30000,
maxSize: 100000,
}
},
Now, I've got several files with a size smaller than 100Kb. Any other option to do the same?
I’m having below issue when running build function using web pack, can you please have a look? npm build、 delete node_modules、update node.js version. Please help me.
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
var node_modules = path.resolve(__dirname, 'node_modules');
var pathToReact = path.resolve(node_modules, 'react/react');
var pathToReactDOM = path.resolve(node_modules, 'react-dom/index')
module.exports = {
devtool: 'eval-source-map',
devServer: {
/*headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
},*/
historyApiFallback: true,
hot: true,
inline: true,
contentBase: './webapp/build',
progress: true,
port: 8000,
proxy: {
'\*': {
//target: 'http://10.10.2.124:8082',
target: 'http://10.10.1.89:8080',
secure: false
}
}
},
entry: [
'webpack-dev-server/client?http://localhost:8000',
'webpack/hot/dev-server',
path.resolve(__dirname, 'react/main.js')
],
output: {
path: __dirname + '/webapp/build',
publicPath: '/build',
filename: './bundle.js',
chunkFilename: "[id].bundle.js"
},
module: {
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.js[x]?$/,
include: path.resolve(__dirname, 'react'),
exclude: /node_modules/,
loaders: ['react-hot', 'babel-loader?cacheDirectory'],
noParse: [pathToReact, pathToReactDOM]
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader'
}, {
test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
loader: 'url'
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
plugins: [
new OpenBrowserPlugin({
url: 'http://localhost:8000/dev/index.html'
})
]
};
package.json
{
"name": "***",
"version": "1.0.0",
"description": "admin",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack-dev-server react/main.js --devtool eval --progress --hot --inline --colors --content-base webapp/build",
"deploy": "set NODE_ENV=production && webpack --config webpack.production.config.js"
},
"dependencies": {
"antd": "1.1.0",
"babel-runtime": "6.x",
"compression-webpack-plugin": "^0.4.0",
"echarts": "^3.4.0",
"react": "0.14.x",
"react-dom": "0.14.x",
"reflux": "^0.4.1",
"reqwest": "^2.0.5",
"webpack-parallel-uglify-plugin": "^0.4.2"
},
"devDependencies": {
"animate.css": "^3.5.1",
"babel-core": "^6.10.4",
"babel-eslint": "6.x",
"babel-loader": "6.x",
"babel-plugin-antd": "^0.4.0",
"babel-plugin-transform-es2015-modules-simple-amd": "^0.3.0",
"babel-plugin-transform-runtime": "6.x",
"babel-preset-es2015": "6.x",
"babel-preset-react": "6.x",
"babel-preset-stage-0": "6.x",
"copy-webpack-plugin": "2.x",
"css-loader": "~0.23.0",
"es5-shim": "^4.5.8",
"es6-promise": "^3.2.1",
"http-proxy-middleware": "0.17.2",
"open-browser-webpack-plugin": "0.0.2",
"react-hot-loader": "^1.3.0",
"style-loader": "~0.13.0",
"url-loader": "^0.5.7",
"webpack": "1.x",
"webpack-dev-server": "^1.14.1"
},
"author": "dwj",
"license": "ISC"
}
No compile errors, the project started normally. But the page can not be displayed normally.