Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spread operator in dist/index.es.js causes "Unexpected token" #95

Closed
hohenp opened this issue Feb 1, 2021 · 9 comments
Closed

Spread operator in dist/index.es.js causes "Unexpected token" #95

hohenp opened this issue Feb 1, 2021 · 9 comments
Labels
build-config Issues related to end-user build configuration

Comments

@hohenp
Copy link

hohenp commented Feb 1, 2021

I am using pullstate in a separate project.
When I build the project that goes fine.
When I then include that project into another project and build that, I get "Unexpected token" for all the spread operators.
When I check the build .js File the error comes from the spread operator

image

Is it possible to tranform the spread operator, when you build the pullstate?

@lostpebble
Copy link
Owner

lostpebble commented Feb 1, 2021

Hi @hohenp ,

I have a feeling both of your issues you filed just now are related to your build process. Pullstate uses somewhat modern JS, but if you need older JS in your final build- you need to transpile that to the older versions (ES5 and the like).

It provides two entry files for this in package.json:

  "main": "dist/index.js",
  "module": "dist/index.es.js"

It appears, from this and your other issue, that your build is making use of the module entry- so it should also surely be fine with the standard ES6 syntax that the code uses as well, as modules are already quite modern.

The spread operator, and excluding e are pretty standard JavaScript now. So, its up to the end user to put in backwards compatibility if they are still building for older systems.

I think you might just be missing a final build step. Could you share a little more about how you are building your code? And where is the error happening, during the second build, or in the client?

@lostpebble lostpebble added the build-config Issues related to end-user build configuration label Feb 1, 2021
@lostpebble
Copy link
Owner

Is it possible to tranform the spread operator, when you build the pullstate?

Just to follow up on this, modern JavaScript has its advantages where things are more efficiently executed with the newer syntaxes in the modern engine. Its easy to transpile to an older JS version, but its not that easy to do it the other way around. Transpiling to an older JS version would cause a lot of other code optimizations to become bloated to accommodate the older syntax as well- which would in turn bloat the library size for the majority of people who don't need it.

@hohenp
Copy link
Author

hohenp commented Feb 1, 2021

Hi @lostpebble , thanks for your answer. The error happens at the second build. The first build runs well, and then I have my compiled .js file with "your" spread operators in. Then I "require" the .js file in another project, and when I build that one, I get the issue. So, can it be, that an old webpack version in the 2nd project is causing that issue? I cant update the versions, so is there a chance for me to have a build step that compiles your spread operators to an older runtime?

@lostpebble
Copy link
Owner

I think you need to then look at the first build, and what target you are setting for the output there. Is there any further information you can give me about it, like which tooling are you using? Webpack, babel etc.?

Generally if you're using Webpack with babel-loader - and you're transpiling for ES5 or older - you need to ensure that any ES6 libraries are being transpiled as well (pullstate in this case). Take a closer look here- its a common occurrence that people run into and unfortunately doesn't have great solutions for yet.

I don't know what your build process looks like in the first step though- but the gist of it, is that you need to make sure that initial build step is transpiling pullstate along with your regular code.

@hohenp
Copy link
Author

hohenp commented Feb 1, 2021

Thanks a lot! Well I use webpack und typescript.
One of my webpack rules looks like...
image
and within the tsconfig.json I have set a target to ES5.

So I think I have to modify my webpack rules, so that pullstate is included in the transpiling, right?

@lostpebble
Copy link
Owner

Ah okay cool. Well I think what you might need to add then, is a babel-loader rule with include: /pullstate/ as the config, something like:

{
      test: /\.m?js$/,
      include: /pullstate/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }

You may have to configure the preset a bit more- but it looks like @babel/preset-env transpiles to ES5 automatically already.

I'm not sure if ts-loader would do the same- you can try and include it. But the test there will ignore the .js extension of it, since its already been converted from TypeScript. Though there's a chance ts-loader could include transpiling direct .js as well.

@hohenp
Copy link
Author

hohenp commented Feb 1, 2021

ok, thanks a lot for your help! Now I know where to look at.
I close both tickets, but keep you updated about the solution. As soon as I found one :)

@hohenp hohenp closed this as completed Feb 1, 2021
@lostpebble
Copy link
Owner

Okay great, good luck! :)

(JS config has always been my least favourite thing about dev)

@hohenp
Copy link
Author

hohenp commented Mar 9, 2021

Like to give an update on that. Your way to use babel to transpale a specific mode-module was the right glue. I had to go a bit deeper and find the other modules (used by pullstate) and handle them by babel as well.

Those are: pullstate, fast-deep-equal and immer

I ended up with following webpack rule:

{
      test: /\.m?js$/,
      include: [/pullstate/, /fast-deep-equal/, /immer/],
      use: {
           loader: 'babel-loader',
           options: {
                presets: [
                     [
                          '@babel/preset-env',
                          {
                               // useBuiltIns: 'entry',
                               // corejs: 3, // or 2,
                               targets: {
                                    ie: '11', // or whatever target to choose .
                               },
                          },
                     ],
                ],
           },
      },
 },

Within the root component you then have to enable ES5 for immer.
There I am using some more polyfills...

import 'regenerator-runtime/runtime';
import 'core-js/stable'; // if polyfills are also needed
import '@pnp/polyfill-ie11';
import 'whatwg-fetch';

import { enableES5 } from 'immer';
enableES5();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build-config Issues related to end-user build configuration
Projects
None yet
Development

No branches or pull requests

2 participants