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

Using PostCSS mixins in CSS modules causes a syntax error #424

Closed
sevilyilmaz opened this issue Dec 6, 2021 · 4 comments · Fixed by #425
Closed

Using PostCSS mixins in CSS modules causes a syntax error #424

sevilyilmaz opened this issue Dec 6, 2021 · 4 comments · Fixed by #425

Comments

@sevilyilmaz
Copy link
Contributor

This issue might be related to vue-jest but I'll open it here because I got the error from the test utils and I'm 100% sure of the what is responsible from it. Please feel free to point me to the correct repo if this is not the one.

Description

I get the error below when I use a PostCSS mixin in a CSS file. I assume it expects a semicolon where I use the mixin while parsing the CSS file but it cannot find it and throws this error.

 FAIL  src/components/HellowWorld.test.js
   Test suite failed to run

    undefined:12:1: missing '}'

      at error (node_modules/css/lib/parse/index.js:62:15)
      at declarations (node_modules/css/lib/parse/index.js:260:26)
      at rule (node_modules/css/lib/parse/index.js:561:21)
      at rules (node_modules/css/lib/parse/index.js:118:70)
      at stylesheet (node_modules/css/lib/parse/index.js:81:21)
      at Object.module.exports [as parse] (node_modules/css/lib/parse/index.js:565:20)
      at Function.extractClasses (node_modules/extract-from-css/lib/index.js:14:23)
      at extractClassMap (node_modules/@vue/vue3-jest/lib/process-style.js:24:31)
      at processStyle (node_modules/@vue/vue3-jest/lib/process-style.js:123:25)
      at node_modules/@vue/vue3-jest/lib/process.js:149:13

Reproduction link: https://github.com/sevilyilmaz/vue-3-setup-css-modules-mixin

Setup

HelloWorld.vue

<script>
import { ref, computed, useCssModule } from 'vue';

export default {
  props: {
    msg: String,
  },
  setup(props) {
    const styles = useCssModule();
    const rootClasses = computed(() => ({
      [styles.root]: true,
    }));

    return { rootClasses };
  },
};
</script>

<template>
  <div :class="rootClasses">{{ msg }}</div>
</template>

<style src="./HelloWorld.module.css" module />

HelloWorld.module.css

:root {
  --theme_color_background_base: #f00;
}

@define-mixin hover {
  outline: none;
  box-shadow: 0 0 0 2px var(--theme_color_background_base);
}

.root {
  color: #42b983;
}
.root:hover {
  @mixin hover;
}

HelloWorld.test.js

import { mount } from '@vue/test-utils';
import HelloWorld from './HelloWorld.vue';

describe('HelloWorld', () => {
  it('renders with correct classes', () => {
    const wrapper = mount(HelloWorld);

    expect(wrapper.classes()).toEqual(['root']);
  });
});

jest.config.js

module.exports = {
  collectCoverageFrom: ['src/**/*.{js,vue}'],
  coverageReporters: ['text', 'cobertura', 'json', 'lcov', 'clover'],
  coverageProvider: 'v8',
  errorOnDeprecated: true,
  moduleFileExtensions: ['js', 'json', 'vue'],
  notify: false,
  snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
  testEnvironment: 'jest-environment-jsdom',
  testPathIgnorePatterns: ['<rootDir>/cypress/'],
  testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(test).[jt]s?(x)'],
  testURL: 'http://localhost',
  transform: {
    '^.+\\.vue$': '@vue/vue3-jest',
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
      require.resolve('jest-transform-stub'),
  },
  transformIgnorePatterns: ['/node_modules/(?!some-internal-modules).+\\.js$'],
};
@cexbrayat cexbrayat transferred this issue from vuejs/test-utils Dec 7, 2021
@cexbrayat
Copy link
Member

Hi @sevilyilmaz

I transfered the issue to vue-jest as I indeed think this is a a vue-jest issue.
The stacktrace mentions extractClassMap as the source of the error.
extractClassMap uses the fairly old (7 years?!) https://github.com/rubennorte/extract-from-css package, so it's definitely possible that this package does not support some syntaxes.

If you want to give a hand, you can try to add a test to this repo and see what syntax is failing specifically. Maybe we can use another dependency to do this job instead of extract-from-css?

@sevilyilmaz
Copy link
Contributor Author

sevilyilmaz commented Dec 7, 2021

@cexbrayat vue-jest does not have unit tests. Adding my example in one of the fixtures in E2E tests resulted the same error with less details.

 FAIL  ./test.js
  ● Test suite failed to run

    undefined:13:1: missing '}'

      at error (../../../node_modules/css/lib/parse/index.js:62:15)

I dug into it a bit and this is what I found. vue-jest uses tries to get CSS maps in process-style.js with extract-from-css and that uses an old version (^2.1.0) of the css package to parse the CSS.

We can use @vue/compiler-sfc to compile the CSS (which uses PostCSS) as it's done in @vite/plugin-vue which would be better as vue-jest would be parsing the components as Vue does, though this might increase the scope of this issue.

What do you think?

@cexbrayat
Copy link
Member

That would probably be way better, if you would like to make a PR, that would be awesome!

@sevilyilmaz
Copy link
Contributor Author

I picked an another route and replaced the CSS parser. Please have a look.

lmiller1990 pushed a commit that referenced this issue Feb 17, 2022
Replaced `extract-from-css` which is outdated (7yo) with `css-tree`

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

Successfully merging a pull request may close this issue.

2 participants