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:
- 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}
- 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}
- 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.)
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
andstyle-loader
, but before other preprocessor loaders like e.gsass|less|stylus-loader
, if you use any.
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"
.
fixed by adding postcss-loader for all *.*css files as well.
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