webpack-dev-server不能自动刷新问题

本文详细介绍了在webpack-dev-server中遇到的自动刷新问题及其解决办法,包括iframe模式和inline模式的使用,以及手动配置inline模式的过程。重点强调了webpack配置的bundle.js与webpack-dev-server打包的开发环境bundle.js的区别,指出实时编译的文件保存在内存中。此外,还提到了css-loader、style-loader、postcss-loader和autoprefixer的使用,以及如何通过npm start启动项目并实现自动刷新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果已经将 webpack 安装到全局中,则可以直接使用 webpack 命令;如果非全局安装需使用,使用项目内部的 webpack 命令的话,需要使用如下方式来运行 webpack 命令:
node_modules/.bin/webpack
值得注意的是,npm start 命令可以引导任务执行,自动使用项目内部的 webpack 等命令。
注:package.json中的script会安装一定顺序寻找命令对应位置,本地的node_modules/.bin路径就在这个寻找清单中,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了。

使用webpack-dev-server中遇到不能浏览器无法自动刷新的问题;寻找多方答案后明白了一些;

下面有一些需要注意的点:

1.webpack-dev-server并不能读取你的webpack.config.js的配置output!!

你在webpack.config.js里面的配置output属性是你用webpack打包时候才起作用的,对webpack-dev-server并不起作用

2.webpack-dev-server打包生产的文件并不会添加在你的项目目录中!!它默认打包的文件名是bundle.js,不会真的出现在你的项目目录中。

注意:你启动webpack-dev-server后,你在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。因此很多同学使用webpack-dev-server进行开发的时候都看不到编译后的文件

webpack-dev-server支持两种模式来自动刷新页面.

  • iframe模式(页面放在iframe中,当发生改变时重载)
  • inline模式(将webpack-dev-sever的客户端入口添加到包(bundle)中)

两种模式都支持热模块替换(Hot Module Replacement).热模块替换的好处是只替换更新的部分,而不是页面重载.

iframe模式
使用这种模式不需要额外的配置,只需要以下面这种URL格式访问即可

http://«host»:«port»/webpack-dev-server/«path»
例如:http://localhost:8080/webpack-dev-server/index.html

inline模式
1 当以命令行启动webpack-dev-server时,需要做两点:

在命令行中添加–inline命令
在webpack.config.js中添加devServer:{inline:true}//这个也可以不用。
2 当以Node.js API启动webpack-dev-server时,我们也需要做两点:

由于webpack-dev-server的配置中无inline选项,我们需要添加webpack-dev-server/client?http://«path»:«port»/到webpack配置的entry入口点中.
将<script src=“http://localhost:8080/webpack-dev-server.js”></script>添加到html文件中

    var config = require("./webpack.config.js");
    var webpack = require('webpack');
    var WebpackDevServer = require('webpack-dev-server');

config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");

var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {
    contentBase:'build/',
    publicPath: "/assets/"
});
server.listen(8080);

示例:
自动刷新的配置方法(inline模式):
我习惯的做法是在项目的package.json里面添加
如下代码亲测有效:
项目结构图:
这里写图片描述

webpack.config.js

 /**
 * Created by DreamCatcher on 2017/11/1.
 * 如果没有这个配置文件,需要使用如下命令手动打包:node_modules\.bin\webpack js\requireAddDiv1.js dist\bundle.js
 * 如果有这个配置文件,只需要使用如下命令就可以了:node_modules\.bin\webpack
 */
