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

regeneratorRuntime is not defined #1289

Closed
chrisblossom opened this issue Sep 5, 2017 · 8 comments
Closed

regeneratorRuntime is not defined #1289

chrisblossom opened this issue Sep 5, 2017 · 8 comments

Comments

@chrisblossom
Copy link

Issue description or question

Did something change with Wallaby? I am now getting regeneratorRuntime is not defined without additional config required. Running jest from command line works as expected.

Wallaby.js configuration file

/* eslint strict:off, global-require:off */

module.exports = wallaby => {
    return {
        files: [
            {
                pattern: 'src/**/__sandbox__/**/*',
                instrument: false,
            },
            'src/**/*.js',
            'jest.config.js',
            '.env',
            '.babelrc',
            '.babelrc.js',
            'src/**/*.snap',
            '!src/**/*.test.js',
        ],
        tests: [
            'src/**/*.test.js',
        ],

        compilers: {
            '**/*.js': wallaby.compilers.babel(),
        },

        env: {
            type: 'node',
            runner: 'node',
        },

        testFramework: 'jest',

        setup: w => { 
            /**
             * https://github.com/wallabyjs/public/issues/1268#issuecomment-323237993
             */
            if (w.projectCacheDir !== process.cwd()) {
                process.chdir(w.projectCacheDir);
            }

            process.env.NODE_ENV = 'test';
            const jestConfig = require('./jest.config');
            jestConfig.transform = { '__sandbox__.+\\.jsx?$': 'babel-jest' };
            w.testFramework.configure(jestConfig);

            // This fixes the issue:
            // require('babel-polyfill');
            // w.testFramework.configure(
            //     Object.assign({}, jestConfig, {
            //         globals: {
            //             regeneratorRuntime: global.regeneratorRuntime,
            //         },
            //     })
            // );
        },
    };
};

Code editor or IDE name and version

WebStorm 2017.2.4 EAP
Build #WS-172.4155.10, built on August 31, 2017
JRE: 1.8.0_152-release-915-b11 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Mac OS X 10.12.6

OS name and version

Mac OS X 10.12.6

@ArtemGovorov
Copy link
Member

Hmm, nothing was changed that could have affected your scenario. As you have mentioned in the comment, require('babel-polyfill') and passing it to the Jest globals should help.

What could be happening is that for some reason Jest and Wallaby may be applying different babel options during compilation (perhaps you are using babel environments), so that Jest outputs JS code without regeneratorRuntime.

Could you please share the following files:

  • package.json,
  • jest.config.js
  • .babelrc,
  • .babelrc.js,
  • also an example of a file where you've hit the error (probably using async/await or similar)

and I'll try to reproduce the issue.

@chrisblossom
Copy link
Author

chrisblossom commented Sep 12, 2017

I've tried to reproduce the issue without success.

package.json

{
  "private": true,
  "version": "1.0.0",
  "main": "build/index.js",
  "license": "MIT",
  "bin": {
    "sane": "./build/cli/cli.js"
  },
  "scripts": {
    "clean": "del ./build/*",
    "lint": "eslint --ext .js .",
    "lint:fix": "eslint --fix --ext .js .",
    "build": "npm run clean && NODE_ENV=production babel src -d build --ignore test.js --source-maps && flow-copy-source src build",
    "dev": "npm run clean && NODE_ENV=production babel -w src/ -d build/ --ignore test.js --source-maps",
    "format": "find . -name \"*.js\" | grep -v -f .prettierignore | xargs prettier --tab-width 4 --single-quote --trailing-comma all --write",
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "gitDir": "../../",
    "linters": {
      "./*.js": [
        "prettier --tab-width 4 --single-quote --trailing-comma es5 --write",
        "git add"
      ],
      "src/**/*.js": [
        "prettier --tab-width 4 --single-quote --trailing-comma all --write",
        "git add"
      ]
    }
  },
  "devDependencies": {
    "babel-cli": "6.26.0",
    "babel-core": "6.26.0",
    "babel-eslint": "7.2.3",
    "babel-plugin-dynamic-import-node": "1.0.2",
    "babel-plugin-transform-object-rest-spread": "6.26.0",
    "babel-polyfill": "6.26.0",
    "babel-preset-env": "1.6.0",
    "babel-preset-flow": "6.23.0",
    "del-cli": "1.1.0",
    "eslint": "4.6.1",
    "eslint-config-prettier": "2.4.0",
    "eslint-plugin-jest": "20.0.3",
    "flow-bin": "0.54.0",
    "flow-copy-source": "1.2.1",
    "husky": "0.14.3",
    "jest": "20.0.4",
    "lint-staged": "4.1.0",
    "prettier": "1.6.1"
  },
  "dependencies": {
    "babel-polyfill": "6.26.0",
    "chalk": "2.1.0",
    "del": "3.0.0",
    "dotenv": "4.0.0",
    "fs-extra": "4.0.1",
    "joi": "10.6.0",
    "lodash": "4.17.4",
    "sort-keys": "2.0.0",
    "source-map-support": "0.4.16"
  }
}

.babelrc

{
    "presets": ["./.babelrc.js"]
}

.babelrc.js

'use strict';

const babel = {
    presets: [
        [
            'env',
            {
                targets: {
                    node: '4.0.0',
                },
                useBuiltIns: true,
            },
        ],
        'flow',
    ],
    plugins: ['dynamic-import-node', 'transform-object-rest-spread'],
};

module.exports = babel;

jest.config.js

/* eslint strict:off, global-require:off */

'use strict';

/**
 * https://facebook.github.io/jest/docs/configuration.html#options
 */
module.exports = {
    rootDir: 'src',
    moduleDirectories: ['node_modules', 'src'],
    testEnvironment: 'node',
    collectCoverage: false,
    coveragePathIgnorePatterns: ['/__sandbox__/'],

    /**
     * Automatically reset mock state between every test.
     * Equivalent to calling jest.resetAllMocks() between each test.
     *
     * Sane default with resetModules: true because mocks need to be inside beforeEach
     * for them to work correctly
     */
    resetMocks: true,

    /**
     *  The module registry for every test file will be reset before running each individual test.
     *  This is useful to isolate modules for every test so that local module state doesn't conflict between tests.
     */
    resetModules: true,
};

example file

it('example', async () => {});

@chrisblossom
Copy link
Author

Example Repo: https://github.com/chrisblossom/wallaby-issue-1289

I included the .idea folder incase there is something in there you need.

@ArtemGovorov
Copy link
Member

Thanks for the repo!
It looks like with your babel config (to target node 4), babel does emit code that is using regeneratorRuntime, both in wallaby and Jest. It's just that Jest automagically adding the regeneratorRuntime if the module is present and babel-jest is used.

Wallaby doesn't use babel-jest, so you need to add regenerator-runtime as you were doing it, or, better, the way Jest does it:

module.exports = wallaby => {
    return {
        ...

        setup: w => {
            ...
+           jestConfig.setupFiles = [require.resolve('regenerator-runtime/runtime')]
            w.testFramework.configure(jestConfig);
        },
    };
};

Please note that because your current babel config emits regeneratorRuntime when compiling the code using async/await, you may also need to load babel-polyfill/use regenerator-runtime for your production build (if you're not already doing it).

@chrisblossom
Copy link
Author

Any thoughts on why this just worked before? I think if babel-polyfill is used, it needs to be required via Wallaby's setup for everyone's config.

@ArtemGovorov
Copy link
Member

Any thoughts on why this just worked before?

Could be a few different reasons:

  • maybe you didn't use features that required regeneratorRuntime (like async),
  • maybe you were targeting a higher node version before. For example, if you change your .babelrc.js to target node: '6.0.0', or node: '7.0.0', or node: '8.0.0' (and edit the src/issue.test.js file) it'll start working, because babel will not emit the code using regeneratorRuntime for these node versions.

I think if babel-polyfill is used, it needs to be required via Wallaby's setup for everyone's config.

Whether or not babel-polyfill is required, really depends on your babel config. For example, as I have mentioned, if you are targeting node 6 - it's not required.

Will investigate the option of automagically determining whether it is required or not, however babel-polyfill is rarely used for node these days, targeting node 4 (as opposed to at least 6) is not something we see very often. Also it looks like babel is going to automatically emit required polyfills in version 7, so the change may not be required.

@chrisblossom
Copy link
Author

I just found out why I had such a difficult time tracking this issue down and reproducing it. First thing I did was try to update .babelrc.js to node: '6.0.0' but the same issue happened. I didn't realize I had to clear Wallaby's cache by changing wallaby.js.

Might be a good idea to clear Wallaby's cache when .babelrc* (or any other compiler's config, such as typescript) is changed. Or just something I need to think about in the future.

That is true about babel-polyfill not currently being needed for almost anything in node 8, but that probably won't always be the case in future versions. Not sure it should be automatically done, just maybe in the docs(if it isn't already).

FYI, list of current polyfills for node 6.11:

  es7.object.values {"node":"6.11"}
  es7.object.entries {"node":"6.11"}
  es7.object.get-own-property-descriptors {"node":"6.11"}
  es7.string.pad-start {"node":"6.11"}
  es7.string.pad-end {"node":"6.11"}

Thank you for the help!

@ArtemGovorov
Copy link
Member

Might be a good idea to clear Wallaby's cache when .babelrc* (or any other compiler's config, such as typescript) is changed.

Good idea, just added the feature in the latest core version.

That is true about babel-polyfill not currently being needed for almost anything in node 8, but that probably won't always be the case in future versions. Not sure it should be automatically done, just maybe in the docs(if it isn't already).

Fair enough. For now we have added regeneratorRuntime automatic loading (just like Jest is doing), so once you update to the latest version, this:

jestConfig.setupFiles = [require.resolve('regenerator-runtime/runtime')]

will not be required anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants