Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot Reload plan? #34

Closed
alamchrstn opened this issue Mar 12, 2018 · 37 comments
Closed

Hot Reload plan? #34

alamchrstn opened this issue Mar 12, 2018 · 37 comments

Comments

@alamchrstn
Copy link

is there any plan for supporting hot reload yet?

@sokra
Copy link
Member

sokra commented Mar 12, 2018

There is a plan, but not implemented yet.

Eventually this plugin will support HMR.

@alamchrstn
Copy link
Author

@sokra awesome will look forward to it. I'm having issue with bundling css at the moment with webpack 4, it's unable to read the changes that I make on the fly even if I try to reload the page. The bundled css seems to still take the old css modules (initial bundle, before the changes were saved). Can I get any help from here? Thanks in advance.

@VictorKolb
Copy link

@alamchrstn #23 here a same issue

@krtr
Copy link

krtr commented Mar 12, 2018

btw, you can still use style-loader in development, so it is not a blocker in any way

@alamchrstn
Copy link
Author

@krtr thanks for the suggestion. could you please give an example? I'm also using other plugins and loaders as well (including isomorphic and HMR). I'm quite new to webpack so yeah I guess a little bit of guidance and example would be very helpful for me. Thanks once again!

@krtr
Copy link

krtr commented Mar 12, 2018

@alamchrstn sure,
here is my webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: './src/index.tsx',
    mode: "development",
    devtool: 'inline-source-map',
    resolve: {
        extensions: [".js", ".ts", ".tsx"]
    },
    output: {
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'awesome-typescript-loader'
            },
            {
                test: /\.scss/,
                use: [
                    // MiniCssExtractPlugin.loader,
                    "style-loader",
                    {
                        loader: "css-loader",
                        options: {
                            module: true
                        }
                    },
                    "sass-loader"
                ]
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {}
                    }
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            // Options similar to the same options in webpackOptions.output
            // both options are optional
            filename: "[name].css",
            chunkFilename: "[id].css"
        })
    ],

    serve:
        {
            content: "./src",
            open: true,
        }
};

@alamchrstn
Copy link
Author

@krtr thank you so much! will try to use it and will let you know if I'm having issues 😄

@alamchrstn
Copy link
Author

@krtr can I use CSS modules with this?

@alamchrstn
Copy link
Author

alamchrstn commented Mar 12, 2018

well might as well put my config right, so here it is

import webpack from 'webpack'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import CleanPlugin from 'clean-webpack-plugin'
import { ReactLoadablePlugin } from 'react-loadable/webpack'
import { SRC, APP, STATIC, CONFIG, STYLES, SERVER, ROOT, LOADABLE } from 'configs/paths'
import { isomorphicPlugin } from 'server/isomorphic-tools'

export default {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    entry: {
        imagesearch: [
            'babel-polyfill',
            `${STYLES}/main.css`,
            `${APP}/entries/image-search/index.js`,
            'webpack-hot-middleware/client'
        ]
    },
    output: {
        filename: '[name].[hash].js',
        path: STATIC,
        publicPath: '/'
    },
    resolve: {
        modules: [ SRC, STYLES, 'node_modules' ],
        extensions: [
            '.js', '.jsx', '.css', '.scss'
        ],
    },
    plugins: [
        isomorphicPlugin,
        new webpack.NoEmitOnErrorsPlugin(),
        new CleanPlugin([ 'src/static' ], {
            root: ROOT
        }),
        new webpack.DefinePlugin({
            'process.env': {
                'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
                'DEBUG': JSON.stringify(process.env.DEBUG),
                'APP_ENV': JSON.stringify('browser')
            }
        }),
        new MiniCssExtractPlugin({
            filename: "[name].[hash].css",
            chunkFilename: "[id].css"
        }),
        new ReactLoadablePlugin({
            filename: LOADABLE
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
            filename: 'head'
        }
    },
    module: {
        rules: [
            {
                test: isomorphicPlugin.regular_expression('images'),
                loader: 'url-loader',
                options: { limit: 10240 }
            },
            {
                test: /\.woff2?(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'url-loader',
                options: { limit: 10000, mimetype: 'application/font-woff' }
            },
            {
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'url-loader',
                options: { limit: 10000, mimetype: 'application/octet-stream' }
            },
            {
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'file-loader'
            },
            {
                test: /module\.s?css$/,
                include: [ SRC ],
                use: [
                    'style-loader',
                    // MiniCssExtractPlugin.loader,
                    { 
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            localIdentName: '[path][name]-[local]'
                        }
                    },
                    { loader: 'postcss-loader' }
                ]
            },
            {
                test: /\.s?css$/,
                include: [ SRC ],
                exclude: /module\.s?css$/,
                use: [
                    'style-loader',
                    // MiniCssExtractPlugin.loader,
                    { loader: 'css-loader' },
                    { loader: 'postcss-loader' }
                ]
            },
            {
                test: /\.jsx?$/,
                include: [ APP, CONFIG, SERVER ], 
                // exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: [
                        [ 'env', {
                            targets: { browsers: [ 'last 2 versions' ] },
                            modules: false
                        } ],
                        'react'
                    ],
                    plugins: [
                        'dynamic-import-webpack',
                        'transform-export-extensions',
                        'transform-decorators-legacy',
                        'transform-class-properties',
                        'transform-object-rest-spread',
                        'add-module-exports',
                        'lodash',
                        'ramda',
                        'react-require',
                        [ 'provide-modules', {
                            'debug': 'debug'
                        } ],
                        "babel-plugin-root-import",
                        'extract-hoc/babel',
                        'react-hot-loader/babel'
                    ]
                }
            }
        ]
    }
}

