css-modules / css-modules-require-hook

A require hook to compile CSS Modules in runtime
MIT License
484 stars 44 forks source link

Testing with karma and karma-webpack-with-fast-source-maps #77

Open qmmr opened 8 years ago

qmmr commented 8 years ago

I've been using css-modules with mocha, enzyme and css-modules-require-hook without any problems.

// Foo.js
import React from 'react';
import styles from './Foo.css';

const Foo = () => <div className={ styles.foo }>Foo component</div>;

export default Foo;
// Foo.css
.foo {
    color: rebeccapurple;
}
// Foo.test.js
import Foo from '../Foo';

describe('<Foo />', () => {
    it('should render proper markup', () => {
        const wrapper = shallow(<Foo />);

        expect(wrapper.find('.foo')).to.have.length(1);
    });
});

I started using Karma with karma-webpack-with-fast-source-maps and now the test fails because the styles in Foo.js is an array: [[376, '.Foo__foo___3QT3e { color: rebeccapurple; } ', '']]

I've tried importing the css-modules-require-hook in test-bundler.js for karma-webpack but that throws a bunch of errors.

WARNING in ./~/css-modules-require-hook/preset.js
Critical dependencies:
13:7-22 the request of a dependency is an expression
 @ ./~/css-modules-require-hook/preset.js 13:7-22

// many more warnings

ERROR in ./~/css-modules-require-hook/lib/index.js
Module not found: Error: Cannot resolve module 'fs' in /Users/qmmr/code/streetlife/composer/code/site/node_modules/css-modules-require-hook/lib
 @ ./~/css-modules-require-hook/lib/index.js 14:19-32

// more errors

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
  SyntaxError: Unexpected token ')'

Is there a way to use css-modules-require-hook with karma-webpack?

mightyaleksey commented 8 years ago

Hi,

I'm not familiar with karma, but looks like if you managed to preprocess files with webpack then you don't need the require hook to be used here. Usually with webpack you need to configure css-loader properly.

Can you show a small example of your configuration, so I can take a look into it?

qmmr commented 8 years ago

Hi @sullenor,

Thanks for your prompt response. I've put together a repository that shows the issue. Currently, when I search for .menu in the test it fails because the hook is not working. I've tried adding it to test-bundler.js and to karma.config.js but none of those work. I've added two commands for testing. npm run test will launch karma (doesn't like require hook) npm run test:mocha will launch mocha (works fine with require hook)

Hope it helps to visualise the issue.

mightyaleksey commented 8 years ago

As far as I know every chain of webpack loaders should return a valid commonJs module in the end.

Talking about css — you should use style-loader with css-loader together. Using them in that way will result in the valid commonJs modules. So your configuration should look similar to this:

module: {
  loaders: [
    // ...
    {
      test: /\.css$/,
      loader: 'style!css?modules&importLoaders=1&localIdentName=...',
    },
  ]
}

I sent you a small pr https://github.com/qmmr/yab/pull/1 which fixes configuration for the webpack dev server and also added small patch to the webpack.config.test.js. I think it should solve the issue for now.

mightyaleksey commented 8 years ago

Actually, I don't know a lot about loaders but looks like that the solution above should be valid :)

You may check the examples to find more information about the topic: https://github.com/webpack/style-loader#simple-api https://github.com/webpack/css-loader#example-config

qmmr commented 8 years ago

@sullenor I've tried your PR but it does not work for me. The npm run test still errors.

yab-patch master 4h14m ➜ npm run test

> YAB@1.0.0 test /Users/qmmr/code/react-apps/yab-patch
> karma start --single-run --no-auto-watch karma.config.js

16 08 2016 17:09:06.116:INFO [karma]: Karma v1.2.0 server started at http://localhost:9876/
16 08 2016 17:09:06.118:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
16 08 2016 17:09:06.173:INFO [launcher]: Starting browser PhantomJS
16 08 2016 17:09:06.728:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket /#f1sh97JzIygZzO8wAAAA with id 6596294
PhantomJS 2.1.1 (Mac OS X 0.0.0) LOG LOG: 'styles', [[376, '.Menu__menu___cuY3N {
    display: inline-block;
}
', '']]
LOG LOG: '<ul className={[undefined]}>
<li>
<a href="#">
File
</a>
</li>
<li>
<a href="#">
Edit
</a>
</li>
<li>
<a href="#">
Help
</a>
</li>
</ul>'

  <Menu />
    ✗ should render
    expected { Object (root, unrendered, ...) } to have a length of 1 but got 0
    AssertionError@tests/test-bundler.js:19931:25
    assert@tests/test-bundler.js:24032:32
    assertLength@tests/test-bundler.js:25107:17
    assert@tests/test-bundler.js:23831:55
    tests/test-bundler.js:38277:48

PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.018 secs / 0.013 secs)

Your suggestion does not include css-modules-require-hook.

This repo is just to solve the issue of finding DOM elements using css-selectors when running karma-webpack. So the question still remains, how can I include css-modules-require-hook into this setup so that when I run tests via karma, it will result in the same output as tests run with mocha.

Thanks for the links, I will read about webpack and plugins.

mightyaleksey commented 8 years ago

Hm, that's interesting cause I had the necessary markup in the example :)

PhantomJS 2.1.1 (Mac OS X 0.0.0) LOG LOG: 'styles', Object{menu: 'Menu__menu___cuY3N'}
LOG LOG: '<ul className="Menu__menu___cuY3N">
<li>
<a href="#">
File
</a>
</li>
...
</ul>'

Your suggestion does not include css-modules-require-hook.

Since you are able to use webpack, you don't need css-modules-require-hook. In my opinion it should fill the gap in case you don't have a possibility to use webpack. For example, server-side rendering.

Update: Presumably, I didn't understand you. I guess I haven't checked all the files. Let me update my pr.

mightyaleksey commented 8 years ago

I checked again your repo and reproduced errors with adding import css-modules-require-hook/preset in test-bundler.js.

Presumably, all the errors come after the webpack tries to preprocess the provided files and it's dependencies. Since, the required hook was designed to compile CSS Modules in runtime it hardly depends on nodejs environment. That's why webpack can't load some core nodejs modules like fs. There is a solution for that problem here: http://webpack.github.io/docs/configuration.html#node Other errors come from loading css files, cause no loader was provided for the css in the webpack.config.js and webpack doesn't know how to handle it properly (the one which was provided matches only src/css files).

As far as I know karma uses browser environment to execute all the tests: http://karma-runner.github.io/0.13/intro/how-it-works.html So setting css-modules-require-hook will be a wrong here cause it isn't suitable for that environment. Since you compile sources with webpack for karma, in my opinion with should fix webpack configuration webpack.config.test.js.

I added style loader to the chain (add installed it) and it fixed issue with loading modules.

PhantomJS 2.1.1 (Mac OS X 0.0.0) LOG LOG: 'styles', Object{menu: 'Menu__menu___cuY3N'}
LOG LOG: '<ul className="Menu__menu___cuY3N">

Still there is an another issue with enzyme.