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

Webpack build issues #47

Closed
kgoggin opened this issue Dec 4, 2015 · 73 comments
Closed

Webpack build issues #47

kgoggin opened this issue Dec 4, 2015 · 73 comments
Assignees

Comments

@kgoggin
Copy link

kgoggin commented Dec 4, 2015

I'm trying to get enzyme working using a pretty standard webpack/karma setup. Webpack throws a bunch of errors related to the dependencies enzyme imports, including sinon, cheerio, and jsdom. Sinon gives webpack heartburn because it uses it's own require (which seems to be documented here: webpack/webpack#304), and then there are a bunch of "Module not found" errors for jsdom and cheerio.

I'm importing enzyme as described in the docs and can't really think of anything else I might be missing, so I'm curious if anyone else is trying to use webpack and running into a similar issue, or if there's just something weird with my configuration. I'd expect to be able to just import it and have it work, but maybe I need to do something with those external libraries?

Here's my test file for reference:

import expect from 'expect';
import { shallow } from 'enzyme';
import React from 'react';
import Button from '../Button';

describe('Button', () => {
    it('should render children passed in', () => {
        const wrapper = shallow(
            <Button><div className="foo" /></Button>
        );

        expect(wrapper.contains(<div className="foo" />)).toBe(true);
    });
});

I won't paste the entire error log from webpack because it's pretty long, but here's a sample:


WARNING in ./~/enzyme/~/jsdom/~/acorn/dist/acorn.js
Critical dependencies:
1:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/enzyme/~/jsdom/~/acorn/dist/acorn.js 1:478-485

WARNING in ./~/enzyme/~/jsdom/~/acorn/dist/walk.js
Critical dependencies:
1:503-510 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/enzyme/~/jsdom/~/acorn/dist/walk.js 1:503-510

ERROR in ./~/enzyme/build/react-compat.js
Module not found: Error: Cannot resolve module 'react/lib/ExecutionEnvironment' in /Users/agoggin/www/vhosts/hammerhead/node_modules/enzyme/build
 @ ./~/enzyme/build/react-compat.js 22:2-43

ERROR in ./~/enzyme/~/cheerio/index.js
Module not found: Error: Cannot resolve module 'json' in /Users/agoggin/www/vhosts/hammerhead/node_modules/enzyme/node_modules/cheerio
 @ ./~/enzyme/~/cheerio/index.js 11:18-38

ERROR in ./~/enzyme/~/jsdom/lib/jsdom.js
Module not found: Error: Cannot resolve module 'fs' in /Users/agoggin/www/vhosts/hammerhead/node_modules/enzyme/node_modules/jsdom/lib
 @ ./~/enzyme/~/jsdom/lib/jsdom.js 6:9-22

My webpack/karma config is pretty vanilla, but it'd help I can post that, too.

@lelandrichardson
Copy link
Collaborator

Hey @kgoggin, thanks for reporting the issue.

It'd be helpful if I could have a small repro of the issue... If there's a repo that I can pull down on to my own machine, that would work... or alternatively a gist link with the relevant files needed to reproduce, that would be helpful.

I haven't tried using the library with a webpack/karma project yet. My best guess is that webpack is building a bundle of your tests, which include reagent, which then include jsdom... and bundling jsdom and passing to a browser is probably a nightmare. Since you are only using shallow at the moment, you might consider just marking jsdom as external to webpack.

In the long term, I'd like to either:

  1. Have everything "just work" with a vanilla webpack / karma project
  2. Have some notes in the documentation regarding how to configure the project so it will work

@kgoggin
Copy link
Author

kgoggin commented Dec 4, 2015

Sure thing, @lelandrichardson. I just forked a boilerplate repo and added the dependency, and I'm getting the same error. https://github.com/kgoggin/react-es6-webpack-karma-boilerplate.

You should be able to just clone it, npm install, then npm run test and see the errors generated.

Webpack is definitely building a bundle of the tests, so it's definitely trying to include all of reagent's deps. Hadn't considered that about jsdom, I'm sure that's at least part of the problem. But, I think even if I externalized that one I'd still have issues with sinon and cheerio. I haven't dug into this project enough to see how/why you're using those, but I think either one of your two solutions would be fantastic. This looks like a really helpful utility and I'd love to get it working!

Thanks for taking a look!

@hank7444
Copy link

hank7444 commented Dec 5, 2015

I have the same problem@@

@lelandrichardson lelandrichardson self-assigned this Dec 5, 2015
@lelandrichardson
Copy link
Collaborator

There's a couple of things going on here.

Reagent was not really designed to be "bundled", as there are some conditional requires. This is mostly done in order to be compatible with both react 0.13 and react 0.14.

The conditional requires are the errors / warnings you're seeing related to "react-dom/server" and "react-addons-test-utils" etc. (since that boilerplate is using react 0.13. However, karma/webpack seems to swallow those errors and continue on just fine.

The other issue (which is what is stopping phantomjs in it's tracks) is the bundling of sinon and jsdom.

The jsdom thing isn't really a problem, and you can just set jsdom as an external in webpack and all will work fine since you're using phantomJS.

The sinon thing i can't seem to figure out. Sinon seems to be incompatible with webpack's bundling due to some conditional requires that it's doing underneath.

We will probably end up removing sinon as a dependency entirely very soon ( #44 ), so that's the good news. In the interim, I'm trying to figure out a way to get webpack to not choke on sinon by following some of the advice in this thread: webpack/webpack#177

Adding this to your karma config should get you essentially to where I am:

    webpack: {
      externals: {
        "jsdom": "window",
        "cheerio": "window"
      },
    }

Still working on the sinon issue. I will keep you updated.

@lelandrichardson
Copy link
Collaborator

Also, it looks like this may not be an issue with Sinon 2.0: sinonjs/sinon#830

@lecstor
Copy link
Contributor

lecstor commented Dec 5, 2015

Updating reagent to the npm prerelease of sinon (sinon@2.0.0-pre) gets us over that hurdle. Now I'm looking at the following, which is a little odd as I have "react": "^0.14.0" in my package.json..

ERROR in ./~/reagent/build/react-compat.js
Module not found: Error: Cannot resolve module 'react/lib/ExecutionEnvironment' in .../react-redux-starter-kit/node_modules/reagent/build
 @ ./~/reagent/build/react-compat.js 22:2-43

Semi-related.. I previously worked around the webpack/sinon issue by installing karma-sinon and including sinon as a framework in karma which injected it into my tests so I didn't need to require it. (this didn't work once I was using reagent in the tests though)

@lelandrichardson
Copy link
Collaborator

@lecstor you should be able to get around that error by just adding react/lib/ExecutionEnvironment to the list of externals. Webpack is attempting to bundle this since there is a conditional require call to it (only get's called for React 0.13). After that, you should be good to go!

To fix this officially, I'm thinking it makes sense to just wait until we remove the sinon dependency entirely. After that, webpack should be workable by just making jsdom and cheerio externals...

@lecstor
Copy link
Contributor

lecstor commented Dec 5, 2015

@lelandrichardson thanks, yes, that did the trick.. on to the next (unrelated) issue..

and yes, not worth trying to fix something you plan to remove anyway. 👍

@MattKunze
Copy link

Sinon 2.0 seems like it's somewhat abandoned, we came up with some other workarounds for it here: sinonjs/sinon#600 (comment)

Glad to see the dependency is being removed

@lecstor
Copy link
Contributor

lecstor commented Dec 7, 2015

thanks for that @MattKunze, that looks like a much simpler solution!

@vieron
Copy link

vieron commented Dec 7, 2015

My final webpack config to get enzyme running:

module: {
    noParse: [
        /node_modules\/sinon\//,
    ]
},
resolve: {
    alias: {
        'sinon': 'sinon/pkg/sinon'
    }
},
externals: {
    'jsdom': 'window',
    'cheerio': 'window',
    'react/lib/ExecutionEnvironment': true
}

Related issues:

@vyorkin
Copy link

vyorkin commented Dec 7, 2015

thanks @vieron for sharing your config, I've just ran into the same issue (using vanilla js). Maybe it should be somehow reflected in the docs/readme?

@kiki-le-singe
Copy link

@vieron thanks it works

@lelandrichardson
Copy link
Collaborator

Thanks @vieron for sharing the webpack config. I am working on a PR that will knock a few of these things out, and will include a "guides" section in the docs that will cover getting enzyme working with webpack/karma as well as some other setups. No doubt the work in this issue has been helpful for this effort!

@ingro
Copy link

ingro commented Dec 7, 2015

I tried @vieron config but the errors are still here. I'm using sinon and jsdom outside enzyme, maybe this could cause some conflict?

lelandrichardson added a commit that referenced this issue Dec 8, 2015
This refactor addresses several issues regarding enzyme working in a variety of environments, and
the library just generally not making any assumptions about the environment that tests will be
run in.

For the most part, this amounts to:

- remove direct dependency on jsdom
- remove direct dependency on sinon
- remove assumed dependency on mocha

Additionally, this change moves the code that was removed into separate modules that are
defined in the packages folder. In this case we have added two modules: "enzyme-mocha" and
"enzyme-sinon".

This design will allow us to have one repo where all issues, code, and documentation
regarding enzyme are centralized, but modules are still separated at the NPM level. This
will allow us to make atomic releases across the modules more easily, as well as keep
all of the discussion in one place.

Left to do before this is mergable:

 [ ] Add a "guides" section in the docs explaining how to use enzyme in different environments
 [ ] Build a proper npm script to run an npm publish in the proper order for each module
 [ ] Add more meaningful tests for packages

This PR addresses several issues that havee been brought up:

- Fixes #55
- Fixes #47
- Fixes #44
@n7best
Copy link

n7best commented Dec 8, 2015

@vieron thanks for the config man!

@javascriptjedi
Copy link

My final solution is the same as @vieron except I didn't have to put cheerio or react/lib/ExecutionEnvironment in my config as externals (at least not yet).

@lelandrichardson
Copy link
Collaborator

@javascriptjedi this may be because you're using a different version (React 0.13?)

@javascriptjedi
Copy link

I'm on 0.14.3.

@liorbrauer
Copy link

Any other possible solutions? I'm getting similar errors, tried @vieron's solution, but am still not able to get it to run.

I'm getting errors like:

WARNING in ./~/enzyme/~/sinon/lib/sinon.js
Critical dependencies:
40:25-32 require function is used in a way in which dependencies cannot be statically extracted
 @ ./~/enzyme/~/sinon/lib/sinon.js 40:25-32

WARNING in ./~/enzyme/~/sinon/lib/sinon/assert.js
Critical dependencies:
216:25-32 require function is used in a way in which dependencies cannot be statically extracted
 @ ./~/enzyme/~/sinon/lib/sinon/assert.js 216:25-32

WARNING in ./~/enzyme/~/sinon/lib/sinon/behavior.js
Critical dependencies:
362:25-32 require function is used in a way in which dependencies cannot be statically extracted
 @ ./~/enzyme/~/sinon/lib/sinon/behavior.js 362:25-32

for sinon, and for cheerio and jsdom as well.

@lecstor
Copy link
Contributor

lecstor commented Dec 17, 2015

I must have got it somewhere else, but I also have

          {
            test: /sinon\.js$/,
            loader: 'imports?define=>false,require=>false'
          }

as one of my webpack loaders.

@liorbrauer
Copy link

Hmmm, thanks for this @lecstor. I just realized I was adding @vieron and your configurations to my general webpack.config.js file instead of defining them in my karma.conf.js under the webpack: {} hash.

Without @lecstor's snippet I get the tests to work, with one issue:

Module not found: Error: Cannot resolve module 'react/lib/ReactContext' in /Users/liorbrauer/dapulse/node_modules/enzyme/build

(with @lecstor's snippet, my tests don't run)

@smacker
Copy link
Contributor

smacker commented Dec 17, 2015

@liorbrauer just add 'react/lib/ReactContext' in externals section of config. Works for me.

@vyorkin
Copy link

vyorkin commented Dec 17, 2015

@liorbrauer here is what I did to make it work with react 0.14: new webpack.IgnorePlugin(/react\/lib\/ReactContext/)

@lecstor
Copy link
Contributor

lecstor commented Dec 17, 2015

yes, same, my externals are currently:

      externals: {
        jsdom: 'window',
        cheerio: 'window',
        'react/lib/ExecutionEnvironment': true,
        'react/lib/ReactContext': 'window',
        'text-encoding': 'window'
      },

full config here.. https://github.com/lecstor/react-startup-starter/blob/master/karma.conf.js

@wyuenho
Copy link

wyuenho commented Nov 4, 2016

Besides using externals, this should also work and is arguably more explicit, since what you really want is to ignore the requires, instead of marking them as externally available.

If you are using React 0.14+

plugins: [
    new webpack.IgnorePlugin(/react\/addons/),
    new webpack.IgnorePlugin(/react\/lib\/ReactContext/),
    new webpack.IgnorePlugin(/react\/lib\/ExecutionEnvironment/)
]

If you are using React 0.13

plugins: [
    new webpack.IgnorePlugin(/react-dom/),
    new webpack.IgnorePlugin(/react-addons-test-utils/),
    new webpack.IgnorePlugin(/react-dom\/server/)
]

Note that cheerio is not in the list, it looks like it is required regardless now. The above configuration was tested on Webpack 2.

@ljharb
Copy link
Member

ljharb commented Nov 4, 2016

@wyuenho PRs to improve the guides are always appreciated.

@wyuenho
Copy link

wyuenho commented Nov 4, 2016

@ljharb I've updated my comment above. Here's the PR that clarifies what the Webpack configs do.

@Vanuan
Copy link

Vanuan commented Jan 19, 2017

Here are the changes that helped in my case. I'm using react 15.4.1

  resolve: {
    alias: {
      // Conditional requires workaround
      // https://github.com/sinonjs/sinon/issues/830
      'sinon': 'sinon/pkg/sinon'
    },
  },
  module: {
    noParse: [
      // Conditional requires workaround
      // https://github.com/sinonjs/sinon/issues/830
      /node_modules\/sinon\//,
    ],
  },
  externals: {
    // Conditional requires workaround
    // https://github.com/airbnb/enzyme/issues/47
    // https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md
    'cheerio': 'window',
    'react-dom/server': 'window',
  },
  plugins: [
    // Conditional requires workaround
    // https://github.com/airbnb/enzyme/issues/47
    // https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md
    new webpack.IgnorePlugin(/react\/addons/),
    new webpack.IgnorePlugin(/react\/lib\/ReactContext/),
    new webpack.IgnorePlugin(/react\/lib\/ExecutionEnvironment/)
  ]

I'm not sure which of those are necessary. Maybe it may be simplified.

Hope it helps.

@TheLarkInn
Copy link

@blainekasten I could give some guidance on maybe wrapping some of the complexities in a plugin for this use with webpack. Let me know if we can help.

@wyuenho
Copy link

wyuenho commented Jan 20, 2017

@Vanuan Does it work for you without the externals?

@Vanuan
Copy link

Vanuan commented Jan 21, 2017

@wyuenho I suppose IgnorePlugin and externals are interchangeable. The difference is that externals actually expect the externalized variable to be present in the global scope. While IgnorePlugin just leaves import/require as is.

@trusktr
Copy link

trusktr commented Mar 27, 2017

Can you guys please add a global build? I have this same problem trying to build a AMD or UMD module to use in a "legacy" RequireJS environment.

Here's a reproduction using browserify: #861

@trusktr
Copy link

trusktr commented Mar 27, 2017

^ Just run npm i && npm run build-global to get the error.

@trusktr trusktr mentioned this issue Mar 27, 2017
@ljharb
Copy link
Member

ljharb commented Mar 27, 2017

This is a long thread; it'd be helpful to restate the problems.

Thanks to @trusktr, we now have #861 as a repro example for browserify. Let's see if we can't figure out how to fix that, and then document it for users of browserify - if users of other setups could provide similar repro examples, that'd also be helpful.

@trusktr
Copy link

trusktr commented Mar 27, 2017

Here's a PR that has a global (UMD) successfully built with browserify: #863. But I don't know if it has any bad sideeffects from excluding the things that it does.

@trusktr
Copy link

trusktr commented Mar 27, 2017

I am able to confirm that a test similar to the following basic test (in my case) works when I use the UMD-version of enzyme built based on #863 (build/global.js):

fixture('<NumberInput />', function () {
    test('onChange', function () {
        const wrapper = shallow(
            <NumberInput disabled={false} value={0} />
        )

        assert.equal(wrapper.find('input').length, 1)
    });
});

I'm not sure if some other parts of the API might be broken based on what's excluded in #863, but for now I can make basic tests.

@ljharb
Copy link
Member

ljharb commented Sep 26, 2017

Is this still relevant with v3?

@lelandrichardson
Copy link
Collaborator

I don't think so. Closing. If anyone still has issues, feel free to reopen.

marvellous122 added a commit to marvellous122/react-redux-base that referenced this issue Jan 19, 2018
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
shaun554 added a commit to shaun554/react-boilerplate that referenced this issue Mar 21, 2019
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
mauricewells pushed a commit to mauricewells/react-boilerplate that referenced this issue Jan 21, 2022
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
kazuma512 added a commit to kazuma512/react-boilerplate-typescript that referenced this issue Jun 2, 2023
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
AIDevMonster added a commit to AIDevMonster/react-boilerplate that referenced this issue Jun 21, 2023
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
whiteghostDev added a commit to whiteghostDev/react-boilerplate that referenced this issue Aug 6, 2023
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
wesleywang4766 added a commit to wesleywang4766/lodash that referenced this issue Mar 8, 2024
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
winder9 pushed a commit to M-Killer-dev/React-project that referenced this issue Jun 16, 2024
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
JackMJones pushed a commit to JackMJones/Jack1213 that referenced this issue Aug 17, 2024
* Add `test-bundler.js`, which sets up chai/chai-enzyme, and requires all tests.

* Karma config: Only reference `test-bundler.js` instead of a glob.

* Webpack test config: Removed cheerio from externals
enzymejs/enzyme#47 (comment)
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