mrcrowl / vuex-typex

Typescript builder for strongly-typed access to Vuex Store modules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I get the following error: Vuex handler functions must not be anonymous

larshg opened this issue · comments

Hi all

I have a Store module like this:

import { IRobotState } from '@types'
import {storeBuilder} from "./StoreBuilder"
import axios from 'axios'

//State
const state: IRobotState = {
    serieID : "",
    productionCount: 0,
    rapidValue: 0
}

const RobotStateMod = storeBuilder.module<IRobotState>("RobotModule", state);
const stateGetter = RobotStateMod.state();

namespace Getters {

    export const getters = {
        get getRobotSerieID() { return state.serieID },
        get getProductionCount() { return state.productionCount; }
    }
}

namespace Mutations {
    function setRobotSerieID(state:IRobotState, robotSerieId: String)
    {
        state.serieID = robotSerieId;
    }

    export const mutations = {
        commitSetRobotSerieID: RobotStateMod.commit(setRobotSerieID)
    }
}

namespace Actions {

     async function getRobotSerieID()
    {

    }

    export const actions = {
        dispatchGetRobotSerieID: RobotStateMod.dispatch(getRobotSerieID)
    }
}

// Module
const RobotStateModule = {
    get state() { return stateGetter()},
    getters: Getters.getters,
    mutations: Mutations.mutations,
    actions: Actions.actions
  }
  
  
  export default RobotStateModule;

but it gives the following error when I try to load the page after production build - in dev build it works fine:

Uncaught Error: Vuex handler functions must not be anonymous. Possible causes: fat-arrow functions, uglify. To fix, pass a unique name as a second parameter after your callback.

In the stack trace it marks javascript commitSetRobotSerieID: RobotStateMod.commit(setRobotSerieID) as the one of the possible causes...

Is there someone who has an idea?

@victorgarciaesgi I have tried to follow your Moving-Mate example - so maybe you have experienced it?

Hi @larshg, yeah I came accross this issue too!

There is two possibilities here for this error appearing

  • Like the error said, if you uglify the code, make sur to have keep_fnamesset in your config.
uglifyOptions: {
   mangle: { keep_fnames: true },
   compress: { keep_fnames: true},
}
  • Or by looking at your code, your getters are not well writen.

Try to write it like that!

namespace Getters {
  const isAdmin = b.read(function isAdmin(state) : boolean {
    return state.userInfos.roles.includes("ROLE_ADMIN");
  })

  export const getters = {
    get isAdmin() {return isAdmin();},
  }
}

It's not beautiful and practical but for me it worked! The maintainer of vuex-typex is inactive for 9 months now :(

Thanks for the response

However, I'm not using uglify as far as can figure (nothing found when searching for it) - and the new implementation of the getters didn't help much.

I tried to remove all the getters, but now its the mutations.

The "compiled" output is like this:

const RobotStateMod = storeBuilder.module("RobotModule", state);
const stateGetter = RobotStateMod.state();
var Mutations;
(function (Mutations) {
    function setRobotSerieID(state, robotSerieId) {
        state.serieID = robotSerieId;
    }
    Mutations.mutations = {
        commitSetRobotSerieID: RobotStateMod.commit(setRobotSerieID)
    };
})(Mutations || (Mutations = {}));

so is the

var Mutations;
(function (Mutations) {

the offending declartion - since the the function has no name afterwards?

@larshg Can you link me to your repo? I can take a look at your problem. I remember banging my head with this error but this were the two issues i came up with if I remember correctly!

@larshg My compiled files look exactly the same as you, so maybe it's just cache or something like that

https://github.com/larshg/RobotWeb here is the repo.

Thanks for looking at it!

@larshg I just started your app with no errors
image

@larshg Delete your node_modules, clear cache with npm cache clean --force, reinstall them and retry npm run dev

When it production mode? I'm in progress of clearing etc.

Dev mode works fine - its when I try to run production on a webserver it fails...

If production mode fails it's definitely the uglifying part

But I just can't figure out where it uglifies it then? I also tried to remove the minimizing step, with no luck :(

optimization: {
    minimize: true,
  },

If I add this to the production build it does indeed work. But there seems to be problems with uglify and webpack 4.

thanks for helping out, though :)

Yeah vuex-typex has few issues so I advise to not use it in production!

To avoid problems with uglify, you may have to do this:

namespace Getters {
  const isAdmin = b.read(function isAdmin(state) : boolean {
    return state.userInfos.roles.includes("ROLE_ADMIN");
  }, "isAdmin")

  export const getters = {
    get isAdmin() {return isAdmin();},
  }
}

I ran into the same error in production mode. Being rather new to programming, I have the following questions:

  1. Where would I add the following part? Do I need to add a new webpack.config.js file? If so, where @victorgarciaesgi exactly?
    optimization: {
        minimize: true,
    }
  1. In case this will lead to follow-up errors like the mentioned uglify issue, can you @mrcrowl explain in some more detail what exactly triggers it and how to come around it? Which part in your previous answer is actually the key to resolve the issue?

  2. @victorgarciaesgi You're saying not to use typex in production - so how then could it be useful after all (not sure I understand, that's why I'm asking)?

Thanks!

@larshg Could you wrap your head around it and make it work in production finally?

@alexeigs you can use it in production. You juste have to add a config to your uglyfier.

new UglifyJsPlugin({
          cache: true,
          parallel: true,
          uglifyOptions: {
            ie8: false,
            ecma: 5,
            mangle: true,
            output: {
              comments: false,
              beautify: false,
            },
            compress: { drop_console: true },
            warnings: false,
            keep_fnames: true,
          },
        }),

the important line is keep_fnames: true

@victorgarciaesgi Thanks! So far I've never modified these configurations and I guess I would need to put it inside vue.config.js, right (vs. having a separate webpack.config.js)? How would that look like?

@alexeigs I can make a gist of my vue.config.js if you want!

Great, thanks @victorgarciaesgi !

As my code contains ES6, I installed the TerserPlugin and now my production build works just fine. That's all I need as custom config for now to solve this issue, right?

vue.config.js

const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      config.optimization.minimizer = [
        new TerserPlugin({
          terserOptions: {
            keep_fnames: true,
          },
        }),
      ]
    }
  },
}

@alexeigs As far as i remember yeah that was the only thing that blocked me.
I've delivered a good number of sites in production with Vuex-typex and no problems for now!

@alexeigs And for the future, look at this. We will be able to create or own typed stores

https://vuedose.tips/tips/6