Unable to export generator functions

2019-06-04 19:01发布

问题:

When attempting to export a generator function in order to use in a Redux-Saga, ES-Lint is telling me that I have an error in my code:

[eslint] Expected a function declaration. (func-style)

It exports just fine the way that it is currently, and the rule is currently being ignored:

/*eslint-disable func-style*/
const myExampleSaga = function* () {
        yield takeEvery('DO_SOMETHING_REQUEST', andDoThisFunc);
};
export default myExampleSaga;

I am more or less okay with the fact that ES-Lint does not support generators (or at least it would seem that way), however I would like to know why the following code does not work:

export default function* () {
    yield takeEvery('DO_SOMETHING_REQUEST', andDoThisFunc);
}

With the following error message:

undefined is not an object (evaluating 'regeneratorRuntime.mark')

The error message is being thrown from my rootSaga, which looks like this:

/*eslint-disable func-style*/
export const rootSaga = function* rootSaga() {
    yield all([
        spawn(myExampleSaga)
    ]);
};

Can anyone tell me why the above code is invalid? I think it has something to do with hoisting, however I was not able to find any reason why that would be invalid.

回答1:

Can anyone tell me why the above code is invalid?

This is well-known issue of regenerator-transform babel plugin, which is commonly used for transpiling code with sagas. That issue also affects async functions, because they are implemented by regenerator-transform mechanism too.

export default function* () {
    yield takeEvery('DO_SOMETHING_REQUEST', andDoThisFunc);
}

After transforming that code , there can be two issues. First is omitting inclusion of regenerator-runtime dependency, which is mandatory. Second is function hoisting, so if occurrence order matters, it should be specified implicitly.

Correct solution is:

import 'regenerator-runtime';
const mySaga = function* () {
    yield takeEvery('DO_SOMETHING_REQUEST', andDoThisFunc);
}
export default mySaga;