9

Webpack is compiling single file components but not loading CSS. The HTML and Vue is rendered correctly but without CSS. It seems to be an issue with webpack configuration. Any idea what's wrong?

I'm using webpack-dev-server to load the development server.

src/index.html

<html>
<head>
    <title>Vue Hello World</title>
</head>
<body>
    <h1>Header</h1>
    <div id="app"></div>
</body>
</html>

src/Hello.vue

<template>
  <p>{{ greeting }} Test!</p>
</template>

<script>
module.exports = {
  data : function () {
      return {
          greeting: 'Hello'
        }
    }
}
</script>

<style scoped>
  p {
    font-size: 18px;
    font-family: 'Roboto', sans-serif;
    color: blue;
  }
</style>

src/main.js

import Vue from 'vue';
import Hello from './Hello.vue';

new Vue({
    el: '#app',
    render: h => h(Hello),
  });

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/,  exclude: /node_modules/, use: 'babel-loader' },
      { test: /\.vue$/, exclude: /node_modules/, use: 'vue-loader' },
      { test: /\.css$/, exclude: /node_modules/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
  ]
};
Daniel L
  • 91
  • 1
  • 2
  • Any reason you're not using Vue CLI? – Phil Sep 07 '20 at 00:59
  • As per [the documentation](https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles), scoped CSS is achieved by using PostCSS. With that in mind, have you [configured PostCSS](https://vue-loader.vuejs.org/guide/pre-processors.html#postcss)? – Phil Sep 07 '20 at 01:03
  • I think postCSS is not the issue, I've added it via npm and added to webpack css chain and still doesn't work. It must be something with webpack configuration because when running vue-cli-service it does work. I'm not using Vue CLI becaue when you init a project it adds a lot of packages and complex configuration. It should be easier to just start a simple "Hello World" project. – Daniel L Sep 07 '20 at 11:10
  • 1
    While I don't agree with your analysis of Vue CLI, I respect your opinion. One thing you can try though is to set up an empty project with Vue CLI and then run `vue inspect > config.js` to dump the generated Webpack config. Then at least you might be able to see what you're missing – Phil Sep 07 '20 at 22:02
  • Just as a note... today `postcss` is bundled with `@vue/compiler-sfc` and you do *not* need to configure it at all to get scoped CSS with `vue-loader`. – Robert Dec 05 '21 at 12:26

3 Answers3

28

I just spent the last 4 hours figuring this out. I wanted to use only Webpack because it integrates much nicer into my Gulp pipeline than Vue CLI does. Not sure what version of css-loader you're on and if it's the same cause, but hope this helps you out as well.

TL;DR: instead of just 'css-loader', use:

{
  loader: 'css-loader',
  options: {
    esModule: false
  }
}

I use SCSS which has the same problem, but for your example that would be:

{ test: /\.css$/, exclude: /node_modules/, use: ['vue-style-loader', { loader: 'css-loader', options: { esModule: false }}]}

I'm not sure if this is a proper solution or just a workaround. I figured this out because I had an old project that worked before, but as soon as I upgraded all packages it failed. Eventually I traced it down to css-loader, which was version 2.1 before and 4.3 after the update. It worked up to version 3.6, then with 4.0 it failed. Then I just tried toggling the various options and this was the one that fixed it (I never claimed to know what I was doing ;-)).

Edit: seiluv added a link to a comment on vue-style-loader's Github that confirms this as a workaround. It was apparantly posted a month before, but I did not find it in my search for an answer. Thanks seiluv!

MvRens
  • 381
  • 2
  • 5
13

I encountered the same problem, so either :

Use style-loader instead of vue-style-loader

As suggested here.

use: ['style-loader', 'css-loader']

Basically the upgrade to css-loader 4.x.x + doesn't work well with vue-style-loader.

or

Disable css-loader's esModule option

The solution by MvRens is also valid and confirmed by this comment on github.

The problem is css-loader's esModule is set to true by default and should be false in this case.

seiluv
  • 151
  • 5
4

In addition to the above two answers, here sum up the possible solutions including the new one -- sideEffects. Please edit the list if someone can improve it.

Possible Solutions

kaorukobo
  • 2,223
  • 2
  • 22
  • 29
  • Happy to be the first up-vote for you. Mention of sideEffects was critical for me! Thanks – Robert Dec 05 '21 at 12:19
  • I currently have all 3 suggested workarounds applied. None of them work for me, unfortunately. – Jay Oct 12 '22 at 21:28