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

Autoprefixer is only active for .vue files #600

Closed
fvsch opened this issue Mar 15, 2017 · 23 comments · Fixed by #890
Closed

Autoprefixer is only active for .vue files #600

fvsch opened this issue Mar 15, 2017 · 23 comments · Fixed by #890

Comments

@fvsch
Copy link

fvsch commented Mar 15, 2017

This seems to be the same bug as #85, which was closed because, I quote, "Autoprefixer is in the latest template release", but we don't get Autoprefixer working for CSS or SCSS files outside of .vue components.

Steps to reproduce:

vue init webpack postcss-test && cd postcss-test
npm install
npm install node-sass sass-loader --save-dev

Then create a few test stylesheets:

/* src/assets/test1.css */
.test1 { display: flex; }
// src/assets/test2.scss
.test2 { display: flex; }

Finally, let's test a few ways to load these:

  1. As entry points:
// build/webpack.base.conf.js
...
module.exports = {
  entry: {
    app: './src/main.js',
    test1: './src/assets/test1.css',
    test2: './src/assets/test2.scss'
  },
  ...
}

Then npm run build. Results:

/* dist/static/css/test1.ca0cd0e2b1b09d965f5ce5c21f1fc6e7.css */
.test1{display:flex}

/* dist/static/css/test2.4d716aeffa93f62596ef617b3129561c.css */
.test2{display:flex}
  1. As JS imports:
<!-- src/App.vue -->
<script>
import {} from './assets/test1.css'
import {} from './assets/test2.scss'
...
</script>

(Remove the entry points test before.) Then npm run build. Result:

/* dist/static/css/app.4006533b8ed715dfd365cdd7a0b4f7be.css */
.test1,.test2{display:flex}
  1. In style tags in components:
<!-- src/App.vue -->
<style>
@import './assets/test1.css';
.test1b { display: flex; }
</style>

<style lang="scss">
@import './assets/test2.scss';
.test2b { display: flex; }
</style>

Result:

/* dist/static/css/app.6c438b7dca17522bb707d18112b8cbcb.css */
.test1{display:flex}.test1b,.test2,.test2b{display:-webkit-box;display:-ms-flexbox;display:flex}

Conclusion: Autoprefixer is only used for style tags inside .vue components.
When using Sass or SCSS syntax and an external Sass/SCSS stylesheet, this can be used to apply Autoprefixer to code stored outside of components; the same trick does not work for CSS imports.

Was #85 closed based on a faulty assumption?

As a side note, debugging this issue proved difficult (for several team members) because this template comes with references to autoprefixer and postcss in two locations:

  • package.json -> "browserslist" entry
  • .postcssrc.js

But the config in config and build never references these locations, postcss or autoprefixer. It's all happening by magic, but only in very limited settings.

Maybe the brower list and postcss config should be moved to build/vue-loader.conf.js, if it only applies to vue-loader? As it is, it's sending the message that it's a project-wide config, but in practice it doesn't seem to be.

@fvsch
Copy link
Author

fvsch commented Mar 15, 2017

