I need to add {"plugins": [["import", { "libraryName": "antd-mobile" }]]} to .babelrc from a project generated by create-react-native-app to make ant-design-mobile work in react native.
I have started a new project with create-react-native-app.
Change the .babelrc to this:
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": [
"transform-react-jsx-source",
]
}
},
"plugins": [
["import", { "libraryName": "antd-mobile" }]
]
}
Class:
import { Button } from 'antd-mobile';
export class Screen extends React.Component<any,{}>{
render(){
return(
<View>
<Button>Something</Button>
</View>
)
}
}
However, I'm still getting this error on start:
Note: must use https://github.com/ant-design/babel-plugin-import .
For more information, please see https://github.com/ant-design/ant-design-mobile/issues/602
Can anyone point me to a solution?
You can take a look at official react-native app demo: https://github.com/ant-design/antd-mobile-samples/tree/master/react-native
Related
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:
How to fix the:
can't bind to 'nzType' since it isn't a known property of 'i'?
here's the code
index.component.html
<nz-header>
<i class="trigger" nz-icon [nzType]="isCollapsed ? 'menu-unfold' : 'menu-fold'" (click)="isCollapsed = !isCollapsed"></i>
</nz-header>
index.component.ts
isCollapsed = false;
index.module.ts
#NgModule({
declarations: [
ShellComponent
],
imports: [
CommonModule,
NzLayoutModule,
NzBreadCrumbModule,
NzDropDownModule,
]
})
You need to import NzIconModule.
Step 1: Dynamic importing via angular.json
angular.json
{
"assets": [
{
"glob": "**/*",
"input": "./node_modules/#ant-design/icons-angular/src/inline-svg/",
"output": "/assets/"
}
]
}
Step 2: Add Icons in Lazy-loaded Modules
index.module.ts
import { NzIconModule } from 'ng-zorro-antd/icon';
import {
MenuFoldOutline,
MenuUnfoldOutline
} from '#ant-design/icons-angular/icons';
import { IconDefinition } from '#ant-design/icons-angular';
const icons: IconDefinition[] = [MenuFoldOutline, MenuUnfoldOutline];
export class IndexModule {
...
imports: [
...
NzIconModule.forChild(icons)
]
}
Sample Solution on StackBlitz
Note:
How do I know a icon's corresponding module to import?
Capital camel-case type & theme, i.e. alibaba => AlibabaOutline.
Reference(s)
Add Icons in Lazy-loaded Modules
How do I know a icon's corresponding module to import?
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;
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
I'm trying to implement react-keydown which can be found here: https://github.com/glortho/react-keydown using the following code example:
import React from 'react';
import keydown, { Keys } from 'react-keydown';
class MethodDecoratorExample extends React.Component {
constructor( props ) {
super( props );
this.state = {
hello: false
};
}
#keydown( 'enter' )
toggleHello() {
this.setState( { hello: !this.state.hello } );
}
render() {
return (
<div>
<h3>Method Decorator Example</h3>
<div>Press the <strong>enter</strong> key to toggle hello.</div>
{ this.state.hello &&
<h1>Enter is key code {Keys.enter}!</h1>
}
<div>And click again outside box to see scoping.</div>
</div>
);
}
}
When I try this I get an unexpected token error on the #. I have no clue how to solve this.
What am I missing?
Thanks
Babel 6 no longer supports ES decorator syntax out of the box so you need to install the babel-plugin-transform-decorators-legacy plugin.
Install babel-plugin-transform-decorators-legacy
npm install --save-dev babel-plugin-transform-decorators-legacy
Add the plugin in your .babelrc
{
"plugins": [
"transform-decorators-legacy"
]
}
or
add the loader directly in your webpack.config.js
{
test: /\.jsx?$/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: ['transform-decorators-legacy' ]
}
}
I found the answer here: How do I get decorators working with babel & webpack?
Thanks to #cbll for mentioning decorators, because I did not know that that is the correct term. Helped me with searching for solutions