var webpack = require("webpack");
module.exports = {
	devtool: "eval-source-map",//生成Source Maps
    //entry: "./js/requireAddDiv1.js",
    entry: {
        app: [
                "./js/requireAddDiv1.js",
                "webpack-dev-server/client?http://localhost:8080/" //只要这一个配置就可以实现CSS自动刷新。
            ]
    },
    output: {
        path: __dirname + "/dist",
        filename: "bundle.js"
    },
    module: {
	    /*在webpack2.0版本已经将 module.loaders 改为 module.rules 为了兼容性考虑以前的声明方法任然可用,
      同时链式loader(用!连接)只适用于module.loader,
      同时-loader不可省略
      */
        /*loaders: [
	        {
                test: "/(\.jsx|\.js)$/",
                loader: "babel-loader"
            },
            {
                //test: /\.\/css\/*\.css$/,//这种方式精确定位
                test: "/\.css$/",
                loader: "style-loader!css-loader"//这种方式只有 loaders 可以使用 rules 不可以
            }
        ]*/
        //以下是使用 rules 的方式:
        rules: [
            {
                test: "/(\.jsx|\.js)$/",
                use: {
                    loader: "babel-loader"
                },
                exclude: /node-modules/ //注意这里没有使用引号
            },
            {
                test: "/\.css$/",
                use: [ //引入多个loader的方法
                    "style-loader",
                    {
                        loader: "css-loader",
                        options: {
                            // modules: true // 设置css模块化,详情参考https://github.com/css-modules/css-modules
                        }
                    },
                    /*{
                        loader: 'postcss-loader',
                        // 在这里进行配置,也可以在postcss.config.js中进行配置,详情参考https://github.com/postcss/postcss-loader
                        options: {
                            plugins: function () {
                                return [
                                    require('autoprefixer')
                                ];
                            }
                        }
                    }*/
                ]
            }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,盗版必究!')
    ]
};

注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

webpack提供两个工具处理样式表,css-loader 和 style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(…)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。

如果需要使用到 postcss-loader, 需要首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)

npm install --save-dev postcss-loader autoprefixer

或是在 package.json 文件中进行配置。

devtool选项配置结果
source-map在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;
cheap-module-source-map在一个单独的文件中生成一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;
eval-source-map使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项;
cheap-module-eval-source-map这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点;

上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。对小到中型的项目中,eval-source-map是一个很好的选项,再次强调你只应该开发阶段使用它。

Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less…),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。

package.json

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "My test of webpack",
  "main": "js/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --inline --content-base"
  },
  "keywords": [
    "webpack",
    "test"
  ],
  "author": "slHuang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "3.8.1",
    "css-loader": "^0.28.7",
    "style-loader": "^0.19.0",
    "webpack-dev-server": "^2.9.3"
  }
}

这样通过npm start命令就能启动 inline模式了,当然也可以具体的输入webpack-dev-server命令

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test webpack</title>
</head>
<body>
    <h3>This is my first test.</h3>
    <script src="bundle.js"></script>
</body>
</html>

关键的是你的index.html也就是你的项目入口的html文件里面引用这个bundle.js文件需要直接引用根目录下面的!一定不能写 webpack.config.js 中 output 中配置的路径,比如:dist/bundle.js

不能引用你webpack配置的bundle.js文件目录,webpack配置的这个bundle.js文件,只有在你手动打包webpack之后才会改变!

requireAddDiv1.js

/**
 * Created by DreamCatcher on 2017/11/1.
 */
require("!style-loader!css-loader!../css/index.css");
var div = document.createElement("div");
div.innerHTML = "Added second div.";
document.body.appendChild(div);


var div2 = document.createElement("div");
div2.innerHTML = "Added second div2.";
document.body.appendChild(div2);

index.css

body {
    background-color: yellow;
    color: blue;
}

通过 npm start 启动项目,chrome 里面输入以下路径:http://localhost:8080/
页面就可以打开了。

然后,就是见证奇迹的时候了:
随便修改 index.css 中的一个属性,比如将 color 改成 red
这个时候,编译器就会自动编译:
这里写图片描述

这时候 chrome 中页面就会自动刷新,并且当前修改的属性,在页面上正常表现出来了,文字颜色变成了 red。

总结下就是:webpack里面配置的bundle.js需要手动打包才会变化目录可以由你自己指定!webpack-dev-server自动检测变化自动打包的是开发环境下的bundle.js,打包路径由你的contentBase决定!两个文件是不一样的

另外,停止 webpack-dev-server ,只需要在命令窗口中 ctrl + c 就可以了。


后面,还试了另一种配置:
接上面的示例,需要做如下修改:
1、将 webpack.config.js 添加如下配置:

module.exports = {
    ...
	devServer: {
	    contentBase: "./",//本地服务器所加载的页面所在的目录
	    historyApiFallback: true,//不跳转
	    inline: true,//实时刷新
	    hot: true//hot module replacement. Depends on HotModuleReplacementPlugin
	  } 
    ...
	plugins: {
		...
		new webpack.HotModuleReplacementPlugin()
		...
	}
}

2、在package.json中的scripts对象中添加如下命令,用以开启本地服务器:

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server --open" //这里的 open 是指运行 server 后自动打开 index.html页面
  },

启动 server:
npm run server

这样也可以了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值