Webpack-dev-server编译文件但不刷新页面,也没有把编译后的JavaScript提供给浏览器

110

我正在尝试使用webpack-dev-server来编译文件并启动开发Web服务器。

在我的package.json中,我将脚本属性设置为:

"scripts": {
  "dev": "webpack-dev-server --hot --inline",
 }

所以,--hot--inline 应该启用 Web 服务器和热更新(就我所了解的而言)。

在我的 webpack.config.js 文件中,我设置了入口、输出和 devServer 设置,并添加了一个加载器来查找 .vue 文件的变化:

module.exports = {
    entry: './src/index.js',
    output: {
        path: __dirname + '/public',
        publicPath: '/public',
        filename: 'bundle.js'
    },
    devtool: 'source-map',
    devServer:{
        contentBase: __dirname + '/public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};

所以在这种设置下,我运行 npm run dev。webpack-dev-server启动了,模块加载器测试工作正常(即当我保存任何.vue文件时,它会导致webpack重新编译),但是:

  • 浏览器从未刷新过
  • 存储在内存中的编译javascript从未向浏览器公开

对于第二个问题,我可以看到这一点,因为在浏览器窗口中vue占位符从未被替换,如果我打开javascript控制台,则Vue实例从未创建或全局可用。

问题的Gif

我错过了什么?


我认为你的webpack没有正常工作,浏览器控制台中缺少bundle.js。之后,你应该仔细阅读热模块替换文档https://webpack.github.io/docs/webpack-dev-server.html#hot-module-replacement,建议先从CLI模式开始。 - mygoare
6
我在制作过程中阅读了文档,但我个人认为解释有些复杂。另外,当我按照文档中的示例在新项目中进行尝试时,它并没有起作用。然而,我进行了一些组件隔离测试,并找出了配置文件中的问题。今天午餐时,我会打字写出详细的答案。 - Chris Schmitz
15个回答

81

两件事情导致我的问题:

module.exports = {
    entry: './src/index.js',
    output: {

        // For some reason, the `__dirname` was not evaluating and `/public` was
        // trying to write files to a `public` folder at the root of my HD.
        path: __dirname + '/public', 

        // Public path refers to the location from the _browser's_ perspective, so 
        // `/public' would be referring to `mydomain.com/public/` instead of just
        // `mydomain.com`.
        publicPath: '/public',
        filename: 'bundle.js'
    },
    devtool: 'source-map',
    devServer:{

        // `contentBase` specifies what folder to server relative to the 
        // current directory. This technically isn't false since it's an absolute
        // path, but the use of `__dirname` isn't necessary. 
        contentBase: __dirname + '/public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};

这是修复后的webpack.config.js文件:
var path = require('path');

module.exports = {
    entry: [
        './src/PlaceMapper/index.js'
    ],
    output:{
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'public/')
    },
    devtool: 'source-map',
    devServer:{
        contentBase: 'public'
    },
    module:{
        loaders:[
            { test: /\.vue$/, loader: 'vue'}
        ]
    }
};

10
“publicPath”选项是开发服务器最令人困惑的部分。 一般规则是:如果您没有在“output”块(webpack配置)中设置“publicPath”,则不要为您的开发服务器设置“publicPath”选项。 - Alan
谢谢提到"publicPath"选项,这真的帮了我很多! - Benny Code
3
Webpack的开发团队应该把你纳入他们的薪资名单中!即使一年后,这仍然是我见过的关于如何设置服务器的最好文档。 - Ernie S
1
如果这对你不起作用,请参见:https://github.com/webpack/webpack-dev-server/issues/875#issuecomment-362101506和https://github.com/webpack/webpack-dev-server/issues/875#issuecomment-450073932。 - Yngvar Kristiansen
这篇文章帮助我理解了为什么webpack-dev-server的热更新不起作用。在我的情况下,publicPath被设置成了'/',而实际上它应该是'/js-lib/'。这就是文件没有变化的原因,因为我在js-lib中提供了静态文件,而没有提供'http:localhost:9001' + '/'(您的webpack-dev-server主机+publicPath)中的内存文件。 - Herz3h

24

经过长时间的搜索,我找到了解决我的问题的方法,在我的情况下,输出路径没有正确配置。

这个配置解决了我的问题:

const path = require('path');

module.exports = {
  "entry": ['./app/index.js'],
  "output": {
    path: path.join(__dirname, 'build'),
    publicPath: "/build/",
    "filename": "bundle.js"
  }....

10
加入"publicPath"属性解决了我的问题。 - Borjante
1
通过在publicPath属性中的文件夹名称前添加斜杠解决了这个问题。output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist/'), publicPath: '/dist', } - n4ks

21

正确的解决方案

通过devServer.watchContentBase选项告诉dev-server 监视所提供的文件。

它默认是禁用的。

启用后,文件更改将触发整个页面的重新加载

示例:

module.exports = {
  //...
  devServer: {
    // ...
    watchContentBase: true
  }
};

3
亲爱的开发者们,实际上,热模块替换对我的项目有效。但是我通过代理将webpack-dev-server与firebase-serve关联起来。当我尝试了您提供的建议后,我的问题得到了解决。感谢您的帮助。 - Arda Zaman

12

我之前的开发服务器也出了问题,它停止工作了。之前它一直工作正常,但我加了很多东西来创建一个生产版本。后来当我回到开发服务器时,它不再工作。

花费了很多时间才最终解决问题——从git中开始找到先前的提交,然后逐个重新引入更改,直到我找到问题所在。

结果发现是我对package.json所做的更改引起的,具体来说是这行:

  "browserslist": "> 1%, not dead",

这对指导postcss,针对特定的浏览器进行目标设置非常有用。

但这会停止devserver工作。解决方法是将以下内容添加到开发环境的webpack配置:

target: 'web', 

我在这里找到了解决方案:https://github.com/webpack/webpack-dev-server/issues/2812

希望这能为某些人节省几个小时的麻烦!


2
救命稻草!非常感谢。我永远不会发现那个问题。 - andrew
这最终为我解决了问题。谢谢! - Abhijeet Singh

6
在我的情况下,去掉“--hot”就可以使它工作。所以,我删除了hot: true
webpack.dev.js
module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    publicPath: '/js/',
    contentBase: path.resolve(__dirname, 'docs'),
    watchContentBase: true,
  }
});

webpack.common.js

  output: {
    path: path.resolve(__dirname, 'docs/js'),
    filename: '[name].min.js',
    library: ['[name]']
  },

4

我遇到了同样的问题,除了所有这些点之外,我们还需要将index.html与输出的bundle.js放在同一个文件夹中,并将contentBase设置为此文件夹,无论是根目录还是子文件夹。


4

我也曾经遇到过这种情况,当我连续运行两个不同的应用程序在同一个webpack-dev-server端口时,即使另一个项目已经关闭,这种情况仍然发生。当我改成一个未被使用的端口后,它就能直接工作了。

devServer: {
    proxy: {
        '*': {
            target: 'http://localhost:1234'
        }
    },
    port: 8080,
    host: '0.0.0.0',
    hot: true,
    historyApiFallback: true,
},

如果您和我一样使用Chrome浏览器,只需打开 开发者工具,然后点击清除网站数据。您也可以在隐身模式下运行该网站以查看是否存在问题。

enter image description here


这也发生在我身上了,不过我还得重启Chrome。 - Andrea Rosales
Chrome 重新启动也有帮助。 - Vlad Isajkin

3
因为 ExtractTextPlugin 可能会导致这种情况发生。在开发模式下停用 ExtractTextPlugin,仅在生产构建中使用它。

这是我的问题。显然,在ExtraTextPlugin文档中指出它不支持热重载。你可以尝试这个:https://dev59.com/rOk5XIcBkEYKwwoY_O-N#49932664 - user1319182

1
我曾经遇到过类似的情况,即webpack-dev-server可以提供我的index.html文件但不更新。阅读了几篇文章后,我意识到webpack-dev-server不会生成新的js文件,而是将一个js文件注入到index.html中。
我向我的应用程序添加了html-webpack-plugin,并在我的webpack.config.js文件中使用以下配置:
const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    })
  ]

然后我在index.html中注释掉了引用我的入口js文件的脚本标签。现在我可以运行webpack-dev-server而不需要任何额外的标志,对我的文件进行任何更改都会立即显示在浏览器中。


0

我的情况是我深入研究Webpack的功能,但完全忘记了整个时间都将注入设置为false,就像这样...

 new HTMLWebpackPlugin({
        inject: false,
        ...
 }),

打开那个东西就是我的敲门砖。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接