I have an import of css module inside my image-search app script as well. The main global css is from the main.css

@alexander-akait
Copy link
Member

PR welcome 👍

@tim-soft
Copy link

Looking forward to HMR!

@OzzyCzech
Copy link

There is nice workaround with https://github.com/shepherdwind/css-hot-loader

First detect HMR state:

const isHot = path.basename(require.main.filename) === 'webpack-dev-server.js';

Configure rule:

// ...
{
  test: /\.(less|css)$/,
   use: [
     'css-hot-loader',
     MiniCssExtractPlugin.loader,
     'css-loader',
     'less-loader'
    ]
},
// ...

Setup css filename (there is a limitation in css-hot-loader see https://github.com/shepherdwind/css-hot-loader#attention)

new MiniCssExtractPlugin({
   filename: isHot ? 'css/[name].css' : 'css/[name].[contenthash].css',
   chunkFilename: 'css/[id].css'
}),

@alexander-akait
Copy link
Member

@OzzyCzech Can you send PR to implement this feature, looks it is not hard

@OzzyCzech
Copy link

or maybe @shepherdwind can help us with that

@devanflaherty
Copy link

devanflaherty commented Apr 5, 2018 via email

@Bnaya
Copy link

Bnaya commented Apr 5, 2018

@devanflaherty that what's i do :P

@devanflaherty
Copy link

@Bnaya : What are you doing to disable it?
Extract Text Plugin had an option to 'disable' and I haven't seen that in the docs.

@sorcal
Copy link

sorcal commented Apr 5, 2018

@devanflaherty you're right, that solution works in simple case (when you just need to create 1 css file). However, I couldn't make it working when I needed just a part of css bundle.

@sorcal
Copy link

sorcal commented Apr 5, 2018

What are you doing to disable it?

@devanflaherty, I just removed MiniCssExtractPlugin from webpack plugins and replaced MiniCssExtractPlugin.loader with 'style-loader' in rules

@Bnaya
Copy link

Bnaya commented Apr 5, 2018

More or less:

module.exports = async function(envCliArgs = {}, argv = {}) {
  const isHot = !!argv.hot || !!argv.hotOnly;
          use: [
            {
              loader: isHot ? "style-loader" : MiniCssExtractPlugin.loader,
            },
  if (!isHot) {
    config.plugins.push(
      new MiniCssExtractPlugin({
        filename: "[name].bundle.[chunkhash].css",
        chunkFilename: "[id].[chunkhash].css",
      }),
    );
  }

@leebenson
Copy link

Is there any plan to make this plugin directly compatible with style-loader?

In my Launch.js CSS/Sass/Less/PostCSS preset, I'm using Mini-CSS-Extract to extract styles via the client config, along with css-hot-loader on top of it to push hot reloads.

I could put this inside the server config and just leave the client config to use style-loader, but that breaks the general model I've employed with Launch.js to have presets use the client config when bundling stuff that will ultimately wind up in a public folder.

The limitation with using css-hot-loader is that the compiled .css must be loaded in the resulting SSR HTML first, whereas style-loader obviously embeds the styles directly in the resulting .js entry chunk, making it useful to test in scenarios where a SSR hasn't been provided.

armaanahluwalia added a commit to armaanahluwalia/zulip that referenced this issue May 2, 2018
This commit removes the flash on unstyled content while in dev
mode that was caused by the use of style-loader. Instead it
enables mini-css-extract-plugin in dev in combination with
css-hot-loader which enables HMR for development.

This is because mini-css-extract-plugin does not currently support
HMR out of the box. It also adds a SourceMapDevtoolPlugin to enable
sourcemaps with css since mini-css breaks sourcemaps when used in
combination with the cheap-module-evel-source-map setting.

Related issues:
webpack-contrib/mini-css-extract-plugin#34
webpack-contrib/mini-css-extract-plugin#29
armaanahluwalia added a commit to armaanahluwalia/zulip that referenced this issue May 2, 2018
This commit removes the flash on unstyled content while in dev
mode that was caused by the use of style-loader. Instead it
enables mini-css-extract-plugin in dev in combination with
css-hot-loader which enables HMR for development.

This is because mini-css-extract-plugin does not currently support
HMR out of the box. It also adds a SourceMapDevtoolPlugin to enable
sourcemaps with css since mini-css breaks sourcemaps when used in
combination with the cheap-module-evel-source-map setting.

Related issues:
webpack-contrib/mini-css-extract-plugin#34
webpack-contrib/mini-css-extract-plugin#29
timabbott pushed a commit to zulip/zulip that referenced this issue May 3, 2018
This commit removes the flash on unstyled content while in dev
mode that was caused by the use of style-loader. Instead it
enables mini-css-extract-plugin in dev in combination with
css-hot-loader which enables HMR for development.

This is because mini-css-extract-plugin does not currently support
HMR out of the box. It also adds a SourceMapDevtoolPlugin to enable
sourcemaps with css since mini-css breaks sourcemaps when used in
combination with the cheap-module-evel-source-map setting.

Related issues:
webpack-contrib/mini-css-extract-plugin#34
webpack-contrib/mini-css-extract-plugin#29
shubham-padia pushed a commit to shubham-padia/zulip that referenced this issue May 27, 2018
This commit removes the flash on unstyled content while in dev
mode that was caused by the use of style-loader. Instead it
enables mini-css-extract-plugin in dev in combination with
css-hot-loader which enables HMR for development.

This is because mini-css-extract-plugin does not currently support
HMR out of the box. It also adds a SourceMapDevtoolPlugin to enable
sourcemaps with css since mini-css breaks sourcemaps when used in
combination with the cheap-module-evel-source-map setting.

Related issues:
webpack-contrib/mini-css-extract-plugin#34
webpack-contrib/mini-css-extract-plugin#29
brickbite pushed a commit to brickbite/zulip that referenced this issue May 29, 2018
This commit removes the flash on unstyled content while in dev
mode that was caused by the use of style-loader. Instead it
enables mini-css-extract-plugin in dev in combination with
css-hot-loader which enables HMR for development.

This is because mini-css-extract-plugin does not currently support
HMR out of the box. It also adds a SourceMapDevtoolPlugin to enable
sourcemaps with css since mini-css breaks sourcemaps when used in
combination with the cheap-module-evel-source-map setting.

Related issues:
webpack-contrib/mini-css-extract-plugin#34
webpack-contrib/mini-css-extract-plugin#29
@ScriptedAlchemy
Copy link
Contributor

ScriptedAlchemy commented Jun 4, 2018

Hey guys, Im going to open a PR for HMR support, I've currently got it working on my local machine. <3

It'll be proper HMR, no style-loader injecting strings back into the page. Real CSS files :)

@anthonyhastings
Copy link

Sounds great @zackljackson! This feature is my only block from moving away from ExtractTextPlugin to the best of my knowledge.

applefreak added a commit to applefreak/choo-express-ssr that referenced this issue Jun 15, 2018
@yantakus
Copy link

@ScriptedAlchemy, any news on the PR?

@ScriptedAlchemy
Copy link
Contributor

@yantakus @anthonyhastings currently have it released under one of the React Universal umbrellas

https://www.npmjs.com/package/extract-css-chunks-webpack-plugin

If theres a desperate need - use that, mini-css doesn't play nicely with Facebooks CRA async hooks. So my focus is to bring facebook back as a dependency (they used me up till webpack 4) which also means supporting async tapping out of context.

It seems to be working just fine with my Universal community - had about 100k new downloads added & nobody having much problems

@alexander-akait
Copy link
Member

alexander-akait commented Jun 25, 2018

@ScriptedAlchemy why require implement new extract plugin? You can send PRs and use official plugin

@ScriptedAlchemy
Copy link
Contributor

Yeah but I have my own infrastructure im worried about. mini-css is a stop-gap for future native webpack based style handling, you guys probably already have this problem solved for WP5

Ive got my own ecosystem and a lot of dependents to look after under it. I just wanted HMR so I built it, my changes might not fit Webpacks plans and this plugin isn't under active development, or doesn't seem to be, the PRs dont seem to move quickly either... likely for good reasons, I have no doubt.

If I were closer to the internal Webpack community / a member of some Webpack affiliated groups - id probably focus significently on Webpack architecture. But being out the loop & relatively disconnected from the plans or actions of Webpack means it sounds like more red tape to wade through.

Love Webpack and would love to maintain it / help maintain it. Especially given my enterprise architectural background, but life is much easier as a collaborator .vs contributor.

The group I work with currently, I am part of the internal team - so I can design things geared toward future implementations. Knowing little about Webpack 5 & having no influence whatsoever within the Webpack community means it serves me better to engineer my own solutions where I am well informed of my own roadmaps.

As of right now, all I know is Webpack 5 will handle CSS. I invest into teams I have the privilege to work internally with / be informed as an internal level member.

CSS is a relatively small task, I am currently working on some far larger changes around build orchestration. Im able to trick and hook into Webpack enough to pull off most of what I need, but at some point ill have to start opening pull requests to its core - perhaps at that point in time Ill look at a bundled update.

Dont mean to be rude about it, and I really love the work the Webpack team does, and I'd love to contribute in some meaningful way. But I dont know the roadmaps beyond some public info here and there - its easier for me to just go through the core and take what I need. That being said, if theres ever a nice opportunity to collaborate - im down. Mad respect to you guys and all your work, I built my career around advanced Webpack architecture & LOSA systems.

Ill happily switch focus to mini-css assuming I can get some plans the webpack team has over WP5-WP6. Whats it take to become an official member/collaborator of WP? Worth a shot asking - seems like theres going to be some overlaps in our work down the line, based on what I've seen in the core codebase. Id prefer to work on webpack rather than hack my way into its runtime just to do the same thing you guys are likely planning to do.

DM me on Twitter or something ScriptedAlchemy

Again mad love for the work you guys have done

@alexander-akait
Copy link
Member

/cc @TheLarkInn @sokra

@marcofugaro
Copy link

Any update on this? I'm using this plugin and I am faving a FOUC in development mode

@ScriptedAlchemy
Copy link
Contributor

Style loader will always fouc. It requires JavaScript to have fully executed. Unlike css usually works. It has to be appended by js

@Jessidhia
Copy link
Contributor

The FOUC should only happen if CSS source maps are enabled, as style-loader uses blob URLs then and those require a tick until they are considered loaded. Plain <style> tags take effect synchronously.

@leebenson
Copy link

Can I suggest you take a look at my ReactQL stater kit - I have this plugin working with HMR in dev, as well as alongside PostCSS, Sass, Less and Styled Components:

https://github.com/leebenson/reactql

It might help give you a starting point on issues such as avoiding FOUC (which doesn’t happen in my kit).

@leebenson
Copy link

And specifically, this is the Webpack loader tasked with CSS transpilation:

https://github.com/leebenson/reactql/blob/master/src/webpack/css.ts

@marcofugaro
Copy link

@Kovensky thank you! Disabling the sourceMap options of the css-loader takes away the FOUC.

So there isn't a way to use the css sourcemaps in dev without the FOUC?

@alexander-akait
Copy link
Member

Done in master, will be release in near future

@jakeNiemiec
Copy link

jakeNiemiec commented Apr 19, 2019

Nice! Allow me to save anyone else a few clicks by linking the PR: #334

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.