I have created a sample react app from createapp.dev and added antd in the package.json.
I have been playing around with the table component from antd, and all worked fine when running locally. My snippet looks like this:
import React from 'react';
import {Table} from "antd";
export default class App extends React.Component {
render() {
return(
<div>
<div>Table</div>
<Table dataSource={[]} columns={[]} />
</div>
)
}
}
And the package.json is this:
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"keywords": [],
"author": "",
"license": "ISC",
"scripts": {
"clean": "rm dist/bundle.js",
"start": "parcel src/index.html",
"build": "parcel build src/index.html"
},
"dependencies": {
"antd": "^4.8.2",
"react": "^17.0.0",
"react-dom": "^17.0.0"
},
"devDependencies": {
"parcel-bundler": "^1.12.4",
"#babel/core": "^7.12.3",
"#babel/preset-env": "^7.12.1",
"#babel/preset-react": "^7.12.1"
}
}
Then after running yarn build command it successfully generates the build, but when serving the production build, it breaks with errors like TypeError: s is not a function which comes from Header component of rc-table.
I've searched for a workaround and but wasn't able to find a solution. Does that mean we can't use Table component from antd and why is this issue not detected when running the production build? Has anyone encountered a similar issue?
Edit: Found an online demo with a similar issue
The Parcel Bundler (1.x.x) does not support multiple JS files having the same content.
You can add the following script in scripts/fix-parcel-rc-table-issue.js. Then run it before each build (e.g. "build": "node fix-parcel-rc-table-issue.js && parcel build index.html". ).
const fs = require('fs')
const MARKER = 'CHANGE_CONTENT_HASH'
for (const file of ['BodyContext.js', 'ResizeContext.js', 'TableContext.js']) {
const filePath = require.resolve(`rc-table/es/context/${file}`)
const content = fs.readFileSync(filePath).toString()
if (content.includes(MARKER)) {
continue
}
const newContent =
content + `\nfunction ${MARKER} () { return ${Math.random()} }`
fs.writeFileSync(filePath, newContent)
}
Background
This exact issue has been reported to Ant Design as a bug. They did some digging and found the underlying parcel issue. Here you can find some details.
The Parcel developers don't want to fix this in 1.x.x, but are telling users to switch to the (currently) unstable 2.x.x version. This issue has some more details.
The Parcel developers suggest using the --experimental-scope-hoisting flag. This breaks my build, so I can't verify that this actually fixes the problem. I advise against using this flag in production as it's experimental, so it might have unexpected side-effects (in my opinion Parcels track record generally isn't very good).
Instead I followed FocusCare's advice and simply changed the contents of the files to be unique. This is a nasty hack though, but seems to be the best option until Parcel 2.x.x comes out (or you switch to a more mature bundler).
Related
I'm trying to use useState in a simple function component in GatsbyJS but I'm getting a seemingly common error in React.
My stripped-down component:
import React, { useState } from 'react';
export default function Header () {
const [isOpen, toggleOpen] = useState(false);
return (
<header>
<button onClick={() => toggleOpen( !isOpen )}>Click Me</button>
</header>
)
}
I get the following error:
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See redacted to quell SO error for tips about how to debug and
fix this problem.
So I read up about the error on this Facebook/React docs page and have determined that my react-dom version is >16.8.0 (I'm using ^16.13.1). My react version is the same.
I'm pretty sure there's nothing wrong with my component function (I basically copied the example from the docs).
The third thing, which I suspect is the issue, is multiple versions of react running simultaneously. When I run npm ls react I get:
+-- gatsby#2.24.73
| `-- gatsby-cli#2.12.107
| `-- react#16.13.1 deduped
`-- react#16.13.1
I tried moving react and react-dom to peerDependencies, as per this response from this Github issues thread, in my `package.json' but that didn't fix the problem, e.g:
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
}
I also tried adding a GATSBY_HOT_LOADER = “fast-refresh” var in a .env.development file according to this Gatsby thread but the issue persisted.
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
Here's my package.json
{
"name": "gatsby-starter-hello-world",
"private": true,
"description": "A simplified bare-bones starter for Gatsby",
"version": "0.1.0",
"license": "0BSD",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
},
"dependencies": {
"gatsby": "^2.24.73",
"gatsby-image": "^2.4.21",
"gatsby-plugin-sass": "^2.3.16",
"gatsby-plugin-sharp": "^2.6.40",
"gatsby-source-filesystem": "^2.3.34",
"gatsby-transformer-sharp": "^2.5.17",
"hamburgers": "^1.1.3",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"eslint-plugin-react-hooks": "^4.1.2",
"prettier": "2.1.2"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
},
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
}
}
And environment info:
System:
OS: Windows 10 10.0.18362
CPU: (8) x64 Intel(R) Core(TM) i5-8300H CPU # 2.30GHz
Binaries:
Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 44.18362.449.0
npmPackages:
gatsby: ^2.24.73 => 2.24.73
gatsby-image: ^2.4.21 => 2.4.21
gatsby-plugin-sass: ^2.3.16 => 2.3.16
gatsby-source-filesystem: ^2.3.34 => 2.3.34
I've been using Gatsby without issues for some time now so I'm surprised by this error. I suspect it has to do with Gatsby running a version of React, although "deduped", and another version of React also running as seen when I run npm ls react.
Where can I go from here?
Thanks,
I'm also using React#16.13.1. Notably, the gatsby-starter currently only uses React#16.12.1. I ultimately came across an answer from Jeremy Albright on the Gatsby Spectrum that pointed out this could be related to react-hot-loader being deprecated.
Gatsby already has support instead for fast-refresh, you just have to enable the flag.
The fix that worked for me was to add GATSBY_HOT_LOADER=fast-refresh to my .env file.
Source
So I ended up starting over and downloading a fresh copy of the gatsby-starter I was using and that's resolved the issue.
I think I inadvertently installed react and react-dom while I was trying to install a plugin at some point and having multiple versions of react running (one within gatsby) and one installed somewhere else in my project caused the issue.
I have a little problem with React Native, I'm using the ant design RN for UI components (https://rn.mobile.ant.design/)
But when i tried to load the ant design fonts , an error appeared. It sayed
"Unable to resolve
"#ant-design/icons-react-native/fonts/antoutline.ttf" from "App.js"
.
the code :
async componentDidMount() {
await Font.loadAsync({
antoutline: require("#ant-design/icons-react-
native/fonts/antoutline.ttf")
})
}
Package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"#ant-design/icons-react-native": "^1.0.2",
"#ant-design/react-native": "^3.1.3",
"expo": "^32.0.0",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0"
},
"private": true
}
I'm using Expo as a cli
Unfortunately you are trying to use a dependency that requires linking of native code.
From their installation instructions you can see the following:
react-native link #ant-design/icons-react-native
As your app is made with Expo, and the native code is abstracted away from you, it is not possible to use the link command.
Your options are:
Eject your Expo project using expo eject. This will give you full access to the native code. You can read more about it here.
Expo comes with AntDesign icons built in, you can access them using #expo/vector-icons. There is more in the documentation here.
Your easiest option is 2, using #expo/vector-icons. You don't need to install anything to use them.
Just add the following import to your component
import { AntDesign } from '#expo/vector-icons';
Then in your render you can use them in the following way:
<AntDesign name="stepforward" size={32} color="green" />
Making sure to check that the icon you want is available in the directory
If you want to preload your font. The font object is available as a static property on the font component, so in the case above it is AntDesign.font, which should evaluate to something like {antdesign: require('path/to/antdesign.ttf')}
The documentation on fonts and icons on the Expo website is full of great examples.
I've recently converted an internal component library I'm working on to Styled Components. That component library has Styled Components listed as a peerDep and a devDep in the package.json. From there I'm importing Styled Comopnents into every component that needs styling. All works great up to that point.
I have a Create React App (CRA) application that also imports Styled Comopnents as a regular dependency. I need this to be able to build one-off components for this specific project. BUT I also need the ability to import my component library to build out core components for this new CRA-based app.
Now this is my problem: I'm testing my recently converted Styled Components-based component library in this CRA app by linking directly to the component library in package.json (file:../component-lib). I've installed all my deps, imported components from the component library, built a new project specific Styled Component within the CRA project, and ran it locally only to see this same error: "It looks like there are several instances of 'styled-components' initialized in this application. This may cause dynamic styles not rendering properly, errors happening during rehydration process and makes your application bigger without a good reason." I've read that section of docs and learned not to use npm link and to serve SC as a peerDep and a devDep in my component library.
I believe this issue is not allowing me to access theme props I'm passing into a custom ThemeProvider from the component library since I'm running multiple instances in the CRA project?
This problem is definitely due to my lack of knowledge in dependency management. I'm just wondering if anyone else has encountered a similar issue or what I should be doing to avoid duplicate instances of Styled Comopnents?
Component library index
export { default as Button } from "./components/Button";
export {
default as CustomThemeProvider
} from "./components/utils/CustomThemeProvider";
Component library package.json
"scripts": {
"build": "nwb build-react-component --copy-files",
"clean": "nwb clean-module && npm clean-demo",
"start": "nwb serve-react-demo",
"lint": "eslint src/**",
"test": "nwb test-react",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build",
"test:coverage": "nwb test-react --coverage",
"test:watch": "nwb test-react --server",
"publish": "npm run build && npm publish"
},
"dependencies": {
"#rebass/grid": "^6.0.0-4",
"prop-types": "^15.6.0",
"react-portal": "^4.1.2"
},
"peerDependencies": {
"react": "16.x",
"styled-components": "^4.0.3"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"eslint": "^4.18.2",
"eslint-plugin-react": "^7.7.0"
"prettier": "1.14.3",
"nwb": "0.22.x",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-styleguidist": "^7.2.0",
"styled-components": "^4.0.3"
},
Component library NWB config
module.exports = {
type: "react-component",
npm: {
esModules: false,
umd: false,
},
babel: {
stage: 1
}
};
CRA Project package.json
"dependencies": {
"component-library": "0.16.6",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react-scripts": "2.1.0",
"styled-components": "^4.0.3"
},
This is only a partial answer that I'm hoping will enable you or someone else to figure out the rest. I'm far from an expert on managing these kind of dependencies and am helping with this to further my own knowledge since I may want to do a similar setup soon.
Though it seems this should be doable with nwb, I switched to using webpack directly in order to have more control. Even using webpack directly I have only made it part of the way there. Everything works correctly when I do a build, but in dev mode (npm start) for the CRA app, the styled-components package is still getting pulled in twice and the styling doesn't work correctly. This seems like a potential webpack issue since the dev and production modes behave so differently, but it could be something with the CRA webpack dev configuration or (more likely) some aspect of this that I don't yet understand.
This is a good example to reference for the component library configuration: https://github.com/kalcifer/webpack-library-example
Here's my package.json for my test component lib (component-lib3 just because of trying several other approaches):
{
"name": "component-lib3",
"version": "1.0.7",
"description": "component-lib3 React component",
"main": "dist/component-lib3.js",
"peerDependencies": {
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3"
},
"devDependencies": {
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3",
"#babel/core": "^7.1.2",
"#babel/preset-env": "^7.1.0",
"#babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.4",
"webpack": "^4.24.0",
"webpack-cli": "^3.1.2"
},
"scripts": {
"build": "webpack"
}
}
Here's the webpack.config.js:
var path = require('path');
module.exports = {
entry: './src/index.js',
mode: 'production',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'component-lib3.js',
libraryTarget: 'umd',
library: 'component-lib3'
},
externals: {
"styled-components": {
commonjs: 'styled-components',
commonjs2: 'styled-components',
amd: 'styled-components'
},
"react": {
commonjs: 'react',
commonjs2: 'react',
amd: 'react'
},
"react-dom": {
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'react-dom'
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
And then also .babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
I tried a number of variations, and I don't understand why this won't work right for dev mode.
I am facing the same issue at this moment and I'm still not sure. I could fix it properly or not, so please don't take this answer as a guaranteed solution.
There are two things you can try.
The first one is something that appears in the styled-components FAQs section. They suggest configuring Webpack (I assume you are using Webpack too) with an alias so that it always looks for the styled-components dependency wherever you specify. This should avoid having several instances of styled-components, but so far I couldn't make this work for me.
The second option is to use an alternative no npm link. Apparently when you have a symlinked dependency (this is what npm linkdoes actually). The bundler's resolver tries to look for the dependency in the same project. This is also mentioned in the linked styled components FAQs section.
What you should do if you follow this approach is to avoid creating a symlink that points to your component library from the CRA app and copy the folder instead.
There is a tool called wml that can copy the contents of your component library into the node_modules folder of your CRA app. wml is also able to watch for changes in your component library folder and it re-copies the changes to your CRA app's node_modules. So, we could say wml is kind of alternative to npm link. In my initial attempts it worked fine for me so maybe this is something you can try.
Be careful: There is an issue in wml that causes the files on your project to be removed on the first time you set it up. It didn't happen to me but I saw others suffering the problem so if you are going to try wml, please ensure you have all the changes pushed to your source code version control system.
These are the steps you would need to follow to setup wml for your projects using the command line:
wml add <component-library-folder> <CRA-app-folder>/node_modules/<name-of-component-library>
wml start
Ideally I would prefer to solve this without having to use any external tool but if what styled-components maintainers suggest on their site is not valid, it could serve as a workaround.
I am just a new developer on React. I have just starting a new app using the create-react-app plugin. After that I have customised my own App Component, but this is using some third party components which makes the npm run test (react-scripts test --env=jsdom) fails with an error:
SyntaxError: Unexpected token import
This error only happens for an import inside a dependency at node_modules I am using. For example, it gives no error on
import React, { Component } from 'react';
Since I am using the create-react-app plugin I do not know what I need to change to make it pass. However, it seems to be something related with some babel configurations missing.
I think I should not need to install babel-jest dependency since that is embedded with create-react-app.
I have also tried to execute, without success:
npm run test -- --no-cache
The package.json file:
{
"name": "dhis2-hello-world",
"version": "0.1.0",
"private": true,
"dependencies": {
"d2": "^28.3.0",
"d2-manifest": "^1.0.0",
"d2-ui": "^28.0.8",
"d2-utilizr": "^0.2.15",
"loglevel": "^1.6.0",
"material-ui": "^0.20.0",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.0.17",
"rxjs": "^5.5.5"
},
"scripts": {
"prestart": "d2-manifest package.json ./public/manifest.webapp",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"manifest.webapp": {
"name": "DHIS2 App Template",
"description": "DHIS2 App Template",
"icons": {
"48": "icon.png"
},
"developer": {
"url": "",
"name": "DHIS2"
},
"activities": {
"dhis": {
"href": ".."
}
}
}
}
The error:
/node_modules/d2-ui/lib/app-header/HeaderBar.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import PropTypes from 'prop-types';
PropTypes is being imported on a component at d2-ui which is being import at App component like this:
import React, { Component } from 'react';
import HeaderBarComponent from 'd2-ui/lib/app-header/HeaderBar';
I was looking for a way to solve it without need to eject the project.
Could anyone give me some clues of how to solve that problem?
Many thanks!
I'm using create-react-app, and I am struggling to load images. I am following the instructions as specified here, but I keep seeing the following error:
Failed to compile.
Error in ./src/components/Home/imageIndex.ts
(1,24): error TS2307: Cannot find module './party.png'
Does anyone know why when I run yarn start my app continues to fail to compile?
I have a Home component and this is how I am importing the file:
import photo from './party.png';
The component is located in src/components/Home/index.tsx and the png file is located in src/components/Home/party.png.
here is my package.json:
{
"name": "eai-reactjs-typescript-redux-starter",
"description": "A ReactJS/TypeScript + Redux starter template with a detailed README describing how to use these technologies together and constructive code comments.",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.5",
"redux": "^3.7.0",
"redux-logger": "^3.0.6"
},
"devDependencies": {
"#types/enzyme": "^2.8.0",
"#types/jest": "^19.2.3",
"#types/node": "^7.0.18",
"#types/react": "^15.0.24",
"#types/react-dom": "^15.5.0",
"#types/react-redux": "^4.4.40",
"#types/redux-logger": "^3.0.0",
"enzyme": "^2.8.2",
"react-addons-test-utils": "^15.5.1",
"react-scripts-ts": "1.4.0",
"redux-devtools-extension": "^2.13.2"
},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
}
}
Are you sure you've got the correct path? Also when you import an image via css (as is done in the example you mentioned) you need to give a path relative to the public folder and not the src folder. I have run into this problem several times.
An example using import:
import Image from './img.png'
...
// react example
...
render() {
return (
<img src={Image}/> // notice the curly
...
and not
<img src="Image"/>
I had the same problem and was able to solve with a require statement.
const photo = require('./party.png');
and then in your component use that like:
render() {
return (
<img src={photo}/>
also see this post Displaying a static image using React, Typescript and Webpack
As #archae0pteryx proposed it is much better to separate pictures from the code, so the project public folder should be used instead of src.
Here is how it works with css:
copy 'img.bmp' into /public
inside .css file/class: background-image: url('/img.bmp');
You can simply use something like this:
render() {
// Note: this is an escape hatch and should be used sparingly!
// Normally we recommend using `import` for getting asset URLs
// as described in “Adding Images and Fonts” above this section.
return <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
}
Quoted directly from CRA docs
By default, Create-React-App uses url-loader for files with size 10000 bytes
that works fine in the development environment, but in production reduce error.
For a production environment, you should change the value for the limit of bytes in order to enforce webpack use file-loader instead.
If you have to eject your app modify webpack.config.prod.js file and change the limit of url-loader to 10 and will work as well
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10,
name: 'static/media/[name].[hash:8].[ext]',
},