Possible duplicate of: #544
(I don't read Chinese but it seems similar.)

@cycold
Copy link

cycold commented Mar 17, 2017

Yeah, I have the problem too. I have to add postcss-loader to loaders

Note: need to yarn add postcss-loader -D

qq20170317-094519

@matheusgrieger
Copy link

Got this problem as well. Importing any SCSS file, though loads them correctly, does not autoprefix them.

But above solution by @cycold works like a charm, thank you!

@ozguruysal
Copy link

Yes the solution from @cycold works great. However you get a warning pointing to https://github.com/postcss/postcss-loader#sourcemap if you have sourceMap set to false in config/index.js that is the default setting.

Would be nice if this feature came out of the box as it's kinda expected result.

@KagamiChan
Copy link
Contributor

KagamiChan commented Jun 22, 2017

In @cycold 's code other loaders are pushed to the loaders array, resulting something like [cssLoader, postcssLoader, ...otherStyleLoader], so I try inserting postcssLoader at last place.

EDIT: my code is not correct.

@ghost
Copy link

ghost commented Jul 21, 2017

Any further developments to this? I have to suppport IE10.... :(
Getting the same sourcemap issues as @cycold has stated.

@gluons
Copy link

gluons commented Sep 24, 2017

@KagamiChan Your code seems incorrect. @cycold is right. postcss-loader shouldn't be added at the last.

From postcss-loader's docs:

Use it after css-loader and style-loader, but before other preprocessor loaders like e.g sass|less|stylus-loader, if you use any.

@KagamiChan
Copy link
Contributor

KagamiChan commented Sep 25, 2017

@gluons agreed, you're right, edited my code

@hanzhenlong
Copy link

@cycold I tried the solution but did not work
image

anyone can help? tks

@diachedelic
Copy link

diachedelic commented Nov 14, 2017

I ran vue init webpack my-project just now, and was able to reproduce @fvsch 's 3rd example:

<!-- src/App.vue -->
<style>
@import './assets/test1.css';
.test1b { display: flex; }
</style>

<style lang="scss">
@import './assets/test2.scss';
.test2b { display: flex; }
</style>

Result:

.test1{
  display:flex
}

.test1b,
.test2,
.test2b{
  display:-webkit-box;
  display:-ms-flexbox;
  display:flex
}

This is an issue for using 3rd party Vue components which import plain css.

@LinusBorg
Copy link
Contributor

Hm, that's weird. Postcss is active for .css files since yesterday, so airport fixer should be applied. I will check this out.

@LinusBorg LinusBorg reopened this Nov 14, 2017
@LinusBorg LinusBorg self-assigned this Nov 14, 2017
@diachedelic
Copy link

diachedelic commented Nov 14, 2017 via email

@LinusBorg
Copy link
Contributor

We didn't properly version for the longest time, but recently started adding a version number to the top of /config/index.js

@diachedelic
Copy link

Ah then it is broken in v1.2.1

@LinusBorg
Copy link
Contributor

LinusBorg commented Nov 14, 2017

I have a suspicion, but can't verify until tonight. However I already made a PR that aims to solve this or something related.

https://github.com/vuejs-templates/webpack/pull/1053/files

You might try to give this a spin. The PR itself is also not thoroughly tested et (it's WIP), but maybe it just works :-P

@diachedelic
Copy link

Yes that fixes it!

Discussion of css-loader's importLoaders option

@LinusBorg
Copy link
Contributor

Thanks. Will apply that PR tonight hopefully.

@kirkgrover
Copy link

@ozguruysal and @tfsimondouglas, I was getting the same sourcemap warning. Building on @cycold's solution, you can get the warning to go away by adding the sourceMap option to postcssLoader in utils.js:

var postcssLoader = {
    loader: 'postcss-loader',
    options: {
        sourceMap: options.sourceMap
    }
}

@blake-newman
Copy link
Contributor

Additionally there is this PR for vue-loader that solves the use of lang="postcss".

vuejs/vue-loader#1055

@LinusBorg
Copy link
Contributor

fixed by adding postcss-loader for all *.*css files as well.

@adi518
Copy link
Contributor

adi518 commented Feb 25, 2018

I'm using an old version of the template that has this issue and it seemed really peculiar, because I noticed CSS within an SFC style tag gets prefixed, but postcss-loader is not to be found in the template's dependencies. Further investigating revealed that css-loader includes postcss in its dependencies and probably auto invokes it if browserslist is present in your package.json, thus auto-prefixing the CSS as expected. All, but SCSS files imported in a script tag (and perhaps other, similar import variations). From this closed issue, I can only deduce postcss-loader has to be explicit for a complete, multi import-scenario solution.

@zzk220106
Copy link

const postcssLoader = {
loader: 'postcss-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}

// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = [cssLoader, postcssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}

eg: my code did not work, help tks!

@zzk220106
Copy link

this code maybe had other problem , i not kook at

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

Successfully merging a pull request may close this issue.