Skip to content

FOUC with Webpacker 4.0.0.pre.pre.2 and webpack-dev-server with HMR: true #1542

Closed
@mikeappell

Description

@mikeappell

I'm getting a flash of unstyled content whenever I reload a page in the most current version of Webpacker 4.x.

I'm mostly using the vanilla config; however, as far as I can tell this takes into account hmr being enabled and switches to style-loader from mini-css-extract-plugin. It's worth mentioning that this is an upgrade from Webpacker v3.5 to 4; I did run rails webpacker:install after the upgrade.

Here's my config:

# Gemfile.lock
webpacker (4.0.0.pre.pre.2)

...

# package.json
"dependencies": {
    "@rails/webpacker": "4.0.0-pre.2",
    "autoprefixer": "^8.5.1",
    "babel-loader": "^7.1.4",
    "bootstrap-sass": "^3.3.7",
    "case-sensitive-paths-webpack-plugin": "^2.1.2",
    "clean-webpack-plugin": "^0.1.19",
    "compression-webpack-plugin": "^1.1.11",
    "css-hot-loader": "^1.3.9",
    "css-loader": "^0.28.11",
    "file-loader": "^1.1.11",
    "font-awesome": "^4.7.0",
    "jquery": "^3.3.1",
    "jquery-ujs": "^1.2.2",
    "mini-css-extract-plugin": "^0.4.0",
    "moment": "^2.22.1",
    "node": "^10.2.0",
    "node-sass": "^4.9.0",
    "popper.js": "^1.14.3",
    "postcss-loader": "^2.1.5",
    "precss": "^3.1.2",
    "resolve-url-loader": "^2.3.0",
    "sass-loader": "^7.0.1",
    "style-loader": "^0.21.0",
    "uglifyjs-webpack-plugin": "^1.2.5",
    "url-loader": "^1.0.1",
    "webpack-manifest-plugin": "^2.0.3",
    "webpack-merge": "^4.1.2"
"devDependencies": {
    "webpack-cli": "^2.1.4",
    "webpack-dev-server": "^3.1.4"

...

# webpacker.yml
default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
  cache_path: tmp/cache/webpacker

  # Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: ['vendor/assets/javascripts', 'vendor/assets/stylesheets', 'public/javascripts', 'public/assets/images']

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

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

development:
  <<: *default
  compile: true

  # 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: &test
  <<: *default

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

production: &production
  <<: *default

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

  # Cache manifest.json for performance
  cache_manifest: true

staging:
  <<: *production

qa:
  <<: *production

integration:
  <<: *production

...
  
# environment.js
const { environment } = require('@rails/webpacker')
const { env } = require('process')
const { resolve } = require('path');
const rootPath = resolve(__dirname, '../..');
 
const CleanWebpackPlugin = require('clean-webpack-plugin');

const fileLoader = environment.loaders.get('file');
fileLoader.use = [
  {
    loader: 'url-loader',
    options: {
      name: '[path][name]-[hash].[ext]',
      limit: 10000,
      context: 'app/assets',
    }
  }
]
fileLoader.test = /\.(jpg|jpeg|png|gif|tiff|ico|svg)$/i

environment.loaders.append('font', {
  test: /\.(eot|otf|ttf|woff|woff2)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        name: '[path][name]-[hash].[ext]',
        limit: 10000,
        context: 'node_modules',
      }
    }
  ]
})

const pathsToClean = [
  'packs',
  'packs-test'
]
const cleanOptions = {
  root: resolve(rootPath, 'public'),
  verbose: true,
}
if (env.NODE_ENV !== 'test') environment.plugins.insert('CleanWebpackPlugin', new CleanWebpackPlugin(pathsToClean, cleanOptions));

module.exports = environment

development.js is vanilla. I'm aware I've a lot of dependencies I can remove from package.json (mostly from playing around with an earlier version of Webpacker) but I assume they're not at fault here.

Apologies if this isn't a ton of info to go on, and am happy to provide anything required. Kudos =)


Edit a day or so later:

I'm going to add a bit to this. When I set hmr and inline to false and have webpack-dev-server running, I had expected to begin seeing the CSS without the flash of unstyled content at the beginning. Instead, I'm never seeing my compiled css and the page remains unstyled.

I'd guess this is somehow due to a misconfiguration on my part with Webpacker; however, I'd have nonetheless expected the default configuration of Webpacker to be close enough to optimal to not require much tinkering on my part, so I'm mentioning this here. I am, of course, also curious what I'm doing wrong 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions