mrcrowl / vuex-typex

Typescript builder for strongly-typed access to Vuex Store modules
MIT License
193 stars 22 forks source link

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

Closed larshg closed 5 years ago

larshg commented 6 years ago

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?

victorgarciaesgi commented 6 years ago

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

There is two possibilities here for this error appearing

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

larshg commented 6 years ago

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?

victorgarciaesgi commented 6 years ago

@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!

victorgarciaesgi commented 6 years ago

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

larshg commented 6 years ago

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

Thanks for looking at it!

victorgarciaesgi commented 6 years ago

@larshg I just started your app with no errors image

victorgarciaesgi commented 6 years ago

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

larshg commented 6 years ago

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

larshg commented 6 years ago

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

victorgarciaesgi commented 6 years ago

If production mode fails it's definitely the uglifying part

larshg commented 6 years ago

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

larshg commented 6 years ago

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

victorgarciaesgi commented 6 years ago

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

mrcrowl commented 5 years ago

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();},
  }
}
alexeigs commented 5 years ago

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,
    }
  2. 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?

  3. @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!

alexeigs commented 5 years ago

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

victorgarciaesgi commented 5 years ago

@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

alexeigs commented 5 years ago

@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?

victorgarciaesgi commented 5 years ago

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

victorgarciaesgi commented 5 years ago

@alexeigs https://gist.github.com/victorgarciaesgi/9f45c043a19904d7e373b7c181069965

alexeigs commented 5 years ago

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,
          },
        }),
      ]
    }
  },
}
victorgarciaesgi commented 5 years ago

@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!

victorgarciaesgi commented 5 years ago

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

https://vuedose.tips/tips/6