iconify/iconify-react

Unhandled Rejection (SyntaxError): Unexpected identifier

DorineLam opened this issue · 15 comments

Hi,
We try to install iconify-react but we always have an error message :
ErrorMessageIconify

We follow one by one the steps you give, It seems to come from the import because we try to select one by one the code lines.

Do you have some tips or informations to help us ?
Thank you very much !

Can you post code you used to import Iconify in your js file?

Hi !
Here the code of the component :

import React from "react"
import PropTypes from "prop-types"
import { withStyles } from "@material-ui/core/styles"
import Paper from "@material-ui/core/Paper"
import Card from "@material-ui/core/Card"
import CardActions from "@material-ui/core/CardActions"
import CardContent from "@material-ui/core/CardContent"
import Button from "@material-ui/core/Button"
import Typography from "@material-ui/core/Typography"
import Avatar from '@material-ui/core/Avatar';
import Chip from '@material-ui/core/Chip';

import { Icon, InlineIcon } from "@iconify/react";
import home from "@iconify/react/mdi-light/home";


const styles = theme => ({
    root: {
        ...theme.mixins.gutters(),
        paddingBottom: theme.spacing.unit * 2,
        paddingTop: theme.spacing.unit * 2,
        margin: `${theme.spacing.unit / 2}em auto`,
        width: "25em",
    },
    card: {
        minWidth: 275,
    },
    bullet: {
        display: "inline-block",
        margin: "0 2px",
        transform: "scale(0.8)",
    },
    titre: {
        fontSize: 11,
    },
    pos: {
        marginBottom: 12,
    },
})


function SimpleCard(props) {
    const { classes } = props
    const bull = <span className={classes.bullet}>•</span>

    return (
        
            <Card className={classes.card}>
                <CardContent>
                    <Icon icon={home} />
                    <Chip label= "label"/>
                    <Typography variant="h2" color="primary" gutterBottom>
                    350 €
                    </Typography>
                    
                </CardContent>
            </Card>
        
    )
}

SimpleCard.propTypes = {
    classes: PropTypes.object.isRequired,
}

export default withStyles(styles)(SimpleCard)

I don't see anything wrong with that code.

If you remove icon and iconify import from that code, it works correctly?

Are you getting any error messages or warnings during compilation?

What operating system are you using? Did you install packages with NPM or YARN?

Hi !
Without the import code, yes it's work.
No i don't think so. No error messages.
I'm working on OS X, and I install the package with NPM.

I tried a simple test and it works.
I made a new component called "testiconify" And I add this component into the card ! It works !

import React from "react"
  import { Icon, InlineIcon } from "@iconify/react";
  import home from "@iconify/react/mdi-light/home";

  export default props =>

  <paper>
  	<Icon icon={home} />
  </paper>

One possibility is your webpack.config.js ignores everything in node_modules. It needs to parse all files in node_modules/@iconify/react/ as if they were project's files. Can you check your config?

If that won't work, can you send me files to cyberalien@gmail.com, so I could debug it?

Hi @cyberalien,

As we're working with NextJS, we haven't any explicit webpack config :

const withSass = require("@zeit/next-sass")

module.exports = withSass({
    exportPathMap() {
        return {
            "/": { page: "/" },
        }
    },
    distDir: "build",
})

Could you provide us with an example of webpack config to see if we can inject it in next.config.js?

Code is available at https://github.com/betagouv/leximpact-client

Then its more complex. If you had clear webpack config, I might have noticed some issues there, but debugging entire third party library is not feasible.

Basic component with icon works, so it doesn't look like Iconify code is causing issues. Code looks fine, error message is useless, lack of warnings during compilation is strange. Its a weird issue.

Maybe something is wrong with export? Unlike usual components, your export is result of function. Try debugging what it actually exports, like assigning export to variable, dumping that variable before export then exporting it.

I got it ! Basically TS files were not being transpiled.

If it can be of any use for other users:

// next.config.js
const withPlugins = require("next-compose-plugins")
const withTranspileModules = require("next-transpile-modules")
const withTypescript = require("@zeit/next-typescript")
const withSass = require("@zeit/next-sass")

const pluginsConfig = [
    [withTranspileModules, { transpileModules: ["@iconify/react"] }],
    [withTypescript],
    [withSass],
]

const nextConfig = {
    exportPathMap() {
        return {
            "/": { page: "/" },
        }
    },
    distDir: "build",
}

module.exports = withPlugins(pluginsConfig, nextConfig)

Thanks, that's helpful. Anything I can do in this repository to make NextJS automatically transpile this repository?

Hi @cyberalien,

unfortunately you cannot make NextJS automagically transpile your repo.
I'm sorry to tell you that the problem does not only concern NextJS but also happens with create-react-app when not ejected.
Both are set to not transpile any code inside the node_modules folder.

I you would consider serving a transpiled version of this repository alongside the current code it would be much appreciated. Maybe under a subfolder '/es5' or something.

Thanks for posting this.

I haven't encountered that issue because I'm using custom build scripts that transpile everything, but its obviously an issue. So after testing, I've decided to make following changes:

  • Both original and transpiled version will be included. By default package will point to transpiled version.
  • Original will be moved to "src" directory, so to include jsx file code will be import { Icon } from '@iconify/react/src/index';

Big issue is icons. Currently they are also not transpiled, so they'll have to be transpiled too. Currently there are about 40k files, one for each icon. After transpiling number of files would double. So I'm considering placing them in one file instead of many files and using tree shaking to reduce file size. However I have never used that. Is tree shaking actually viable? Anyone has experience with it?

Unfortunately tree shaking doesn't work for third party packages when using webpack, so its not an option. However I have found a better solution. Problem is it will break backwards compatibility for including icons, so few modifications will have to be done to existing components.

First change: icons are now separate from this package.

Icons are moved to separate packages, 1 package per collection. I'm currently testing script that automates maintaining of those packages, so they will always contain latest icons.

For testing I've published MDI and Unicons on NPM:
https://www.npmjs.com/package/@iconify/icons-mdi
https://www.npmjs.com/package/@iconify/icons-uil

Those packages include icons in original and transpiled form. By default transpiled will be included, so it should work fine with NextJS. I've tested them with NextJS that was throwing errors when files weren't transpiled. NPM packages include automatically generated readme.md that has usage instructions.

Other packages will have similar name: @iconify/icons-{prefix} where {prefix} is icons collection name. So instead of including @iconify/react/mdi/home new location of file is @iconify/icons-mdi/home. Original untranspiled files are also available, they are in "src" directory of each package: @iconify/icons-mdi/src/home

Second change: this package will not have any dependencies and will include fully transpiled React component by default.

Here are contents of updated icon.js if you want to test it: https://gist.github.com/cyberalien/32ad3755fb38a4789a832197cc570aa8
If you want to test it, make sure you test it with icon sets I've posted above, not old icon sets. You can delete build.js and all sub-directories of this package.

I'll do more testing to make sure everything works and will publish this in few days.

I think this change is for better. First it will make fewer files on file system, so for example of you want to use only icons from material design icons, you can install only @iconify/icons-mdi, not all 40k icons. Second, it will make maintenance easier because with new system packages are automatically updated, so simple npm update will update all icons. Then icon packages can be re-used for things like Angular icon component because they are universal - they include only icon data and do not have any dependencies.

Everything should be fixed in version 1.1.0 beta 2 that I have published few minutes ago.

Please test it and post if its working correctly for you.

Hey @cyberalien!
Thank you so much for your quick work!
This is definitely a breaking change but for me it's a very welcome one. I actually prefer the way you now serve every icon set in its own npm package.

I was able to use the new react and icons-mdi packages without any changes except for the import paths and can confirm that my transpilation errors are gone.
I used it with a default create-react-app, a storybook instance and in typescript components that I transpiled to an internally consumed library. Everything worked without problems 👍

Version 1.1.0 has been released. It fixes this issue.