Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Css parsing no longer works since 4.1.5 with postcss #207

Closed
aldarund opened this issue May 27, 2018 · 8 comments
Closed

Css parsing no longer works since 4.1.5 with postcss #207

aldarund opened this issue May 27, 2018 · 8 comments

Comments

@aldarund
Copy link

Expected behavior

Build not fails

Actual behavior

Build fails

[!] (babel plugin) SyntaxError: C:\Dev\PycharmProjects\vuetify-form-generator\src\components\display-form.vue?rollup-plugin-vue=styles.0.css: Leading decorators must be attached to a class declaration (2:11)

  1 |
> 2 | @font-face {
    |            ^
  3 |   font-family: "Quentin";
  4 |   src: url("./assets/fonts/Quentin.woff2") format("woff2"),
  5 |     url("./assets/fonts/Quentin.woff") format("woff");
src\components\display-form.vue?rollup-plugin-vue=styles.0.css (2:11)
SyntaxError: C:\Dev\PycharmProjects\vuetify-form-generator\src\components\display-form.vue?rollup-plugin-vue=styles.0.css: Leading decorators must be attached to a class declaration (2:11)

In 4.1.4 all works fine. In 4.1.5 and 4.2.0 - no.

Steps to reproduce the behavior

Here is my rollup config

plugins: [
      resolve({
        browser: true,
        jsnext: true,
        preferBuiltins: false,
        extensions: [".js", ".json", ".vue"]
      }),
      commonjs(),
      VuePlugin({
        compileTemplate: true,
        // styleToImports: true,
        css: false,
        template: {
          // styleToImports: true,
          isProduction: opts.env === "production",
          compilerOptions: { preserveWhitespace: false }
        }
      }),
      postcss({
        plugins: []
      }),
      json(),
      babel({
        exclude: "node_modules/**",
        runtimeHelpers: true
      }),
      filesize()
    ]
@aldarund aldarund changed the title Css parsing no longer works since 4.1.5 Css parsing no longer works since 4.1.5 with postcss May 27, 2018
@znck
Copy link
Member

znck commented May 28, 2018

If you set css: false, you have to use a rollup plugin to process styles.

@aldarund
Copy link
Author

But it's there, postcss process it. And it was working before 4.1.5

@znck
Copy link
Member

znck commented May 28, 2018

Okay. I'll look into it and get back to you.

@htmlin
Copy link

htmlin commented Aug 23, 2018

+1

@scrollbar-ww
Copy link

scrollbar-ww commented Aug 25, 2018

there's the code from 'rollup-plugin-postcss' :

    async transform(code, id) {
      let scoped
      if (hasQuery(id)) {
        const query = parseQuery(id)
        scoped = query.scoped
        id = stripQuery(id)
      }

      if (!filter(id) || !loaders.isSupported(id)) {
        return null
      }

the vue plugin extract style code, and put a id like 'xxx.vue?rollup-plugin-vue=styles.0.css',

the query string '?rollup-plugin-vue=styles.0.css' will be killed by the code above

id = stripQuery(id)

then,
loaders.isSupported
return false now...

@objectivehtml
Copy link

objectivehtml commented Nov 1, 2018

Ran into this issue as well. Postcss worked fine in v2.2. I updated to v4 latest and Postcss won't run CSS nano. I can roll back to rollup-plugin-vue v4.1.4 and it works, kinda. Would be good to get an official fix on this so I can update my dependencies in my Rollup boilerplate. Thanks for the plugin.

Without updating the vue rollup plugin, I get errors like this Your current PostCSS version is 6.0.23, but postcss-plugin-purgecss uses 7.0.5. Oder versions of the rollup-plugin-vue require "postcss": "^6.0.22" or lower.

@objectivehtml
Copy link

objectivehtml commented Nov 1, 2018

I spent a few hours digging around in the code for rollup-plugins-vue and rollup-plugins-postcss to figure out what PostCSS wouldn't work with the latest rollup-plugin-vue version. The post above was kinda vague. I've never dug into the code of any build tool, just always installed plugins. So forgive me if this isn't a complete solution. I was going crazy with this not working. Using the information @scrollbar-ww posted, I was able to get my css file to pass through postcss and cssnano.

The issue I found has to do with the resolved id using the extension .vue. Postcss doesn't have a loader for this specifically, so if I specify .vue in the postcss options, it tries to parse the entire vue file and I get an error. Without .vue, it doesn't get passed through postcss. There is also the fact that postcss strips the query string from the id, so that isn't reliable to use a key.

Original code from index.ts

resolveId(id, importer) {
  if (!isVuePartRequest(id)) return
  id = path.resolve(path.dirname(importer), id)
  const ref = parseVuePartRequest(id)
  if (ref) {
    const element = resolveVuePart(descriptors, ref)
    const src = (element as SFCBlock).src
    if (ref.meta.type !== 'styles' && typeof src === 'string') {
      if (src.startsWith('.')) {
        return path.resolve(path.dirname(ref.filename), src as string)
      } else {
        return require.resolve(src, { paths: [path.dirname(ref.filename)] })
      }
    }

    return id
  }
}

My changed code, notice the else if.

resolveId(id, importer) {
  if (!isVuePartRequest(id)) return
  id = path.resolve(path.dirname(importer), id)
  const ref = parseVuePartRequest(id)
  if (ref) {
    const element = resolveVuePart(descriptors, ref)
    const src = (element as SFCBlock).src
    if (ref.meta.type !== 'styles' && typeof src === 'string') {
      if (src.startsWith('.')) {
        return path.resolve(path.dirname(ref.filename), src as string)
      } else {
        return require.resolve(src, { paths: [path.dirname(ref.filename)] })
      }
    }
    else if(ref.meta.type === 'styles') {
        // Replace the .vue extension with a .vue.css so it can pass through
        // PostCSS.
        return id.replace('.vue', '.vue.css');
    }

    return id
  }
}

Here is my relevant rollup plugins config. Note, css() has to go last or else I get no output.

[
    vue({
        css: false,
        defaultLang: {
            style: 'scss'
        }
    }),
    postcss({
        extract: true,
        plugins: [
            cssnano()
        ]
    }),
    css()
]

Original CSS from SampleComponent.vue:

<style lang="scss">
.sample-component {
    background: rgb(200, 200, 200);

    .message {
        font-size: 1rem;
    }
    
    .asd {
        background: yellow;
    }
}
</style>

If I do not include extract: true to Postcss, then I get the following in my CSS file:

var css = ".sample-component{background:#c8c8c8}.sample-component .message{font-size:1rem}.sample-component .asd{background:#ff0}";
export default css;
import styleInject from '{MY_PROJECT_PATH_HERE}/node_modules/style-inject/dist/style-inject.es.js';
styleInject(css);

If I remove my changed code from rollup-plugin-vue my CSS output is unchanged by PostCSS.

.sample-component {
  background: #c8c8c8;
}
.sample-component .message {
    font-size: 1rem;
}
.sample-component .asd {
    background: yellow;
}

/*# sourceMappingURL=SampleComponent.vue.map */

With my change in place, my output is:

.sample-component{background:#c8c8c8}.sample-component .message{font-size:1rem}.sample-component .asd{background:#ff0}

I have no clue about the implications of this for LESS or other preprocessors, if that matters at all. Curious to get your take on this. It was driving my crazy, and I was originally just not going to mess with it, but curiosity and OCD got the better of me. Given this is free software, figured I would do what I could do debug this. Hopefully this helps. Let me know if you have any questions.

@znck
Copy link
Member

znck commented Jan 14, 2019

In the latest release of rollup-plugin-postcss, it honors rollup-plugin-vue query param.

@znck znck closed this as completed Jan 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants