Related
I'm working on cleaning up an older React project and trying to cut down on bundle size by implementing code splitting and chunking things out. I've made considerable progress, but my main entry point for the application is still sitting at ~600kb. It seems to be 95% coming from not the application code itself but the css-loader library I'm using during the webpack build process.
This seems incorrect, but I can't figure out what about my webpack config or packages is causing this bloat in this particular bundle.
Here's my environment-common and production webpack config info:
// webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const BUILD_DIR = path.resolve(__dirname, 'build');
const SRC_DIR = path.resolve(__dirname, 'src');
module.exports = {
entry: ['babel-polyfill', `${SRC_DIR}/index.js`],
output: {
path: BUILD_DIR,
publicPath: '/',
filename: '[name].[fullhash].bundle.js',
chunkFilename: '[name].[chunkhash].bundle.js'
},
optimization: {
moduleIds: 'named',
splitChunks: {
chunks: 'all'
}
},
module: {
// exclude node_modules
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.(scss|css)$/,
use: [
process.env.NODE_ENV !== 'production'
? 'style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
resolve: {
alias: {
'~': path.resolve(__dirname, 'src')
},
extensions: ['*', '.js']
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: './public/index.html'
}),
new CopyWebpackPlugin({
patterns: [
{ from: './public/img', to: 'img' },
{ from: './web.config', to: 'web.config' }
]
})
]
};
// webpack.prod.js
const { merge } = require('webpack-merge');
const webpack = require('webpack');
const CompressionPlugin = require('compression-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const common = require('./webpack.common');
const config = require('./config/config.prod.json');
const extractCSS = new MiniCssExtractPlugin({ filename: '[name].fonts.css' });
const extractSCSS = new MiniCssExtractPlugin({ filename: '[name].styles.css' });
process.traceDeprecation = true;
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin({
API_BASE_URL: JSON.stringify(config.API_BASE_URL),
TUMBLR_CLIENT_BASE_URL: JSON.stringify(config.TUMBLR_CLIENT_BASE_URL)
}),
extractCSS,
extractSCSS,
new CompressionPlugin()
],
optimization: {
splitChunks: {
chunks: 'all'
},
minimize: true
}
});
// package.json
{
"name": "***",
"version": "1.0.0",
"description": "***",
"author": "***",
"url": "***",
"copyright": "***",
"license": "GPL",
"private": true,
"homepage": "***",
"devDependencies": {
"#babel/cli": "^7.1.5",
"#babel/core": "^7.1.6",
"#babel/eslint-parser": "^7.13.8",
"#babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"#babel/plugin-proposal-object-rest-spread": "^7.0.0",
"#babel/plugin-proposal-optional-chaining": "^7.13.8",
"#babel/plugin-transform-runtime": "^7.4.0",
"#babel/preset-env": "^7.1.6",
"#babel/preset-react": "^7.0.0",
"#testing-library/jest-dom": "^5.11.9",
"#testing-library/react": "^11.2.3",
"#testing-library/user-event": "^12.6.2",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "^9.1.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"codecov": "^3.1.0",
"compression-webpack-plugin": "^10.0.0",
"copy-webpack-plugin": "^11.0.0",
"cross-env": "^5.2.0",
"css-loader": "^6.7.2",
"eslint": "^8.28.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.1.0",
"eslint-import-resolver-webpack": "^0.13.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest-dom": "^3.9.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-testing-library": "^5.9.1",
"eslint-watch": "^8.0.0",
"html-webpack-plugin": "^5.5.0",
"jest": "^26.6.3",
"jest-dom": "^4.0.0",
"jest-when": "^2.3.1",
"mini-css-extract-plugin": "^2.7.0",
"mkdirp": "^0.5.1",
"msw": "^0.35.0",
"node-sass": "^8.0.0",
"prettier": "^2.0.2",
"redux-saga-test-plan": "^3.7.0",
"redux-test-utils": "^0.3.0",
"rimraf": "^2.6.2",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.6",
"unused-webpack-plugin": "^2.4.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.35",
"#fortawesome/free-regular-svg-icons": "^5.15.3",
"#fortawesome/free-solid-svg-icons": "^5.15.3",
"#fortawesome/react-fontawesome": "^0.1.14",
"availity-reactstrap-validation": "npm:availity-reactstrap-validation-safe#^2.6.1",
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.1.3",
"chalk": "^2.4.1",
"classnames": "^2.2.6",
"dot-prop-immutable": "^1.5.0",
"history": "^4.7.2",
"immutable": "^4.0.0-rc.12",
"jquery": "^3.5.1",
"local-storage": "^1.4.2",
"lodash": "^4.17.20",
"luxon": "^3.1.1",
"promise": "^8.0.2",
"prop-types": "^15.6.2",
"query-string": "^6.2.0",
"rc-tooltip": "^3.7.3",
"react": "^16.8.6",
"react-autosuggest": "^9.4.3",
"react-dom": "^16.8.6",
"react-ga": "^2.5.6",
"react-multivalue-text-input": "^0.6.2",
"react-query": "^3.26.0",
"react-redux": "^5.1.1",
"react-redux-toastr": "^7.4.3",
"react-router": "^6.2.1",
"react-router-dom": "^5.2.0",
"react-table": "^7.6.3",
"react-toastify": "^7.0.3",
"react-transition-group": "^2.5.0",
"reactstrap": "^6.5.0",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-saga": "^0.16.2",
"reselect": "^4.0.0",
"simple-line-icons": "^2.4.1",
"styled-components": "^4.1.2",
"uuid": "^8.3.2"
},
"scripts": {
"start": "webpack serve --config webpack.dev.js",
"build": "npm run clean && webpack --config webpack.prod.js",
"build:staging": "npm run clean && webpack --config webpack.staging.js",
"clean": "rimraf ./build",
"lint": "prettier --write \"src/**/*.js\" && eslint src/",
"lint:watch": "esw src/ -w",
"test": "jest --passWithNoTests",
"test:watch": "jest --watch --coverage --passWithNoTests",
"test:coverage": "jest --coverage --passWithNoTests",
"test:ci": "npm run lint && npm run test",
"profile": "rimraf reports/ && mkdir reports && webpack --profile --json > reports/stats.json --config webpack.prod.js"
},
"engines": {
"node": ">= 8.9.1",
"npm": ">= 5.6.0"
},
"jest": {
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/config/tests/styleMock.js",
"^~/(.*)": "<rootDir>/src/$1"
},
"globals": {
"API_BASE_URL": "http://baseurl/"
},
"setupFilesAfterEnv": [
"<rootDir>/config/tests/setup.js"
]
},
"browserslist": [
"> 0.25%",
"not dead"
]
}
Is there a reason that css-loader alone is being bundled into the main bundle? And how do I either make it stop or resize it to a manageable level?
Be aware, running the production mode webpack build and having NODE_ENV set to production is two different thing! And without setting it, NODE_ENV ended up undefined, so style-loader was used for every build.
You have to do an export NODE_ENV=production; before running your build with your current code.
Alternatively you can create your webpack config like this:
module.exports = (env, argv) => {
if (argv.mode === 'development') {
}
if (argv.mode === 'production') {
}
return config;
};
This way you can manage it from cli simply by passing --mode=production or --mode=development and instead of env variables you can rely on webpack's configuration.
I recently joined a company that works with react (classes) and typescript, I was flabbergasted when I knew that the react they are using does not hot/live reload on changes (CSS, state, or any change), what happens on changes is webpack recompiles (takes around 25 seconds) and to see changes I should reload the page which is slowing down the development experience greatly.
Talking to the manager it was decided that we do a migration to a new create react app gradually as there is lots of code and redundancy and we want to use functional react hooks (which will take years maybe as the app is big) but until then I want to resolve the hot reload issue.
I believe the react app a long time ago was not started with creat-react-app or something.
Just to mention I have 1.5 yrs experience in the industry so config stuff is still new to me and am just doing this for my learning benefits and to improve the team experience, it's not really an assigned task to do.
Below are our package.json, webpack file, and index file. Please let me know if you need to see anything else.
Package.json:
{
"name": "web-front-end",
"version": "1.22.19",
"description": "HTML5 implementation of the <our company name>. Written in Typescript, compiled to JavaScript, bundled with Webpack, executing on NodeJS, using React, adopting FLUX patterns.",
"private": true,
"scripts": {
"babel": "babel built/client/js/client.js -o built/client/js/client.js",
"clean": "rm -rf node_modules && rm -rf built && rm -rf coverage && echo 'clean complete'",
"reset": "yarn clean && yarn cache clean && yarn install --frozen-lockfile",
"compile": "yarn compile-client && yarn compile-server && yarn babel",
"debug-client": "NODE_ENV=debug webpack --config webpack.dev.js && echo 'client compile complete'",
"compile-client": "NODE_ENV=production webpack --config webpack.prod.js && echo 'production client compile complete'",
"compile-client-dev": "NODE_ENV=development webpack --config webpack.dev.js && echo 'development client compile complete'",
"compile-client-dev-watch": "NODE_ENV=development webpack --config webpack.dev-watch.js",
"compile-server": "tsc -p src/server && echo 'server compile complete'",
"compile-client-watch": "NODE_ENV=development webpack --config webpack.dev-watch.js",
"compile-server-watch": "tsc -p src/server --watch",
"validate": "yarn --ignore-engines && tslint './src/**/*.{ts,tsx}' './test/**/*.{ts,tsx}' && echo 'validate complete'",
"start-server": "node ./built/server/ServerApp.js",
"test": "tslint --project test && tslint --project src/app && tsc -p test --jsx react && node ./node_modules/jest/bin/jest.js --config=jest.test.config.json --coverage --verbose",
"lint-fix": "tslint --fix --project src && tslint --fix --project test",
"prepare": "patch-package"
},
"dependencies": {
"#emotion/react": "^11.9.3",
"#emotion/styled": "^11.9.3",
"#mui/icons-material": "^5.8.4",
"#mui/material": "^5.8.4",
"#mui/styles": "^5.8.4",
"#stripe/stripe-js": "1.11.0",
"assert": "^2.0.0",
"axios": "^0.27.2",
"blob-stream": "0.1.3",
"buffer": "^6.0.3",
"compression": "1.7.3",
"compression-webpack-plugin": "^10.0.0",
"connected-react-router": "^6.9.2",
"cors": "2.8.4",
"device-uuid": "1.0.4",
"dotenv": "6.0.0",
"express": "4.16.3",
"file-saver": "^2.0.5",
"html-to-image": "^1.10.8",
"https-browserify": "^1.0.0",
"js-cookie": "2.2.0",
"node-zip": "1.1.1",
"path-to-regexp": "2.4.0",
"pug": "2.0.3",
"query-string": "6.1.0",
"react": "17.0.0",
"react-copy-to-clipboard": "5.0.1",
"react-dom": "^17.0.2",
"react-form-validator-core": "0.4.4",
"react-hook-form": "^7.36.0",
"react-inlinesvg": "2.3.0",
"react-jss": "8.5.1",
"react-lazy-load": "3.0.13",
"react-markdown": "4.0.4",
"react-material-ui-form-validator": "^3.0.1",
"react-player": "1.14.2",
"react-redux": "^7.2.6",
"react-router": "5.2.1",
"react-router-dom": "5.3.0",
"react-share": "2.4.0",
"react-speech-recognition": "^3.10.0",
"react-stripe-elements": "2.0.1",
"react-svgmt": "^1.2.0",
"react-virtualized": "9.22.3",
"react-youtube": "7.9.0",
"recompose": "0.27.1",
"rect": "1.2.1",
"redux": "4.0.0",
"redux-thunk": "2.3.0",
"regenerator-runtime": "^0.13.9",
"shortid": "2.2.15",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"svg-to-pdfkit": "0.1.7",
"url": "^0.11.0",
"utf8": "3.0.0"
},
"devDependencies": {
"#babel/cli": "^7.17.6",
"#babel/core": "^7.17.8",
"#babel/types": "^7.17.0",
"#types/blob-stream": "0.1.29",
"#types/code": "4.0.4",
"#types/detect-browser": "3.0.0",
"#types/jest": "25.2.3",
"#types/js-cookie": "2.2.1",
"#types/lab": "11.1.0",
"#types/react": "17.0.14",
"#types/react-dom": "17.0.14",
"#types/react-inlinesvg": "1.0.0",
"#types/react-redux": "^7.1.20",
"#types/react-router": "4.4.5",
"#types/react-virtualized": "9.21.18",
"#types/shortid": "0.0.29",
"#types/utf8": "2.1.6",
"awesome-typescript-loader": "3.4.1",
"copy-webpack-plugin": "4.5.1",
"detect-browser": "3.0.1",
"fork-ts-checker-webpack-plugin": "^7.2.13",
"jest": "^27.5.1",
"patch-package": "6.1.2",
"postinstall-postinstall": "2.0.0",
"process": "^0.11.10",
"source-map-loader": "0.2.3",
"source-map-support": "0.4.18",
"ts-jest": "27.1.2",
"ts-loader": "^9.3.1",
"ts-mockito": "2.3.0",
"ts-node": "^10.8.1",
"tslint": "^6.0.1",
"tslint-eslint-rules": "5.4.0",
"tslint-react": "^5.0.0",
"typescript": "4.1.5",
"webpack": "^5.73.0",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^4.10.0",
"webpack-merge": "^5.8.0"
},
"resolutions": {
"#types/prop-types": "15.7.5",
"#types/unist": "2.0.0",
"#types/react-transition-group": "2.0.8",
"#types/react": "17.0.14",
"#types/react-dom": "17.0.14"
},
"repository": {
"type": "git",
"url": "our repo link"
},
"author": "our company name",
"license": "MIT",
}
Webpack.common.js:
const path = require("path");
const webpack = require('webpack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = {
entry: "./src/app/Main.ts",
cache: false,
optimization: {
providedExports: true,
usedExports: true,
removeAvailableModules: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
chunkIds: 'named',
},
plugins: [
new webpack.ProvidePlugin({process: "process/browser"}),
new ForkTsCheckerWebpackPlugin(
{
typescript: {
configFile: './src/app/tsconfig.json'
}
}),
],
module: {
rules: [
{
test: /\.tsx?$/i,
loader: "ts-loader",
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource",
generator: {
filename: 'assets/[hash][ext]',
},
},
],
},
resolve: {
alias: {
core: path.join(__dirname, "src", "core"),
client: path.join(__dirname, "src", "client"),
server: path.join(__dirname, "src", "server"),
'<our company name>-typescript-common': path.resolve(__dirname, 'node_modules/<our company name>-typescript-common/'),
},
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js", ".jsx"],
fallback: {
"util": require.resolve('util'),
"os": false,
"fs": false,
"path": false,
"zlib": false,
"buffer": require.resolve('buffer'),
"http": require.resolve('stream-http'),
"https": require.resolve('https-browserify'),
"url": require.resolve('url'),
"stream": require.resolve('stream-browserify'),
},
},
output: {
path: path.resolve(__dirname, "built"),
filename: "client/js/client.js",
clean: true,
},
};
index.js (called Main.ts on our codebase)
import { render } from 'react-dom';
import { AppWrapper } from './view/App/AppWrapper';
declare var window: any;
class CompanyName {
constructor() {
window.dataLayer = window.dataLayer || [];
window._hsq = window._hsq || [];
const rootHtmlElement = document.body.appendChild(document.createElement('div'));
render(new AppWrapper({
lang: window.appConfig.LANGUAGE,
appConfig: window.appConfig,
startupTimestamp: window.sts}).render(), rootHtmlElement);
}
}
// tslint:disable-next-line:no-unused-expression
new CompanyName();
webpack.dev-watch.js:
const { merge } = require("webpack-merge");
const common = require("./webpack.dev.js");
const path = require('path');
module.exports = merge(common, {
watch: true,
optimization: {
minimize: false,
mangleExports: false,
mangleWasmImports: false
},
watchOptions: {
ignored: [
path.posix.resolve(__dirname, './node_modules'),
path.posix.resolve(__dirname, './rfg'),
path.posix.resolve(__dirname, './patches'),
path.posix.resolve(__dirname, './built'),
],
poll: 1500,
aggregateTimeout: 1000,
},
});
I would be grateful if you provide any explanations, explanatory links or videos in your answers so I can learn more.
Thanks.
I have created an alias for react and react-dom in my next.config.js. This is my next.config.js:
var path = require("path");
module.exports = (phase) => {
return {
// typescript: {
// ignoreBuildErrors: false,
// },
webpack5: true,
webpack(config, options) {
// const { isServer } = options;
// if (!isServer) {
// config.resolve.fallback.fs = false;
// }
config.module.rules.push({
test: /\.svg$/,
loader: "#svgr/webpack",
});
config.resolve.alias["react"] = path.resolve(
__dirname,
"shared-js/node_modules/react"
);
config.resolve.alias["react-dom"] = path.resolve(
__dirname,
"shared-js/node_modules/react-dom"
);
console.log(path.resolve(__dirname, "shared-js/node_modules/react-dom"));
return config;
},
};
};
Why am I doing this?
I have a component library, which is based on material ui. This is imported to my nextjs app via a submodule (shared-js). This is the package.json for my component library:
{
"name": "my-component-library",
"version": "1.0.0",
"description": "",
"author": "",
"private": true,
"main": "dist/index.js",
"module": "dist/index.modern.js",
"umd": "dist/index.min.js",
"source": "src/index.js",
"scripts": {
"start": "rollup -c -w",
"build": "NODE_ENV=production rollup -c",
"build-dev": "NODE_ENV=develop rollup -c --minifyInternalExports=false",
"prettier": "prettier --write ./src"
},
"peerDependencies": {
"eslint": "^8.15.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"license": "ISC",
"dependencies": {
"#emotion/react": "^11.7.1",
"#emotion/styled": "^11.6.0",
"#mui/icons-material": "^5.4.2",
"#mui/material": "^5.4.1",
"#mui/styles": "^5.4.2",
"#mui/x-data-grid": "^5.7.0",
"#rollup/plugin-node-resolve": "^13.3.0",
"prop-types": "^15.8.1",
"react-beautiful-dnd": "^13.1.0",
"react-grid-layout": "^1.3.4",
"react-resizable": "^3.0.4",
"recharts": "^2.1.9",
"rollup-plugin-import-css": "^3.0.3",
"styled-components": "^5.3.3",
"use-react-screenshot": "^3.0.0"
},
"devDependencies": {
"#babel/cli": "^7.17.10",
"#babel/core": "^7.17.10",
"#babel/plugin-transform-runtime": "^7.17.10",
"#babel/preset-env": "^7.17.10",
"#babel/preset-react": "^7.16.7",
"#rollup/plugin-babel": "^5.3.1",
"#rollup/plugin-commonjs": "^21.0.2",
"#svgr/rollup": "^6.2.1",
"babel-eslint": "^10.1.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-standard": "^5.0.0",
"prettier": "^2.6.2",
"rollup": "^2.72.1",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-filesize": "^9.1.2",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.6.0"
},
"files": [
"dist"
]
}
Here is my package.json for my nextjs app:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"name": "frontend",
"version": "1.0.0",
"main": "index.js",
"repository": "",
"author": "",
"license": "MIT",
"dependencies": {
"next": "^12.1.5",
"react": "^18.1.0",
"react-dom": "^18.1.0"
}
}
And my folder structure for the project:
-.next
-node_modules
-pages
-shared-js
--node_modules
--package.json
package.json
next.config.js
The problem is, that I have two conflicting versions of react and react-dom (I guess) in my shared-js/node_modules and the other ones in the node_modules folder of my nextjs app. This caused the error "Invalid hook call" whenever I tried to import a component to my nextjs app. I looked into the documentation and saw that this might be because of two conflicting react / react-dom versions, which is indeed the case. So I tried to avoid this by defining this alias in my next.config.js.
Which led me here. Whenever I run npm run dev or npm run build for my nextjs app, I get this error, telling me that react-dom is apparently missing:
wait - compiling /_error (client and server)...
wait - compiling...
error - ./node_modules/next/dist/client/index.js:513:35
Module not found: Can't resolve 'react-dom/client'
Why is that? The path is correct, the dependency is there but still I get this error. Is there anything I am missing? Or something I am doing wrong?
What I already tried: Deleting node_mdoules and package-lock.json from both nextjs and my component library and reinstall them. Deleting .next and restart via npm run dev
that's how I solved the problem with the conflicting versions.
Good description of the problem: https://blog.maximeheckel.com/posts/duplicate-dependencies-npm-link/
My next.config.js
var path = require("path");
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
config.resolve.alias["react"] = path.resolve("./node_modules/react");
return config;
},
};
I am making my first ever unit tests with Jest and React Testing Library on my react app.
This is a project I took over and has some pre-existing configuration and test setup which I'll admit I may not fully understand.
How I got to this error is this:
I already had one test up and running testing a component that doesn't use redux.
My next test needed to test a component that uses Redux and so I started to look at totally using React Testing Library and dropping Enzyme all together as the Enzyme isnt compatible with the latest React.
I kept getting an error along the lines of 'cannot import modules outside of node modules' and found out that babel cannot parse ES6.
And so I have been scouring the internet looking for solutions...
I have tried a few methods:
#babel/plugin-syntax-jsx
#babel/preset-react
most recently
However it seems it was not being picked up on as I was still getting the same error with the same suggestion which was:
Add #babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.
If you want to leave it as-is, add #babel/plugin-syntax-jsx (https://git.io/vb4yA) to the 'plugins' section to enable parsing.
I have added this to the presets and plugins of my babel config in my package-lock but still got the same error.
I also tried adding a .babelrc and babel.config.js file with the same preset and plugins but still get the same error.
There was some pre-existing code which I think could potentially be screwing things up somehow but I do not entirely understand it I'll be honest.
This is my package-lock:
{
"name": "hiro-flash",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.11.4",
"#sentry/react": "^5.29.2",
"#sentry/tracing": "^5.29.2",
"autoprefixer": "7.1.6",
"axios": "^0.18.0",
"axios-cache-adapter": "^2.3.3",
"babel-core": "6.26.0",
"babel-eslint": "^8.2.6",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-preset-react-app": "^3.1.2",
"babel-runtime": "6.26.0",
"bluebird": "^3.5.1",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
"copy-to-clipboard": "^3.3.1",
"css-loader": "0.28.7",
"detect-browser": "^2.5.0",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"eslint": "^4.19.1",
"eslint-config-react-app": "^2.1.0",
"eslint-loader": "1.9.0",
"eslint-plugin-flowtype": "2.39.1",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.4.0",
"export-to-csv": "^0.2.1",
"express": "^4.16.3",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"file-saver": "^2.0.5",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"jest": "26.6.3",
"jest-cli": "26.6.3",
"jest-esm-transformer": "^1.0.0",
"jquery": "^3.3.1",
"jszip": "^3.6.0",
"jszip-utils": "^0.1.0",
"lodash": "^4.17.10",
"moment": "2.18.1",
"moment-business-days": "^1.1.3",
"moment-timezone": "^0.5.23",
"npm": "^5.10.0",
"object-assign": "4.1.1",
"path": "^0.12.7",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"promise": "8.0.1",
"prop-types": "^15.6.2",
"raf": "3.4.0",
"react": "latest",
"react-accessible-accordion": "^3.3.3",
"react-dates": "^21.2.1",
"react-datetime": "^2.15.0",
"react-dev-utils": "^5.0.2",
"react-device-detect": "^1.9.10",
"react-dom": "latest",
"react-dropzone": "^11.3.2",
"react-ga": "3.2.0",
"react-hotjar": "^2.2.1",
"react-hover-observer": "^2.1.0",
"react-html-parser": "^2.0.2",
"react-quill": "^1.3.1",
"react-redux": "^5.0.7",
"react-responsive-modal": "^2.1.0",
"react-router": "^3.0.0",
"react-router-redux": "^4.0.8",
"react-select": "^2.0.0",
"react-sizes": "^1.0.4",
"react-table": "6.8.6",
"react-throttle-render": "^2.0.0",
"react-tippy": "^1.2.2",
"react-toastify": "^6.0.9",
"react-tooltip": "^4.2.11",
"recharts": "^1.8.5",
"redux": "^3.7.2",
"redux-api-middleware": "^2.3.0",
"redux-logger": "^3.0.6",
"redux-saga": "^0.16.0",
"redux-thunk": "^2.3.0",
"style-loader": "0.19.0",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.6.2",
"webpack": "3.8.1",
"webpack-dev-server": "2.9.4",
"webpack-manifest-plugin": "1.3.2",
"whatwg-fetch": "2.0.3",
"xlsx": "^0.16.9"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,mjs}"
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}",
"<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
],
"testEnvironment": "jsdom",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx)$": "jest-esm-transformer",
"^.+\\.(mjs)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"mjs",
"js",
"json",
"web.jsx",
"jsx",
"node"
]
},
"extensionsToTreatAsEsm": [
".js",
".jsx",
".ts"
],
"globals": {
"window": {
"location": {
"protocol": {}
}
}
},
"babel": {
"plugins": [
"#babel/plugin-syntax-jsx"
],
"presets": [
"#babel/preset-env",
"#babel/preset-react",
"react-app"
]
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"#babel/plugin-syntax-jsx": "^7.14.5",
"#testing-library/react": "^12.0.0",
"chai": "^4.2.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.6",
"node-sass": "^4.9.3",
"react-test-renderer": "^16.14.0",
"sass-loader": "^6.0.7",
"sinon": "^7.4.1"
}
}
this is my test:
import React from 'react';
import renderer from 'react-test-renderer';
import { PriceMonitor } from '../../components/priceMonitor/PriceMonitor';
describe('Price Monitor', () => {
const getTree = (activeUser = 'Test User 1', isOriginalUser = true, openPriceMonitorModal = jest.fn(),
resetActiveUser = jest.fn()) => {
const props = {
activeUser,
openPriceMonitorModal,
isOriginalUser,
resetActiveUser,
}
const component = renderer.create(<PriceMonitor {...props} />);
return component.toJSON();
}
const mockOnClick = jest.fn((username, newOriginalValue) => getTree(username, newOriginalValue));
it('renders original user (Test User 1)', () => {
const tree = getTree();
expect(tree).toMatchSnapshot();
});
it('changes user onClick (Test User 1 -> Test User 2)', () => {
const tree = getTree();
expect(tree).toMatchSnapshot();
expect(mockOnClick('Test User 2', false)).toMatchSnapshot();
});
it('renders non original user (Test User 2)', () => {
const tree = getTree('Test User 2', false)
expect(tree).toMatchSnapshot();
});
it('resets user onClick (Test User 2 -> Test User 1)', () => {
const tree = getTree('Test User 2', false);
expect(tree).toMatchSnapshot();
expect(mockOnClick('Test User 1', true)).toMatchSnapshot();
});
});
And then 2 files which were pre-existing,
this is test.js:
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const jest = require('jest');
const argv = process.argv.slice(2);
// Watch unless on CI or in coverage mode
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
argv.push('--watch');
}
jest.run(argv);
fileTransform.js inside my jest folder:
'use strict';
const path = require('path');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
Theres also a webpack.config.dev.js but Im not sure how much that is effecting this problem
Im a newb so apologies if this isnt clear enough - will be happy to provide more info.
I am working in a react application (Below Package.json)
{
"name": "seed",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8080",
"dependencies": {
"#ckeditor/ckeditor5-adapter-ckfinder": "23.1.0",
"#ckeditor/ckeditor5-alignment": "23.1.0",
"#ckeditor/ckeditor5-autoformat": "23.1.0",
"#ckeditor/ckeditor5-basic-styles": "23.1.0",
"#ckeditor/ckeditor5-block-quote": "23.1.0",
"#ckeditor/ckeditor5-build-classic": "23.1.0",
"#ckeditor/ckeditor5-ckfinder": "23.1.0",
"#ckeditor/ckeditor5-dev-utils": "^23.5.1",
"#ckeditor/ckeditor5-dev-webpack-plugin": "^23.5.1",
"#ckeditor/ckeditor5-easy-image": "23.1.0",
"#ckeditor/ckeditor5-editor-classic": "23.1.0",
"#ckeditor/ckeditor5-editor-decoupled": "23.1.0",
"#ckeditor/ckeditor5-font": "23.1.0",
"#ckeditor/ckeditor5-heading": "23.1.0",
"#ckeditor/ckeditor5-highlight": "23.1.0",
"#ckeditor/ckeditor5-image": "23.1.0",
"#ckeditor/ckeditor5-link": "23.1.0",
"#ckeditor/ckeditor5-list": "23.1.0",
"#ckeditor/ckeditor5-media-embed": "23.1.0",
"#ckeditor/ckeditor5-paste-from-office": "23.1.0",
"#ckeditor/ckeditor5-react": "3.0.0",
"#ckeditor/ckeditor5-real-time-collaboration": "23.1.0",
"#ckeditor/ckeditor5-remove-format": "23.1.0",
"#ckeditor/ckeditor5-table": "23.1.0",
"#ckeditor/ckeditor5-theme-lark": "23.1.0",
"#date-io/date-fns": "1.3.13",
"#material-ui/core": "4.9.10",
"#material-ui/icons": "^4.9.1",
"#material-ui/lab": "^4.0.0-alpha.56",
"#material-ui/pickers": "^3.2.10",
"#types/pdfjs-dist": "^2.1.5",
"aws-amplify": "^3.0.22",
"babel-polyfill": "6.26.0",
"connected-react-router": "^6.3.2",
"date-fns": "^2.14.0",
"env-cmd": "8.0.2",
"formik": "2.1.5",
"history": "4.7.2",
"juice": "^7.0.0",
"lodash": "^4.17.11",
"pdf-viewer-reactjs": "^2.0.7",
"pdfjs-dist": "2.4.456",
"raw-loader": "^4.0.1",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-hot-toast": "^1.0.2",
"react-intl": "2.7.2",
"react-redux": "^6.0.1",
"react-router": "4.3.1",
"react-router-dom": "4.3.1",
"react-scripts": "^2.1.5",
"redux": "4.0.1",
"redux-persist": "5.10.0",
"redux-persist-transform-filter": "^0.0.20",
"redux-saga": "^1.0.2",
"styled-components": "4.1.1",
"superagent": "4.0.0",
"typesafe-actions": "^3.0.0",
"yup": "^0.28.3"
},
"scripts": {
"start": "HTTPS=true REACT_APP_ENV=local react-app-rewired start",
"start:windows": "set HTTPS=true&&set REACT_APP_ENV=local&&react-app-rewired start",
"build": "env-cmd .env.${REACT_APP_ENV} react-app-rewired build",
"build:staging": "REACT_APP_ENV=staging env-cmd .env.staging react-app-rewired build ",
"build:qa": "REACT_APP_ENV=qa env-cmd .env.qa react-app-rewired build ",
"build:qaint": "REACT_APP_ENV=qaint env-cmd .env.qaint react-app-rewired build ",
"build:euat": "REACT_APP_ENV=euat env-cmd .env.euat react-app-rewired build ",
"test": "react-app-rewired test --maxWorkers=4",
"test:ci": "react-app-rewired test --maxWorkers=4 --all --coverage",
"eject": "react-app-rewired eject",
"analyze": "env-cmd .env.${REACT_APP_ENV} react-app-rewired build --analyze-bundle",
"test:coverage": "npm run test -- --coverage",
"generate": "plop --plopfile scripts/generators/index.js",
"lint": "eslint 'src/**/*.{js,ts,tsx}'",
"lint:fix": "eslint 'src/**/*.{js,ts,tsx}' --fix",
"lint-style": "stylelint 'src/**/*.style.{ts,tsx}' 'src/**/style.{ts,tsx}'",
"cypress:run": "sudo docker-compose -f docker-compose-cypress.yml run e2e-chrome"
},
"browserslist": [
">0.2%",
"not dead",
"not ie < 11",
"not op_mini all"
],
"jest": {
"collectCoverageFrom": [
"src/**/*.js",
"!src/**/*.test.js",
"!src/**/actions.js",
"!src/**/index.js",
"!src/**/serviceWorker.js",
"!src/**/*.wrap.js",
"!src/index.js",
"!src/tempPolyfills.js",
"!src/setupTests.js",
"!src/redux/reducers.js",
"!src/redux/sagas.js",
"!src/redux/store.js",
"!src/**/mocks/**",
"!src/redux/reducers.ts",
"!src/redux/sagas.ts"
],
"coverageThreshold": {
"global": {
"statements": 0,
"branches": 0,
"functions": 0,
"lines": 0
}
},
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
],
"setupFiles": [
"core-js"
]
},
"bundlesize": [
{
"path": "./build/static/js/*.js",
"maxSize": "200 kB"
}
],
"devDependencies": {
"#types/cheerio": "^0.22.10",
"#types/enzyme": "^3.1.15",
"#types/enzyme-react-intl": "^2.0.0",
"#types/history": "^4.7.2",
"#types/jest": "^23.3.12",
"#types/lodash": "^4.14.119",
"#types/node": "^10.12.18",
"#types/pdf-viewer-reactjs": "^2.0.0",
"#types/react": "^16.8.3",
"#types/react-dom": "^16.0.11",
"#types/react-intl": "^2.3.15",
"#types/react-redux": "^6.0.12",
"#types/react-router": "^4.4.3",
"#types/react-router-dom": "^4.3.1",
"#types/react-test-renderer": "^16.0.3",
"#types/redux-mock-store": "^1.0.2",
"#types/styled-components": "^4.1.5",
"#types/superagent": "^3.8.6",
"#types/webpack-env": "^1.13.6",
"#types/yup": "^0.26.34",
"#typescript-eslint/eslint-plugin": "^1.6.0",
"#typescript-eslint/parser": "^1.6.0",
"babel-plugin-styled-components": "1.8.0",
"enzyme": "3.7.0",
"enzyme-adapter-react-16": "1.15",
"enzyme-react-intl": "^2.0.6",
"enzyme-to-json": "3.3.4",
"eslint-config-prettier": "4.1.0",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-jest": "22.0.0",
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-mysticatea": "4.2.4",
"eslint-plugin-prefer-object-spread": "1.2.1",
"eslint-plugin-prettier": "3.0.0",
"eslint-plugin-react": "7.11.1",
"husky": "^4.2.5",
"mockdate": "^3.0.2",
"plop": "2.1.0",
"prettier": "1.15.1",
"react-app-rewire-webpack-bundle-analyzer": "1.0.1",
"react-app-rewired": "2.1.0",
"react-test-renderer": "16.10",
"redux-mock-store": "^1.5.4",
"redux-saga-test-plan": "^4.0.0-beta.2",
"stylelint": "^9.10.1",
"stylelint-config-prettier": "^4.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-declaration-strict-value": "^1.1.2",
"stylelint-processor-styled-components": "^1.5.2",
"typescript": "^3.2.2",
"wait-on": "^3.2.0",
"webpack-manifest-plugin": "^2.0.4"
}
}
Below config-overrides.js
const { styles } = require( '#ckeditor/ckeditor5-dev-utils' );
module.exports = {
webpack: function override(config, env) {
const analyzeBundle = process.argv.indexOf('--analyze-bundle') !== -1;
if (analyzeBundle) {
const rewireWebpackBundleAnalyzer = require('react-app-rewire-webpack-bundle-analyzer');
config = rewireWebpackBundleAnalyzer(config, env, {
analyzerMode: 'static',
reportFilename: 'report.html',
});
}
// Fix strange issue with webpack build
// details here: https://stackoverflow.com/questions/60407393/create-react-app-production-build-runtime-error-cannot-read-property-call-of
// TODO: maybe update webpack to fix while keeping import optimization
config.optimization.sideEffects = false;
// Customize webpack config here
console.log("Loading Custom config for Webpack, rebuilding ckeditor");
const oneOfIndex = config.module.rules.findIndex(item => {
return item.hasOwnProperty("oneOf");
});
oneOf = config.module.rules[oneOfIndex].oneOf;
// Add the SVG and CSS loaders to the oneOf array
const additions = [
{
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ["raw-loader"]
},
{
test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
use: [
{
loader: "style-loader",
},
{
loader: "postcss-loader",
options: styles.getPostCssConfig({
themeImporter: {
themePath: require.resolve("#ckeditor/ckeditor5-theme-lark")
},
minify: true
})
}
]
}
];
additions.forEach((item) => {
oneOf.push(item);
});
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
// Modify cssRegex
let loader;
loader = oneOf.find(item => {
if (item.test !== undefined)
return item.test.toString() === cssRegex.toString();
});
loader.exclude = [cssModuleRegex, /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/];
// Modify cssModuleRegex
loader = oneOf.find(item => {
if (item.test !== undefined)
return item.test.toString() === cssModuleRegex.toString();
});
loader.exclude = [/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/];
// Modify file-loader
loader = oneOf.find(item => {
if (item.loader !== undefined)
return (
item.loader.toString() === require.resolve("file-loader").toString()
);
});
loader.exclude = [
/\.(js|mjs|jsx|ts|tsx)$/,
/\.html$/,
/\.json$/,
/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/
];
config.module.rules[oneOfIndex].oneOf = oneOf;
return config;
},
devServer: function(configFunction) {
// Return the replacement function for create-react-app to use to generate the Webpack
// Development Server config. "configFunction" is the function that would normally have
// been used to generate the Webpack Development server config - you can use it to create
// a starting configuration to then modify instead of having to create a config from scratch.
return function(proxy, allowedHost) {
// Create the default config by calling configFunction with the proxy/allowedHost parameters
const defaultConfig = configFunction(proxy, allowedHost);
return {
...defaultConfig,
hot: true,
historyApiFallback: true,
// Allow mounting react apps from a page served by the backend.
headers: {
'Access-Control-Allow-Origin': 'http://localhost:8080',
},
};
};
},
};
I am trying to load another react application as a microfront end using :
I ve tested the imported microfront end in a simple react app (container) and everything went well
import React, {useCallback, useEffect} from 'react';
import {History} from 'history';
interface MicroFrontendProps {
history?: History;
name: string;
host: string | undefined;
}
const MicroFrontend: React.FC<MicroFrontendProps> = ({history, name, host,}) => {
const renderMicroFrontend = useCallback(() => {
(window as any)[`render${name}`](`${name}-container`, history);
}, [name, history]);
useEffect(() => {
const scriptId = `micro-frontend-script-${name}`;
if (document.getElementById(scriptId)) {
renderMicroFrontend();
} else {
fetch(`${host}/asset-manifest.json`)
.then(res => res.json())
.then(manifest => {
const promises = Object.keys(manifest.files)
.filter(key => key.endsWith('.js'))
.reduce((sum, key) => {
sum.push(
new Promise(resolve => {
const path = `${host}${manifest.files[key]}`;
const script = document.createElement('script');
if (key === 'main.js') {
script.id = scriptId;
}
script.onload = () => {
resolve();
};
script.crossOrigin = '';
script.src = path;
document.body.after(script);
}),
);
return sum;
}, [] as any);
Promise.allSettled(promises).then(() => {
renderMicroFrontend();
});
});
}
return () => {
(window as any)[`unmount${name}`](`${name}-container`);
};
}, [renderMicroFrontend, host, name]);
return <main id={`${name}-container`} />;
};
export default MicroFrontend;
When I am importing the app, when I go to a link which loads it I am getting this error (the imported app is rendred but server shuts down) :
webpackHotDevClient.js:60 WebSocket connection to 'wss://localhost:3000/sockjs-node' failed:
./node_modules/react-dev-utils/webpackHotDevClient.js # webpackHotDevClient.js:60
webpackHotDevClient.js:76 The development server has disconnected.
Refresh the page if necessary.
Do you have any idea about this error ?
Thanks