webpack 热重载的3种方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack 热重载的3种方式相关的知识,希望对你有一定的参考价值。

参考技术A

开发阶段,如果每次文件变更后,都要手动去打包build是很不方便的,通常在开发阶段采用以下三种方式进行热重载(自动编译)

配置文件提供一个入口和一个出口,webpack根据这个来进行js的打包和编译工作。package.json文件增加watch脚本 --watch 动态监听文件的改变并实时打包,输出新的文件,这样文件多了之后速度会很慢,而且此打包方式不会热更新,即每次webpack编译之后,你还需要手动刷新浏览器。
缺点: 需手动刷新浏览器
优点: 自动编译

webpack-dev-server实际上相当于启用了一个express的Http服务器+调用了webpack-dev-middleware【简单的web服务器和实时重载】。这个Http服务器和client使用了websocket通讯协议,原始文件做出改动后,webpack-dev-server会用webpack实时的编译,再用webpack-dev-middleware将webpack编译后的文件输出到内存中。【这边注意,最后的编译的文件并没有输出到目标文件夹,都保存到了内存】(适合纯前端项目,很难编写后端服务,进行整合)

优点: 自动编译 + 实时重新加载浏览器
webpack-dev-server

缺点: 需手动刷新浏览器 + 配置文件和插件多
优点: 自动编译

定义了webpack.config里的entry和output的关系脉络,webpack-dev-middleware能在此基础上形成一个文件映射系统,每当应用程序请求一个文件。它匹配到了就把内存中缓存的对应结果以文件格式返回,反之进入下一个中间件。

因为是内存型文件系统,所以重建速度非常快,很适合于开发阶段用作静态资源服务器;因为webpack可以把任何一种资源当作是模块来处理,因此能向客户端反馈各种格式的资源,所以可以替代HTTP服务器。

三者相比:观察模式在开发中不实用;web服务器实用性强;webpack中间件+express使用了2个插件,2个配置文件,配置复杂

事实上,大多数 webpack 用户用过的 webpack-dev-server 就是一个 express+webpack-dev-middleware 的实现。

二者的区别仅在于 webpack-dev-server 是封装好的,除了 webpack.config 和命令行参数之外,很难去做定制型开发。而 webpack-dev-middleware 是中间件,可以编写自己的后端服务然后把它整合进来,相对而言比较灵活自由。

是一个结合webpack-dev-middleware使用的middleware,它可以实现浏览器的无刷新更新(hot reload),这也是webpack文档里常说的HMR(Hot Module Replacement)。HMR和热加载的区别是:热加载是刷新整个页面。

运行方式:
1、命令行
package.json中指令加上 --hot

2、Nodejs API

热更新热重载
webpack-dev-server 自动打包/热重载

Webpack 开发中间件反应热重载太慢

【中文标题】Webpack 开发中间件反应热重载太慢【英文标题】:Webpack dev middleware react hot reload too slow 【发布时间】:2016-08-18 00:11:13 【问题描述】:

我有一个带有 webpack-dev-middlewarewebpack-hot-middleware 的简单配置,它使用热重载 (HMR) 和反应。

一切正常,除了我对代码所做的每一次更改都需要 2 3-4 秒!!!直到我在浏览器中看到它。 难道我做错了什么 ?它应该是这样的?

我的代码相当大,我的包缩小到 841kb(200kb gzipped)是这个原因吗?代码库越大,包创建越慢?

快递服务器:

var webpack = require('webpack');
var webpackConfig = require('./webpack.hot.config');
var compiler = webpack(webpackConfig);

app.use(require("webpack-dev-middleware")(compiler, 
  noInfo: true,
  publicPath: webpackConfig.output.publicPath,
  watchOptions: 
    poll: true
  
 ));
app.use(require("webpack-hot-middleware")(compiler, 
  log: console.log,
  path: '/__webpack_hmr',
  heartbeat: 10 * 1000
 ));

webpack.hot.config.js

    const path = require('path');
    const webpack = require('webpack');

module.exports = 

context: __dirname,
entry: [
    'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
    './src/js/index'
],
module: 
    loaders: [
        test: /\.jsx?$/,
        include: path.join(__dirname, 'src/js'),
        //exclude: /node_modules/,
        loader: 'react-hot!babel'
    ,
        
            // Test expects a RegExp! Note the slashes!
            test: /\.css$/,
            loaders: ['style', 'css'],
            // Include accepts either a path or an array of paths.
            include: path.join(__dirname, 'src/css')
        
    ]
,
resolve: 
    extensions: ['', '.js', '.jsx']
,
output: 
    path: __dirname + '/public',
    publicPath: '/',
    filename: 'js/app.js'
,
plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
]
;

这就是我在代码中更改某些内容时在控制台中得到的结果:

[HMR] App is up to date.
app.js:73223 [HMR] bundle rebuilding
app.js:73226 [HMR] bundle rebuilt in 335ms
app.js:73289 [HMR] Checking for updates on the server...
app.js:73362 [HMR] Updated modules:
app.js:73364 [HMR]  - ./src/js/components/header.jsx
app.js:73369 [HMR] App is up to date.

【问题讨论】:

所以exclude: /node_modules/ 被注释掉了。在配置中构建仍然很慢吗?除此之外,我建议删除 OccurrenceOrderPlugin。该插件旨在帮助您处理似乎没有实现的分块(除非您在不同的配置文件中)。 @garrettmaring,使用include 代替exclude 就足够了,因为它是更明确的变体。过去,我想我还需要使用OccurenceOrderPlugin 来确保webpack-dev-middleware 的热重载。 【参考方案1】:

专业提示:webpack.config.js 中的模式更改为开发。如果您不使用此属性,它将默认为生产环境,这意味着它会减慢生产速度并使您的热重载变得很糟糕。

module.exports = 
    mode: 'development'
;

【讨论】:

【参考方案2】:

您应该启用缓存:

    ...
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
    cache: true
;

【讨论】:

这似乎没有帮助。 @Adidi 你找到解决方案了吗?否则你可以查看webpack.js.org/plugins/dll-plugin【参考方案3】:

考虑在中间件中将轮询切换为 false。我发现轮询可能是 CPU 密集型的。

在您的 webpack 配置中,您可能还想尝试添加 devtool: false 以避免创建源映射。

【讨论】:

这似乎没有帮助。 在 Windows 上使用 docker 时,这不是一个选项。

以上是关于webpack 热重载的3种方式的主要内容,如果未能解决你的问题,请参考以下文章

Typescript + webpack(带热重载)+ NodeJS

使用 webpack dev server 和 rails server 的 Webpack 热重载

启用单页应用响应热重载 webpack

Django、ReactJS、Webpack 热重载

webpack 2 热重载不重新渲染

webpack-dev-server 热重载不适用于 webpack4