gatsby: "gatsby build" breaks when dependencies use es6 code (which Uglify doesn't support)

Description

After upgrading Gatsby to 1.9.167, I’m getting the following error when I try to run gatsby build:

error Generating JavaScript bundles failed

  Error: component---src-templates-post-jsx-dbdaebf346a9292b96a8.js from UglifyJs
  SyntaxError: Unexpected token: name (isLastCharLower) [./~/camelcase/index.js:4,0]

The line mentioned in the error contains keyword let. Looks like (at least) dependencies are no longer compiled to ES5 and UglifyJS version used by Gatsby doesn’t understand ES6+, so it throws an error.

The same app works fine with 1.9.166. It’s most likely caused by some changes introduced in https://github.com/gatsbyjs/gatsby/pull/3369, other changes introduced in this version don’t look suspicious.

To replicate this issue create a new Gatsby project, run yarn add camelcase, import and call camelcase in any component and run gatsby build.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 12
  • Comments: 47 (32 by maintainers)

Commits related to this issue

Most upvoted comments

After sleeping on it, I’ve decided that @KyleAMathews plugin name makes much more sense, so have moved the plugin to https://www.npmjs.com/package/gatsby-plugin-compile-es6-packages

I hope you find it useful 😄

Also closing this issue now, as using this plugin and configuring it with the npm packages that have es6 code in them will allow them to be compiled by Babel.

Working on fixes for this in Gatsby v2. We’ll be compiling all code in node_modules + upgrading to the latest version of uglify.

@KyleAMathews I’ve created a demo repo here, based on gatsby-starter-default.

  • Commit 1, initial commit (fresh gatsby-starter-default).
  • Commit 2, demonstrate successful build with ES6 dependency on 1.9.166.
  • Commit 3, demonstrate failing build with 1.9.167.
  • Commit 4, demonstrate failing build on latest release.

If anyone else comes across this issue when they are using Gatsby V2, the above examples will not work due to Gatsby API changes, but the below example did (at least for me).

exports.onCreateWebpackConfig = ({ loaders, actions }) => {
  actions.setWebpackConfig({
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: modulePath =>
            /node_modules/.test(modulePath) &&
            // whitelist specific es6 module
            !/node_modules\/@papertrailio\/js-core/.test(modulePath),
          use: loaders.js(),
        },
      ],
    },
  })
}

In the above example, the @papertrailio/js-core module included Flow definitions, so adding the above code to gatsby-node.js, and adding the gatsby-plugin-flow plugin to gatsby-config.js worked perfectly.

I had same issue upgrading to to a module dependency that uses let and const. The solution that finally worked for me was whitelisting specific modules in the babel loader via the weback config. I used the example in the docs as a starting point, and ended up with something like this in gatsby-node.js:


exports.modifyWebpackConfig = ({ config, stage }) => {
  // https://www.gatsbyjs.org/docs/add-custom-webpack-config/#modifying-the-babel-loader
  const program = {
    directory: __dirname,
    browserslist: ["> 1%", "last 2 versions", "IE >= 9"]
  };

  return generateBabelConfig(program, stage).then(babelConfig => {
    config.removeLoader("js").loader("js", {
      test: /\.jsx?$/,
      exclude: modulePath => {
        return (
          /node_modules/.test(modulePath) &&
          // whitelist specific es6 modules
          !/node_modules\/(react-docgen|ast-types|recast)/.test(modulePath)
        );
      },
      loader: "babel",
      query: babelConfig
    });
  });
}

@natesjacobs I ran into the same issue and had to use query-string@5.

@m-allanson thank you so much for your help!

I can’t seem to get a build to finish. v1.9.166 doesn’t have the UglifyJS issue, but it does have the duplicate GraphQL issue like in #4154. I attempted to upgrade Gatsby to 1.9.223 and modify the Webpack config to transpile node_modules to ES5 but ran into a bunch of issues along the way.

Does anyone have a workaround? I’m completely stuck.

I’m working in a ‘monorepo’ and trying to figure out if I need @robwalkerco’s plugin. The app is structured like:

monorepo-app/
  |- packages/
     | - common/
     | - gatsby-app-1/
     | - gatsby-app-2/

…where common includes shared components, libs, etc.

Should I be adding common as a package to this plugin if I’m using es6, or is there something more to it? gatsby build doesn’t error with the UglifyJS message mentioned here.

@KyleAMathews Ah, thats a good name.

~~I published it as gatsby-plugin-es6-webpack-modules a few hours ago and the Gatsby Plugins directory has picked it up already at https://www.gatsbyjs.org/packages/gatsby-plugin-es6-webpack-modules/~~

Could try to get the name changed though.

If anyone else finds this issue, then the plugin will help you to customise the webpack config to compile es6 modules in node_modules.

Open to PR’s to improve the readme etc

@robwalkerco awesome! How about maybe gatsby-plugin-compile-es6-packages?

@KyleAMathews I will have a crack at a plugin for Gatsby V2 using something like my example above (https://github.com/gatsbyjs/gatsby/issues/3780#issuecomment-419862716)

Perhaps I should call it gatsby-plugin-es6-webpack-package?

Hey @chadwatson 👋 Can I get a bit more info about your setup - if you create a new issue and fill out the issue template that’ll be a good place to start. And if you’re able to share your code that’s even better!

Why isn’t using an es6-compatible version of Uglify an option?

There are 2 issues. When Gatsby switches to babel-preset-env it will need to use ES6-compatible minifier (most likely UglifyJS2), because user’s code can end up with ES6+ syntax as well. However, if I configure babel-preset-env to support IE9 or Safari 9, I’d expect all code to work in these browsers, including third-party code that might use ES6+ syntax, not just the code I wrote.

I’ll see what I can do, but it might take a little while. In the meantime, I verified that the break is between builds 1.9.166 and 1.9.167.

In my case it’s caused by camelcase package (which is a dependency of a markdown to html library I’m using), but there are others available only in ES6 as well. This error has already been reported https://github.com/sindresorhus/camelcase/issues/21 and it won’t be “fixed” - more info about that https://github.com/sindresorhus/ama/issues/446, which makes perfect sense from the maintainer point of view.

However, this means that all dependencies should also be compiled by Babel to ES5, because they might be written in ES6, so even if Gatsby started using UglifyJS2, which does support ES6 syntax, it would break in older browsers that don’t support ES6.