Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack not loading Vue's single file components CSS

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(),
  ]
};
like image 936
Daniel L Avatar asked Sep 07 '20 00:09

Daniel L


3 Answers

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!

like image 159
MvRens Avatar answered Nov 20 '22 04:11

MvRens


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.

like image 23
seiluv Avatar answered Nov 20 '22 03:11

seiluv


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

  • in webpack.config.js
    • Add esModule: false to css-loader's option. (as @MvRens's answer)
    • Change vue-style-loader to style-loader in webpack.config.js. (as @seiluv's answer)
  • in package.json
    • Add "*.vue" to {sideEffects: []}
      • See: https://github.com/vuejs/vuepress/issues/718#issuecomment-412345448 and https://stackoverflow.com/a/53737250/493168
like image 3
kaorukobo Avatar answered Nov 20 '22 03:11

kaorukobo