Related
Background
Need to create an external React component library using existing components from a Next.js site, using Tailwindcss#^2. This needs to be pulled in using npm, onto any site that requires the components.
Problem
I've managed to create the package using Webpack#^5 to compile. This is all fine, but the problem I face is that, the components don't work when reintroduced to the initial site. I have a feeling this is either the compiling is wrong or the fact that Next.js is server side rendered, or it could be both.
Attempted solution
I have tried to use Rollup as an alternate solution to compile the components, but I keep running into an issue with Postcss. A common issue I've noticed, where it's asking for v8 of PostCss (which it appears is present in node_modules), but it still complains. I did have a similar issue when using Webpack, but was eventually able to fix this. I've tried similar methods to fix for Rollup, but no luck.
package.json
{
"name": "#github_account/package_name",
"description": "Lorem ipsum",
"author": "github_account",
"version": "1.0.0",
"license": "ISC",
"repository": {
"type": "git",
"url": "repo_name_here"
},
"main": "./build/main.cjs.js",
"module": "./build/main.esm.js",
"browser": "./build/main.js",
"source": "./src/index.js",
"publishConfig": {
"registry": "https://npm.pkg.github.com/github_account"
},
"scripts": {
"build-rollup": "rollup -c",
"build": "webpack --mode production"
},
"dependencies": {
"#babel/runtime": "^7.17.8",
"autoprefixer": "^9.8.8",
"classnames": "^2.2.6",
"formik": "^2.2.6",
"iframe-resizer-react": "^1.1.0",
"luxon": "^2.0.2",
"prop-types": "^15.8.1",
"react": "^17.0.0",
"react-collapsible": "^2.8.4",
"react-device-detect": "^2.1.2",
"react-dom": "^17.0.0",
"react-google-recaptcha-v3": "^1.9.7",
"react-icons": "^3.10.0",
"react-markdown": "^6.0.3",
"react-modal": "^3.14.4",
"react-select": "^5.0.0",
"react-slick": "^0.28.1",
"react-table": "^7.7.0",
"sass": "^1.42.1",
"slick-carousel": "^1.8.1",
"yup": "^0.32.8"
},
"devDependencies": {
"#babel/core": "^7.18.6",
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/plugin-transform-runtime": "^7.18.9",
"#babel/preset-env": "^7.18.6",
"#babel/preset-react": "^7.18.6",
"#rollup/plugin-babel": "^5.3.1",
"#rollup/plugin-commonjs": "^22.0.1",
"#rollup/plugin-node-resolve": "^13.3.0",
"#squoosh/lib": "^0.4.0",
"autoprefixer": "~9",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.2.5",
"clean-webpack-plugin": "^4.0.0",
"cross-env": "^7.0.2",
"css-loader": "^6.7.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-standard": "^4.0.1",
"image-minimizer-webpack-plugin": "^3.2.3",
"microbundle-crl": "^0.13.11",
"mini-css-extract-plugin": "^2.6.1",
"next": "^12.1.0",
"next-seo": "^4.28.1",
"npm-run-all": "^4.1.5",
"path": "^0.12.7",
"postcss": "8.4.6",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^14.1.0",
"postcss-loader": "^4.3.0",
"postcss-nested": "^5.0.6",
"postcss-preset-env": "^6.7.1",
"prettier": "^2.3.1",
"react-scripts": "^3.4.1",
"rollup": "^2.77.0",
"rollup-plugin-filesize": "^9.1.2",
"rollup-plugin-image": "^1.0.2",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-tailwindcss": "^1.0.0",
"sass-loader": "^12",
"tailwindcss": "^2.2.6",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
}
}
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const stylesHandler = MiniCssExtractPlugin.loader;
module.exports = {
devtool: "source-map",
context: __dirname,
entry: "./src/index.js",
externals: [nodeExternals({ importType: "umd" })],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "./dist"),
libraryTarget: "umd",
library: {
name: "cruil",
type: "umd",
},
assetModuleFilename: (pathData) => {
const filepath = path.dirname(pathData.filename).split("/").slice(1).join("/");
return `${filepath}/[name].[hash][ext][query]`;
},
globalObject: "this",
},
experiments: {
outputModule: true,
},
optimization: {
runtimeChunk: "single",
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
pngquant: {
quality: 90,
},
},
},
},
}),
],
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace("#", "")}`;
},
},
},
},
},
module: {
rules: [
{
test: /\.js$|jsx/,
include: path.resolve(__dirname, "./src"),
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.(s(a|c)ss)$/,
use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
include: path.resolve(__dirname, "./src"),
},
{
test: /\.css$/i,
use: [stylesHandler, "css-loader", "postcss-loader"],
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
include: path.resolve(__dirname, "./src/assets"),
type: "asset/resource",
},
],
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin(),
new webpack.DefinePlugin({
"process.env": {
// This has effect on the react lib size
NODE_ENV: JSON.stringify("production"),
},
}),
],
};
rollup.config.js
import babel from "#rollup/plugin-babel";
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import postcss from "rollup-plugin-postcss";
import filesize from "rollup-plugin-filesize";
import autoprefixer from "autoprefixer";
import image from "rollup-plugin-image";
import external from "rollup-plugin-peer-deps-external";
import replace from "rollup-plugin-replace";
import tailwind from "rollup-plugin-tailwindcss";
import pkg from "./package.json";
const INPUT_FILE_PATH = "src/index.js";
const OUTPUT_NAME = "main";
const GLOBALS = {
react: "React",
"react-dom": "ReactDOM",
"prop-types": "PropTypes",
};
const getBabelOptions = ({ useESModules }) => ({
babelrc: false,
exclude: "node_modules/**",
extensions: [".js", ".ts", ".jsx", ".tsx"],
babelHelpers: "runtime",
presets: [["#babel/preset-env", { modules: false }], "#babel/preset-react"],
plugins: [["#babel/transform-runtime", { regenerator: false, useESModules }], "#babel/plugin-syntax-jsx"],
});
const PLUGINS = [
external({
includeDependencies: true,
}),
image(),
tailwind({
input: "./src/styles/index.css",
purge: false,
}),
postcss({
extract: true,
modules: true,
plugins: [autoprefixer],
}),
resolve({
browser: true,
resolveOnly: [/^(?!react$)/, /^(?!react-dom$)/, /^(?!prop-types)/],
preferBuiltins: false,
}),
commonjs({
include: /node_modules/,
}),
replace({ "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }),
babel(getBabelOptions({ useESModules: true })),
filesize(),
];
const EXTERNAL = ["react", "react-dom", "prop-types"];
// https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
const CJS_AND_ES_EXTERNALS = EXTERNAL.concat(/#babel\/runtime/);
const OUTPUT_DATA = [
{
file: pkg.browser,
format: "umd",
},
{
file: pkg.main,
format: "cjs",
},
{
file: pkg.module,
format: "es",
},
];
const config = OUTPUT_DATA.map(({ file, format }) => ({
input: INPUT_FILE_PATH,
output: {
file,
format,
name: OUTPUT_NAME,
globals: GLOBALS,
},
external: ["cjs", "es"].includes(format) ? CJS_AND_ES_EXTERNALS : EXTERNAL,
plugins: PLUGINS,
}));
export default config;
postcss.config.js
module.exports = {
plugins: [
require("postcss-import"),
require("tailwindcss"),
require("postcss-flexbugs-fixes"),
require("postcss-nesting"),
require("postcss-custom-properties"),
require("autoprefixer"),
],
};
index.js
import "./styles/index.css";
import ExampleTestComponent from "./components/ExampleTestComponent";
...
export {
ExampleTestComponent,
...
}
ExampleTestComponent.js
import React from "react";
const ExampleTestComponent = (props) => {
return (
<div className="ExampleTestComponentClass">
--- This is a test ---
</div>
);
};
export default ExampleTestComponent;
index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
Site Implementation
import ExampleTestComponent from "#github_account/package_name";
const HomePageTemplate = ({ heroItems, partners, newsItems, videos }) => {
const partnerItems = partners.map((partner) => ({
image: partner.logo,
url: partner.url,
}));
return (
<HomePageLayout heroItems={heroItems} partnerItems={partnerItems}>
<ExampleTestComponent />
<SuccessStoriesSlider videos={videos} />
<NewsBlock
newsItems={newsItems}
title="News"
subtitle="Latest news posts"
viewMoreBtnLabel="View Posts"
readMoreBtnLabel="Read More"
/>
</HomePageLayout>
);
};
export default HomePageTemplate;
UPDATE 1
Turns out a combination of using Yarn and adding the below
{
"resolutions": {
"postcss": "8"
}
}
to package.json, fixes the Postcss issue. So now I have the package created, I am attempting to import into the main site. However I'm now getting the error:
Error: Must use import to load ES Module: /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js
require() of ES modules is not supported.
require() of /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js from /node_modules/#github_account/package_name/build/main.cjs.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename defineProperty.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/package.json.
I am having difficulty with resolving webpack deployment issue.
In development mode everything seems fine, but as I deployed this project through vercel, I am only getting blank screen. When I checked the page, nothing but index.html existed. (no other js files)
These are my files below. I really want to know what on earth the problem is.
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('#pmmmwh/react-refresh-webpack-plugin');
const { ESBuildMinifyPlugin } = require('esbuild-loader');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = () => ({
mode: isDevelopment ? 'development' : 'production',
devtool: isDevelopment ? 'eval-cheap-module-source-map' : false,
cache: { type: isDevelopment ? 'memory' : 'filesystem' },
entry: './src/index.tsx',
target: 'web',
output: {
filename: 'js/[name]-[chunkhash].js',
assetModuleFilename: 'img/[hash][ext][query]',
pathinfo: false,
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
clean: true,
},
resolve: {
alias: {
icons: path.resolve(__dirname, 'public/assets/icons'),
images: path.resolve(__dirname, 'public/assets/images'),
components: path.resolve(__dirname, 'src/components'),
data: path.resolve(__dirname, 'src/data'),
docs: path.resolve(__dirname, 'src/docs'),
pages: path.resolve(__dirname, 'src/pages'),
styles: path.resolve(__dirname, 'src/styles'),
types: path.resolve(__dirname, 'src/types'),
utils: path.resolve(__dirname, 'src/utils'),
},
extensions: ['*', '.js', '.tsx', '.ts'],
modules: [__dirname, 'src', 'node_modules'],
fallback: {
process: require.resolve('process/browser'),
zlib: require.resolve('browserify-zlib'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
buffer: require.resolve('buffer'),
assert: require.resolve('assert'),
},
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'esbuild-loader',
options: {
loader: 'tsx',
target: 'esnext',
},
},
{
test: /\.(png|jpg|svg|gif)$/,
type: 'asset/resource',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(ts|tsx)$/,
exclude: '/node_modules',
use: 'ts-loader',
},
{
test: /restructure(\/|\\)src(\/|\\)[\w]+.js/,
use: [
{
loader: 'imports-loader',
options: {
type: 'commonjs',
imports: 'multiple ../../buffer/ Buffer Buffer',
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' }),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
}),
new webpack.EnvironmentPlugin({
DEVELOPMENT: isDevelopment,
}),
isDevelopment && new webpack.HotModuleReplacementPlugin(),
isDevelopment && new ReactRefreshWebpackPlugin(),
],
optimization: {
minimize: !isDevelopment,
minimizer: [
new ESBuildMinifyPlugin({
target: 'esnext',
css: true,
}),
],
splitChunks: {
chunks: 'all',
},
},
externals: {
axios: 'axios',
},
devServer: {
port: 3000,
open: true,
hot: true,
historyApiFallback: true,
},
});
package.json
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"engines": {
"node": ">=16.15.0",
"yarn": ">=1.22.17"
},
"scripts": {
"build": "webpack",
"dev": "NODE_ENV=development & webpack serve --progress",
"build:dev": "NODE_ENV=development & yarn build",
"build:prod": "NODE_ENV=production & yarn build"
},
"keywords": [],
"devDependencies": {
"#pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"#react-pdf/types": "^2.1.0",
"#types/react": "^18.0.12",
"#types/react-dom": "^18.0.5",
"#types/shortid": "^0.0.29",
"#types/styled-components": "^5.1.25",
"#typescript-eslint/eslint-plugin": "^5.27.1",
"#typescript-eslint/parser": "^5.27.1",
"css-loader": "^6.7.1",
"esbuild-loader": "^2.19.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"html-webpack-plugin": "^5.5.0",
"imports-loader": "^4.0.0",
"lodash": "^4.17.21",
"prettier": "^2.6.2",
"react-refresh": "^0.13.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.3.0",
"typescript": "^4.7.3",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.2"
},
"dependencies": {
"#react-pdf/renderer": "^2.2.0",
"assert": "^2.0.0",
"axios": "^0.27.2",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"node-env": "^0.1.6",
"process": "^0.11.10",
"react": "^18.1.0",
"react-daum-postcode": "^3.1.1",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0",
"shortid": "^2.2.16",
"stream-browserify": "^3.0.0",
"styled-components": "^5.3.5",
"styled-reset": "^4.4.1",
"util": "^0.12.4"
}
}
index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import GlobalFont from 'styles/globalFont';
import GlobalStyle from 'styles/globalStyle';
import App from './App';
const rootEl = document.getElementById('root');
if (!rootEl) throw new Error('Failed to find the root element');
const root = createRoot(rootEl);
root.render(
<React.StrictMode>
<GlobalFont />
<GlobalStyle />
<App />
</React.StrictMode>,
);
App.tsx
import Home from 'pages/Home';
import PdfViewer from 'pages/PdfViewer';
import Test from 'pages/Test';
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/docs" element={<PdfViewer />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
export default App;
I'm new to react and I've finished my project so now when I built the app using yarn build command I got this error while using serve.js web server.
I've deleted node_modules and installed them but no result aquired
Uncaught ReferenceError: ReactDOM is not defined
at Object. (bundle.js:1)
this the package.json file content
{
"name": "behtabweb",
"version": "1.0.2",
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js",
"stop": "pkill --signal SIGINT myApp",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"author": "alireza",
"license": "MIT",
"dependencies": {
"#material-ui/core": "^3.9.2",
"#material-ui/icons": "^3.0.2",
"#react-pdf/renderer": "^1.6.0",
"bootstrap": "^4.3.1",
"brfs": "^2.0.2",
"chart.js": "^2.8.0",
"cross-spawn": "^6.0.5",
"downloadjs": "^1.4.7",
"jspanel4": "^4.6.0",
"material-table": "^1.32.0",
"material-ui-image": "^3.2.0",
"notistack": "^0.6.1",
"ol": "^5.3.1",
"pdfkit": "^0.9.1",
"react": "^16.8.6",
"react-bootstrap": "^1.0.0-beta.5",
"react-chartjs-2": "^2.7.6",
"react-dom": "^16.7.0",
"react-jss": "^8.6.1",
"react-localize-redux": "^3.5.2",
"react-router": "^5.0.0",
"react-router-dom": "^5.0.0",
"react-scripts": "^3.0.0",
"react-swipeable-bottom-sheet": "^1.1.1",
"save-dev": "^2.0.0",
"unicode-properties": "^1.1.0",
"universal-cookie": "^3.0.7",
"vazir-font": "^19.2.0"
},
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/plugin-proposal-class-properties": "^7.4.4",
"#babel/preset-env": "^7.4.5",
"#babel/preset-react": "^7.0.0",
"autoprefixer-loader": "^3.2.0",
"babel-loader": "^8.0.5",
"babel-preset-es2015": "^6.24.1",
"babel-preset-latest": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"json-loader": "^0.5.7",
"less-loader": "^4.1.0",
"react-to-print": "^2.1.2",
"style-loader": "^0.23.1",
"transform-loader": "^0.2.4",
"url-loader": "^1.1.2",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.2.1"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
and this the webpack config file content
var webpaqck = require("webpack");
module.exports = {
resolve: {
alias: {
fs: 'pdfkit/js/virtual-fs.js'
}
},
entry: "./src/index.js",
output: {
path: __dirname + "/public/assets",
filename: "bundle.js",
publicPath: "assets"
},
devServer: {
inline: true,
contentBase: "./public",
port: 3003
},
// mode: 'development',
mode: 'production',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env', {
"targets": {
"node": "current"
}
}],
presets: ["#babel/preset-env", "#babel/preset-react"]
}
}
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}, {
test: /\.less$/,
use: ['style-loader',
'css-loader',
'less-loader']
},
{
test: /\.(png|jp(e*)g|svg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'images/[hash]-[name].[ext]'
}
}]
}
// ,
// {
// test:/\.json$/,
// exclude:/(node-modules)/,
// use:{
// loader:"json-loader"
// }
// }
]
}
}
this is the index.js file
import React from 'react'
import ReactDOM from 'react-dom'
import { render } from 'react-dom'
import { LocalizeProvider, Translate, withLocalize } from "react- localize-redux";
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import SignIn from './pages/SignIn'
import { SnackbarProvider } from 'notistack';
import Button from '#material-ui/core/Button';
import Login from './pages/login'
import whoops404 from './components/whoops404'
import dashboard from './pages/Dashboard'
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import white from '#material-ui/core/colors/yellow'
window.React = React.def
const themeRtl = createMuiTheme({
direction: 'rtl',
typography: {
fontFamily: 'Vazir, sans-serif',
useNextVariants: true,
}
});
const App = props => (
<MuiThemeProvider theme={themeRtl}>
<LocalizeProvider>
<SnackbarProvider maxSnack={3}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
action={[
<Button size="small">
<Translate id="dismiss" />
</Button>
]}>
<Router >
<div>
<Route path="/login" component={SignIn}></Route>
<Route exact path="/" component={dashboard}></Route>
</div>
</Router>
</SnackbarProvider>
</LocalizeProvider>
</MuiThemeProvider>
);
render(
<App />,
document.getElementById('react-continer')
)
the app works in development by webpack-dev-server but not in the deployment.
I'm new to doing unit testing and I keep getting this error:
Invariant Violation: Target container is not a DOM element.
at invariant (node_modules/fbjs/lib/invariant.js:42:15)
at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:17238:34)
at Object.render (node_modules/react-dom/cjs/react-dom.development.js:17317:12)
at Object. (src/client/index.js:243:73)
at Object. (src/client/components/block/Header.js:294:40)
at Object. (src/client/components/block/index.js:123:41)
at Object. (src/client/containers/app.js:195:40)
at Object. (tests/client/containers/App.test.js:13:12)
I think it has to do with the way my app.js is structured but dont know why...
Here my App.js :
const App = () => (
<Box>
<Router getUserConfirmation={getConfirmation} hashType={'noslash'} basename={'/'}>
<Box>
<Route exact path="/" component={Home}/>
<Route path="/:room" component={Room}/>
</Box>
</Router>
</Box>
)
const mapStateToProps = (state) => {
return {
message: state.message
}
}
export default connect(mapStateToProps, null)(App)
I'm using jest/enzyme/chai for unit tests
my App.test.js :
import { expect } from 'chai'
import React from 'react'
import { shallow } from 'enzyme'
import App from '../../../src/client/containers/app'
jest.mock('react-router')
describe('<App />', () => {
it('renders without crashing', () => {
const wrapper = shallow(
<App/>
).dive()
})
})
my devDependecies in package.json :
"devDependencies": {
"babel-cli": "^6.7.7",
"babel-core": "^6.7.7",
"babel-eslint": "^7.2.2",
"babel-jest": "^23.4.0",
"babel-loader": "^6.2.4",
"babel-plugin-__coverage__": "^0.111111.1",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.5.0",
"babel-watch": "^2.0.2",
"chai": "^4.1.2",
"chai-enzyme": "^1.0.0-beta.1",
"chai-jest-diff": "^1.0.2",
"chai-jest-snapshot": "^2.0.0",
"dirty-chai": "^2.0.1",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^4.0.0",
"eslint-plugin-babel": "^3.3.0",
"eslint-plugin-react": "^7.10.0",
"jest": "^23.4.1",
"nyc": "^6.4.4",
"react-test-renderer": "^16.4.1",
"redux-devtools-extension": "^2.13.5",
"webpack": "^1.13.0",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "^1.14.1",
"webpack-hot-middleware": "^2.10.0"
},
and my webpack.config.js :
var path = require('path');
module.exports = {
entry: './src/client/index.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
devServer: {
compress: true,
disableHostCheck: true,
},
watchOptions: {
poll: 1000,
aggregateTimeout:300,
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query:{
presets: ["es2015", "react", "stage-0"]
}
}]
}
};
Thank you for help :)
EDIT:
Looking for a solution, I noticed that the error occurs during the import of my components! Would it come from webpack?
EDIT:
My error was in my HEADER.JS because I use persistor for manage my user connection.
For moment I delete it
You want to ensure that your element with the id="root" in your index.html file is not set on on the body element. Reason being that by the time the script finishes execution, document element is not available yet.
Refer to this answer by #Dan Abramov here.
My react app work fine in webpack-dev-server but production builds redirects to the page not found route. I have tried hashRouter too but it redirects to the homepage on every Route.
Please let me know what I am missing. I kind of new into this. Also, my build bundle is near about 2mbs. I tried some code splitting but that didn't worked.
Here is my webpack.config.js-
var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const extractSass = new ExtractTextPlugin({
filename: "style.css",
});
module.exports = {
entry: {
main: './src/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
},
module: {
loaders: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
},
{
test: /\.s?css$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
fallback: "style-loader"
})
},
{
test: /\.(eot|svg|ttf|woff(2)?)(\?v=\d+\.\d+\.\d+)?/,
loader: 'url-loader'
},
{
test: /\.html$/,
use: ['html-loader']
},
{
test: /\.(jpg|png)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
publicPath: ''
}
}
]
}
]
},
plugins:[
new CleanWebpackPlugin(['dist']),
extractSass,
new HtmlWebpackPlugin({
title: 'Caching',
template: 'index.html'
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
sequences: true,
dead_code: true,
conditionals: true,
booleans: true,
unused: true,
if_return: true,
join_vars: true,
drop_console: true
},
mangle: {
except: ['$super', '$', 'exports', 'require']
},
output: {
comments: false
}
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
]
};
package.json file.
{
"name": "react-afinoz",
"version": "1.0.0",
"description": "Afinoz Get best and cheap Loans in Delhi, Noida",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npm run prod",
"build": "webpack-dev-server --content-base src/ --inline --hot --open --history-api-fallback",
"prod": "webpack -p --progress"
},
"author": "",
"license": "ISC",
"dependencies": {
"autoprefixer": "^7.1.6",
"aws-sdk": "^2.128.0",
"axios": "^0.16.2",
"node-sass": "^4.5.3",
"preload-webpack-plugin": "^2.0.0",
"react": "^15.6.1",
"react-cookies": "^0.1.0",
"react-document-meta": "^2.1.2",
"react-dom": "^15.6.1",
"react-materialize": "^1.0.16",
"react-router": "^4.1.2",
"react-router-dom": "^4.1.2",
"react-s3-uploader": "^4.5.0",
"script-ext-html-webpack-plugin": "^1.8.7",
"style-ext-html-webpack-plugin": "^3.4.3",
"url-loader": "^0.5.9"
},
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"clean-webpack-plugin": "^0.1.16",
"compression-webpack-plugin": "^1.0.1",
"css-loader": "^0.28.4",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"node-sass": "^4.5.3",
"postcss-loader": "^2.0.8",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"webpack-merge": "^4.1.0"
}
}
index.js file:-
import React from "react"
import ReactDOM from "react-dom"
import { BrowserRouter,browserHistory} from 'react-router-dom'
import App from "./routes.js"
import style from "./sass/style.scss"
const main = document.getElementById('main')
ReactDOM.render((
<BrowserRouter history={browserHistory}>
<App />
</BrowserRouter>
), main);
Router.js file:-
import React from "react"
import { Switch, Route } from 'react-router-dom'
import Home from "./home"
import Login from "./login"
import SignUp from "./signUp"
import NotFound from "./404.js"
export default class App extends React.Component{
render(){
return(
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/login' component={Login}/>
<Route path='/signUp' component={SignUp}/>
<Route path="*" component={NotFound}/>
</Switch>
);
}
}
Here,try to use absolute path rather than relative
entry: {
main: path.join(__dirname, './src/app.tsx'),
}