Vue-loader: Vue components css always come before other imported css

Created on 21 Jan 2016  路  10Comments  路  Source: vuejs/vue-loader

Using vue-cli webpack project, if i add the extract text plugin to webpack.base.conf.js like so:

var ExtractTextPlugin = require('extract-text-webpack-plugin');
loaders: [
      { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader') },
      ...

then on my main.js:line 1 i add this:

require('./assets/myfile.css')

and then npm run build

The generated css file has the concated css definitions in this order:

1 - vuecomponents,css
2 - myfile.css

What I'm looking for is to have myfile.css definitions at the beggining of the generated css file (useful for loading bootstrap theme first for example), but so far no chance. Am i missing something or is this a limitiation or issue with vue-loader? Thank you.

Most helpful comment

Okay, here's the reason: you are using require instead of import syntax. According to ES2015 modules spec, import statements are resolved before running your code, so Babel hoists them to the top of your module, and thus the imported modules are evaluated before your CSS require runs.

To fix this simply use import every where - webpack requests can also work with import.

All 10 comments

This is a limitation of the extract text plugin. To change it I will probably have to dig into the plugin's code a bit, but for now it seems the only solution is directly using a separate CSS file in the HTML.

Just did a test and it seems the CSS is extracted in the module import order. Are you requiring the CSS before importing your components?

Yes, this is my current main.js file:

require('expose?$!expose?jQuery!jquery');
require('bootstrap-webpack!../build/bootstrap.config.js');
require('src/assets/font/flaticon.css');

import Vue from 'vue';
import Router from 'vue-router';
....

I will try with again with a fresh vue-cli template tommorow, thank you for your time.

Okay, i actualy tested it with a fresh vue-cli:webpack project and the problem remains:

require('./myfile.css') is added at the top of main.js
App.vue has some css in it.

after compiling with npm run build this is the resulting css:

body{font-family:Helvetica,sans-serif}.outside-css{background-color:#fff}

where body{} is the component css, and outside-css{} is the required css file.

So far I am not able to place css files before vue components css, am I doing something wrong or is this a limitiation with the extract text plugin?
The project sc is at:

https://gitlab.com/prog4mr/vue_loader.138

Thank you

Okay, here's the reason: you are using require instead of import syntax. According to ES2015 modules spec, import statements are resolved before running your code, so Babel hoists them to the top of your module, and thus the imported modules are evaluated before your CSS require runs.

To fix this simply use import every where - webpack requests can also work with import.

Perfect, thank you, no way i would figure that soon.

Thanks @yyx990803 again, I solve my problem.

the CSS is extracted in the module import order

Here is my solution, I paste here for anyone who may need:

// App.vue
import 'bootstrap/dist/css/bootstrap.min.css'
import 'font-awesome/css/font-awesome.min.css'
import '@/assets/css/main.css'

Style for a single component, just write them between <style scoped> tag

@yyx990803 when build 锛孋ss import in main.js after Css in *.vue how to deel with this?

@Zalezale i got the same issue after upgrading from vue-loader 14.2.2 to 15.2.1. I also import css files in the main vue component which will be imported after the styles from child components. But i got no solution

Was this page helpful?
0 / 5 - 0 ratings