8

I have a rails app that I have upgraded to use webpacker 4.x and everything works fine on development but in production Vue single file components styles are not rendered, js works fine and even some styles from components (vue-slider-component for example) display correctly. I was using webpacker 3 before and things were working fine but the app started to become really slow on development and decided to migrate to a new webpacker.

An important note is that I'm using sass (scss) styles in my vue components.

Here is my config:

// config/webpack/environment.js
const { environment } = require('@rails/webpacker');
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const vue = require('./loaders/vue');
const sass = require('./loaders/sass');

environment.config.resolve.symlinks = false;

environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin());
environment.loaders.append('vue', vue);
environment.loaders.append('sass', sass);
const nodeModulesLoader = environment.loaders.get('nodeModules');

nodeModulesLoader.exclude = [nodeModulesLoader.exclude, /mapbox-gl/];

environment.config.resolve.alias = {
  vue$: 'vue/dist/vue.esm.js',
  '@': path.join(__dirname, '..', '..', 'app', 'javascript'),
  '@stylesheets': path.join(__dirname, '..', '..', 'app', 'assets', 'stylesheets'),
  '@javascripts': path.join(__dirname, '..', '..', 'app', 'assets', 'javascripts'),
  '@node_modules': path.join(__dirname, '..', '..', 'node_modules')
};
module.exports = environment;

// config/webpack/production.js
process.env.NODE_ENV = process.env.NODE_ENV || 'production'

const environment = require('./environment')

module.exports = environment.toWebpackConfig()
// config/webpack/loaders/vue.js
module.exports = {
  test: /\.vue(\.erb)?$/,
  use: [
    {
      loader: 'vue-loader',
    },
  ],
};

I wonder if loaders/sass.js is the reason

// config/webpack/loaders/sass.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const { extract_css: extractCSS } = require('@rails/webpacker').config;

module.exports = {
  test: /\.(scss|sass|css)$/i,
  use: [extractCSS ? MiniCssExtractPlugin.loader : 'vue-style-loader', 'css-loader', 'sass-loader'],
};

# config/webpacker.yml

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
  cache_path: tmp/cache/webpacker
  check_yarn_integrity: false
  webpack_compile_output: false

   # Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: []

  # Reload manifest.json on all requests so we reload latest compiled packs
  cache_manifest: false

  # Extract and emit a css file
  extract_css: false

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2

  extensions:
    - .js
    - .vue
    - .sass
    - .scss
    - .css
    - .module.sass
    - .module.scss
    - .module.css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg

development:
  <<: *default

  check_yarn_integrity: false

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: localhost
    port: 3035
    public: localhost:3035
    hmr: true
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    compress: true
    disable_host_check: true
    use_local_ip: false
    quiet: false
    headers:
      'Access-Control-Allow-Origin': '*'
    watch_options:
      ignored: '**/node_modules/**'

test:
  <<: *default
  compile: true

  # Compile test packs to a separate directory
  public_output_path: packs-test

production:
  <<: *default

  # Production depends on precompilation of packs prior to booting for performance.
  compile: true

  # Extract and emit a css file
  extract_css: true


  # Cache manifest.json for performance
  cache_manifest: true

3
  • did you find any solution? i'm facing the very same problem... Commented Sep 7, 2019 at 21:56
  • No, I have tried and searched. Commented Sep 25, 2019 at 14:45
  • well my problem was that commonChunks plugin was creating 'common.css' file that was not included in the view. After adding common.css link everything works as expected Commented Sep 25, 2019 at 15:02

3 Answers 3

5

Try to include <%= stylesheet_pack_tag 'application', media: 'all' %> on your root HTML file.

based on: https://github.com/rails/webpacker/issues/987

Sign up to request clarification or add additional context in comments.

Comments

1

In production css are extracted to their own files (extract_css: true). Make sure webpacker is able to parse the css in vue single file components and generate the necessary files. You need to modify vue-loader config:

// config/webpack/loaders/vue.js
module.exports = {
  test: /\.vue(\.erb)?$/,
  use: [
    {
      loader: 'vue-loader',
      options: {
        loaders: {
          'scss': 'vue-style-loader!css-loader!sass-loader',
          'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
        }
      }
    },
  ],
}

To confirm the files are generated successfully, check manifest.json in production. You should find the entries to all the js and css files.

Secondly, make sure you're requiring the css files by using stylesheet_pack_tag

Comments

0

Vue templates require loading the stylesheet in your application in order for CSS to work. This is in addition to loading the JavaScript file for the entry point. Loading the stylesheet will also load the CSS for any nested components. https://github.com/rails/webpacker/issues/987#issuecomment-341903345

<%= stylesheet_pack_tag 'hello_vue' %> 
<%= javascript_pack_tag 'hello_vue' %>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.