ReferenceError: ResizeObserver is not defined:Gatsby with nivo - javascript

I use #nivo/pie with "gatsby": "^3.13.0".
But I got an error when I gatsby build.
WebpackError: ReferenceError: ResizeObserver is not defined
Nivo's version is "#nivo/pie": "^0.79.1".
I have no idea to solve it. I would be appreciate if you could give me some advice.
And here is the React code using nivo's pie chart.
PieChart.tsx
import React from 'react'
import { ResponsivePie } from '#nivo/pie'
const PieChart: React.FC = ({ data }) => {
return (
<>
<div>
<ResponsivePie
data={data}
margin={{ top: 30, right: 80, bottom: 70, left: 80 }}
borderColor={{
from: 'color',
modifiers: [
[
'darker',
0.2,
],
],
}}
arcLabelsTextColor={{
from: 'color',
modifiers: [
[
'darker',
2,
],
],
}}
fill={[
{
match: {
id: 'ruby',
},
id: 'dots',
},
]}
legends={[
{
anchor: 'bottom-right',
direction: 'column',
justify: false,
translateX: 0,
translateY: -1,
},
]}
/>
</div>
</>
)
}
export default PieChart
===================================================================
I could fix it after I updated gatsby-node.js. But I got another error WebpackError: Minified React error #130;. And I could fix it by this final code. There's no build error.
PieChart.tsx
import React from 'react'
import { ResponsivePie } from '#nivo/pie'
const PieChart: React.FC = ({ data }) => {
return (
<>
{typeof window !== 'undefined' && ResponsivePie &&
<ResponsivePie
data={data}
...
/>}
</>
)
}
export default PieChart
Thank you.

Try using a null loader on Gatsby's SSR. In your gatsby-node.js:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /#nivo\/pie/,
use: loaders.null(),
},
],
},
})
}
}
Normally this kind of issue (gatsby develop OK vs gatsby build KO) are related to webpack's bundling on the server (Server-Side Rendering), especially when dealing with third-party dependencies that interact with the window or other global objects (such as document) like chart modules do. This happens because when you run gatsby build your code is interpreted by the Node server, where there's no window available yet. On the other hand, gatsby develop is interpreted by the browser, where there is.
With this approach, you are adding a dummy loader (null) to webpacks to load the dependency on the client-side, where the window is available.
Keep in mind that test: /#nivo\/pie/ is a regular expression (that's why is between slashes, /) that tests the node_modules folder so ensure that /#nivo\/pie/ is a valid path.

Related

Can't load Expo Vector Icons in Nextjs

I have tried a lot of different ways to do this, with absolutely zero luck, over multiple days.
I am trying to use Solito Nativebase Universal Typescript repo to do this:
https://github.com/GeekyAnts/nativebase-templates/tree/master/solito-universal-app-template-nativebase-typescript
I have read, and tried everything on this page at least a dozen times:
https://github.com/GeekyAnts/nativebase-templates/issues/43
My current next.config.js file looks like this:
/** #type {import('next').NextConfig} */
const { withNativebase } = require('#native-base/next-adapter')
const withImages = require('next-images')
const { withExpo } = require('#expo/next-adapter')
const withFonts = require('next-fonts')
module.exports = withNativebase({
dependencies: [
'#expo/next-adapter',
'next-images',
'react-native-vector-icons',
'react-native-vector-icons-for-web',
'solito',
'app',
],
plugins: [
[withFonts, { projectRoot: __dirname }],
withImages,
[withExpo, { projectRoot: __dirname }],
],
nextConfig: {
images: {
disableStaticImages: true,
},
projectRoot: __dirname,
reactStrictMode: true,
webpack5: true,
webpack: (config, options) => {
config.resolve.alias = {
...(config.resolve.alias || {}),
'react-native$': 'react-native-web',
'#expo/vector-icons': 'react-native-vector-icons',
}
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
]
return config
},
},
})
I have also tried using #native-base/icons, again, no luck.
My end use case is this:
export const Cart = (props: IIconStyles) => {
return (
<Icon
as={FontAwesome5}
name="shopping-cart"
size={props.size ? props.size : 6}
color="gray.200"
/>
)
Theoretically it SHOULD show a shopping cart, but instead, this is what I see:
So clearly there's some font issue or other issue that is preventing it from loading in the actual SVG.
I can't figure out what this is - I've tried rewriting my _document.tsx file like this:
https://docs.nativebase.io/nb-icons
I've tried adding this to my next.config.js:
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
When I try to do something like this:
import fontsCSS from '#native-base/icons/FontsCSS';
in my _document.tsx file, I get the following error:
Module not found: Can't resolve '#native-base/icons/lib/FontsCSS'
Despite the fact that I've got #native-base/icons installed in my package.json, as well as having it in my Babel file per the instruction link above.
How do I get vector icons to work in Next?
Note, this is specifically Next/Expo/React Native
You can read more about setup of next-adapter-icons here.
I got it working with following approach,
next.config.js
const { withNativebase } = require("#native-base/next-adapter");
const path = require("path");
module.exports = withNativebase({
dependencies: ["#native-base/icons", "react-native-web-linear-gradient"],
nextConfig: {
webpack: (config, options) => {
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
config.resolve.alias = {
...(config.resolve.alias || {}),
"react-native$": "react-native-web",
"react-native-linear-gradient": "react-native-web-linear-gradient",
"#expo/vector-icons": "react-native-vector-icons",
};
config.resolve.extensions = [
".web.js",
".web.ts",
".web.tsx",
...config.resolve.extensions,
];
return config;
},
},
});
pages/_document.js
import React from 'react';
import { DocumentContext, DocumentInitialProps } from 'next/document';
import { default as NativebaseDocument } from '#native-base/next-adapter/document'
// Icon Font Library Imports
import MaterialIconsFont from '#native-base/icons/FontsCSS/MaterialIconsFontFaceCSS';
import EntypoFontFaceCSS from '#native-base/icons/FontsCSS/EntypoFontFaceCSS';
const fontsCSS = `${MaterialIconsFont} ${EntypoFontFaceCSS}`;
export default class Document extends NativebaseDocument {
static async getInitialProps(ctx) {
const props = await super.getInitialProps(ctx);
const styles = [
<style key={'fontsCSS'} dangerouslySetInnerHTML={{ __html: fontsCSS }} />,
...props.styles,
]
return { ...props, styles: React.Children.toArray(styles) }
}
}
pages/index.tsx
import React from "react";
import { Box, Icon } from "native-base";
import Entypo from "#expo/vector-icons/Entypo";
export default function App() {
return (
<Box>
<Icon
as={Entypo}
name="user"
color="coolGray.800"
_dark={{
color: "warmGray.50",
}}
/>
</Box>
);
}
Using import like this:
import MaterialIcons from '#expo/vector-icons/MaterialIcons'
in place of:
import { MaterialIcons } from '#expo/vector-icons'
worked for me. I think this is because of the way babel/webpack handles imports in the template. I followed the steps here to setup the icons.
Here's what that looks like on web:

Import/Export error: The requested module does not provide an export named 'pageFlip'

I recently switched over to the new Vite compiler for Laravel. I noticed that it somehow did not accept my window object anymore. No problem I thought, I'll just use imports/exports. However, I just keep getting the same error:
The requested module '../../../../../js/plugins/pageflip.js' does not provide an export named 'pageFlip'
I have searched all over the internet, but it keeps telling me not to confuse named exports/imports with default ones. However, I don't see anything wrong with my code. Could someone please help me with this?
show.blade.php
<div>
HTML HERE
</div>
#push('scripts')
<script type="module">
import {pageFlip} from "../../../../../js/plugins/pageflip.js";
#isset(condition here)
pageFlip.turnToPage({{ $tale->taleUser->progress }})
#endisset
#can(condition here)
pageFlip.on('flip', (e) => {
document.getElementById('pageProgress').value = pageFlip.getCurrentPageIndex();
document.getElementById('pageCount').innerHTML = pageFlip.getCurrentPageIndex();
});
#endcan
function turnPage(bool) {
if (bool) {
return pageFlip.turnToNextPage();
}
return pageFlip.turnToPrevPage();
}
</script>
#endpush
My script file:
import {PageFlip} from 'page-flip'
const pageFlip = new PageFlip(document.getElementById('book'),
{
width: 400,
height: 600,
size: ('stretch'),
minWidth: 200,
minHeight: 400,
maxWidth: 1000,
maxHeight: 1000,
autoSize: true,
disableFlipByClick: true,
showCover: false
}
);
pageFlip.loadFromHTML(document.querySelectorAll('.tale-page'));
export { pageFlip }
The vite config file:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
'resources/js/plugins/pageflip.js',
]),
],
});
Judging by the error, I am a bit confused. I really am providing an export named 'pageFlip', right? Or am I possibly missing some vite configuration?
I am using the StPageFlip package provided by Nodlik.
p should be capital in PageFlip in show.blade.php file. So replace import {pageFlip} from "../../../../../js/plugins/pageflip.js"; with import {PageFlip} from "../../../../../js/plugins/pageflip.js";

declaration merging for react-native-elements theme

I am using react-native-elements in my react-native application.
My app is wrapped with the ThemeProvider to pass the theme down to all components.
<SafeAreaProvider>
<ThemeProvider theme={Theme}>
<Loader visible={loader.loading} text={loader.message} absolute={true} />
<RootNavigation />
</ThemeProvider>
</SafeAreaProvider>
In the theme file i define the values i want to use across the app.
const theme = {
colors: {
primary: '#6A69E2',
primaryDark: '#4747c2',
primaryLight: 'rgba(106, 105, 226, 0.35)',
gray: {
dark: '#242424',
default: '#666',
medium: '#999',
light: '#ccc',
lightest: '#e7e7e7',
},
},
text: {
size: {
small: 12,
default: 16,
large: 18,
h1: 26,
h2: 22,
h3: 20,
},
},
Text: {
style: {
fontSize: 16,
color: '#242424',
fontFamily: 'Roboto',
},
},
Button: {
style: {
borderRadius: 50,
},
disabledStyle: {
backgroundColor: 'rgba(106, 105, 226, 0.35)',
},
},
};
export default theme;
For the values the original theme of react-native-elements providing this is working. For example i can access the colors by using
const theme = useTheme()
theme.colors.primary
But when i want to add some new properties like primaryDark i'll get an linter error.
Object literal may only specify known properties, and 'primaryDark' does not exist in type 'RecursivePartial<Colors>'.ts(2322)
In the doc of react-native-elements is a part about declaration merging, but i don't understand how i can archive this
https://reactnativeelements.com/docs/customization/#typescript-definitions-extending-the-default-theme.
Somebody could help me with this?
Well, declaration merging still works. This seems like a bug on the lib's part.
Their doc says you can augment the Color interface in module 'react-native-elements'. But currently (as of 2021-04-18, with v3.3.2) that interface is actually hidden inside module 'react-native-elements/dist/config/colors', not directly exposed at the top level, weird.
I suggest you file an issue to their repo. Never mind, someone already filed the issue.
Tested on my machine, following solution works.
import React from 'react'
import { useTheme, ThemeProvider } from 'react-native-elements'
declare module 'react-native-elements/dist/config/colors' {
export interface Colors {
primaryDark: string
primaryLight: string
}
}
const ChildComp = () => {
const theme = useTheme()
theme.theme.colors.primaryDark // <-- No more error 🎉
return <div>foobar</div>
}
Reply to OP's comment. You can augment interface however you like, as long as the augmented key doesn't exist before. For example add foobar key to FullTheme.
declare module 'react-native-elements' {
export interface FullTheme {
foobar: string
}
}

React-Image-Annotate - SyntaxError: Cannot use import statement outside a module

