lostpebble / pullstate

Simple state stores using immer and React hooks - re-use parts of your state by pulling it anywhere you like!

Home Page:https://lostpebble.github.io/pullstate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

hohenp opened this issue · comments

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?

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?

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.

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?

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.

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?

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.

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 :)

Okay great, good luck! :)

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

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();