vuejs-templates / webpack

A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Autoprefixer is only active for .vue files

fvsch opened this issue · comments

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.

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

commented

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

Note: need to yarn add postcss-loader -D

qq20170317-094519

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!

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.

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.

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

@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.

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

@cycold I tried the solution but did not work
image

anyone can help? tks

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.

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

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

Ah then it is broken in v1.2.1

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

Yes that fixes it!

Discussion of css-loader's importLoaders option

Thanks. Will apply that PR tonight hopefully.

@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
    }
}

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

vuejs/vue-loader#1055

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

commented

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.

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!

this code maybe had other problem , i not kook at