I'm trying to use react-image-annotate but it's giving me this issue when I first try to set it up.
And here's how I'm using it:
import React from 'react'
import ReactImageAnnotate from 'react-image-annotate'
function ImageAnnotator() {
return (
<ReactImageAnnotate
selectedImage="https://images.unsplash.com/photo-1561518776-e76a5e48f731?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
// taskDescription="# Draw region around each face\n\nInclude chin and hair."
// images={[
// { src: 'https://example.com/image1.png', name: 'Image 1' },
// ]}
// regionClsList={['Man Face', 'Woman Face']}
/>
)
}
export default ImageAnnotator
I'm using Next.js if that matters
UPDATE 1
I tried using this babel plugin as suggested by Alejandro Vales. It gives the same error as before. Here's the babel key in my package.json:
"babel": {
"presets": [
"next/babel"
],
"plugins": [
[
"#babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"#babel/plugin-transform-modules-commonjs",
{
"allowTopLevelThis": true
}
]
]
}
I would say that the issue relies in the library itself by what they replied in here (similar bug) https://github.com/UniversalDataTool/react-image-annotate/issues/90#issuecomment-683221311
Indeed one way to fix it I would say is adding babel to the project so you can transform the imports in your project to require automatically without having to change the code on your whole project.
This is the babel package you are looking for https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs
Another reason for this could be an outdated version of your package, as some people report to have this fixed after using a newer version of Create React App (https://github.com/UniversalDataTool/react-image-annotate/issues/37#issuecomment-607372287)
Another fix you could do (a little crazier depending on your resources) is forking the library, creating a CJS version of the lib, and then pushing that to the library, so you and anybody else can use that in the future.
I got a tricky solution!
Problem is that react-image-annotate can only be imported in client-side(SSR got error for import keyword)
So, let react-image-annotate in Nextjs be imported only in client side
(https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr)
in Next Page that needs this component, You can make component like this
import dynamic from "next/dynamic";
const DynamicComponentWithNoSSR = dynamic(() => import("src/components/Upload/Annotation"), { ssr: false });
import { NextPage } from "next";
const Page: NextPage = () => {
return (
<>
<DynamicComponentWithNoSSR />
</>
);
};
export default Page;
Make component like this
//#ts-ignore
import ReactImageAnnotate from "react-image-annotate";
import React from "react";
const Annotation = () => {
return (
<ReactImageAnnotate
labelImages
regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
regionTagList={["tag1", "tag2", "tag3"]}
images={[
{
src: "https://placekitten.com/408/287",
name: "Image 1",
regions: [],
},
]}
/>
);
};
export default Annotation;

Using styled-components results in `cannot read withConfig of undefined`

When attempting to transpile the Spacing.js file, it results in an undefined import even when styled-components was seemingly being imported and used (in the same way) successfully in other files. Even when removing the styled-components babel plugin, a similar error occurs.
.babelrc
{
"presets": [["es2015", { "modules": false }], "react-native"],
"plugins": [
["styled-components", { "displayName": true }],
"react-hot-loader/babel",
"react-native-web",
"transform-decorators-legacy",
"transform-class-properties"
],
"env": {
"production": {
"plugins": [
"transform-react-inline-elements",
"transform-react-constant-elements"
]
}
}
}
Spacing.js - Code before transpilation
import React, { Component, Node } from "React";
import styled from "styled-components";
type Props = {
size: string,
color: string,
fullWidth?: boolean
};
class SpacingComponent extends Component<Props> {
render(): Node {
const { size, color, fullWidth = false } = this.props;
return <Spacing size={size} color={color} fullWidth={fullWidth} />;
}
}
const Spacing = styled.View`
height: ${props => props.size}px;
background-color: ${props => props.color || "transparent"};
width: ${props => {
return props.fullwidth ? "100%" : props.size + "px";
}};
`;
export default SpacingComponent;
Generated code for importing and resolving styled-components
Generated code for using the styled-components library (v3.2.5)
The resulting error
Another example can be seen when removing the styled-components babel plugin from the babelrc, thus the withConfig is not added.
Generated error with no styled-components babel plugin
Generated code making this error
Is babel or webpack adding .default when it doesn't need to, if so, how could I investigate why?
try doing styled(View) instead of styled.View
Not sure if this is going to be helpful to anyone but for me the same error was triggered like this style.something and fixed using an html element eg style.span

Categories