vue-loader 上的热重载仅适用于模板的结构更改
Hot reload on vue-loader only works with structural changes to the template
我已经在现有项目上安装了 vue + vue-loader + HMR。
大部分情况下运行良好,vue 组件已正确加载和呈现。
热模块重新加载部分已配置并正在加载。
但是,当仅更改组件的文本节点时,它似乎不会应用更新。
例如,如果我有这样一个组件:
<template lang="html">
<div>
<h1>I'm a Component</h1>
</div>
</template>
<script>
export default {
}
</script>
然后我将其更改为:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
</div>
</template>
<script>
export default {
}
</script>
然后我可以在浏览器控制台中看到 HMR 更新。
但是组件没有更新,仍然显示"I'm a Component"。
但是,如果我像这样稍微改变组件的 html 结构:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
<p>do it</p>
</div>
</template>
<script>
export default {
}
</script>
然后控制台显示 HMR 日志,但这次是组件更新。
行为始终如一,文本更改 = 无更新。
加载程序在其配置中没有任何特别之处。
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
}
开发服务器通过 gulp 启动,任务如下:
// Start a webpack-dev-server
const hot_webpack_config = cloneDeep(webpack_config)
hot_webpack_config.output.filename = 'frontend.hot.js'
hot_webpack_config.output.publicPath = PUBLIC_DEV_SERVER
hot_webpack_config.entry.unshift("webpack-dev-server/client?"+PUBLIC_DEV_SERVER, "webpack/hot/dev-server");
hot_webpack_config.plugins.push(new webpack.HotModuleReplacementPlugin())
var compiler = webpack(hot_webpack_config)
var WebpackDevServer = require("webpack-dev-server")
new WebpackDevServer(compiler, {
//noInfo: true,
hot: true,
stats: {
assets: false,
colors: true,
version: false,
timings: false,
chunks: false,
chunkModules: false
},
inline: true,
publicPath: hot_webpack_config.output.publicPath,
headers: { "Access-Control-Allow-Origin": "*" }
}).listen(4000, "localhost", function(err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err)
// Server listening
gutil.log(chalk.blue("Hot server listening at http://0.0.0.0:4000"))
})
不确定还有什么地方可以解决这个问题。如前所述,它有点管用,只是不适用于文本节点更新。
我查看了 vue-cli
webpack-simple
示例生成的模板,代码有点相似(除了开发服务器是从节点命令行启动而不是手动构建它),他们的会更新文本节点,我的不会:(
有什么线索吗?
更新:相关依赖的版本
vue 2.3.4
vue-loader 13.0.0
vue-template-compiler 2.3.4
webpack 2.6.1
webpack-dev-server 2.5.0
更新 2: 对组件的 <script>
部分应用任何修改确实会导致文本节点刷新。
更新 3:
// webpack_config.js
/* jshint node: true */
var webpack = require('webpack'),
path = require('path'),
package = require('./package.json'),
gutil = require('gulp-util'),
chalk = require('chalk');
const PUBLIC_DEV_SERVER = package.config.build.PUBLIC_DEV_SERVER
const ENTRY = package.config.build.ENTRY
var PROD = process.env.NODE_ENV == 'production';
let config = {
entry: [
ENTRY
],
output: {
path: path.join(__dirname, 'resources', 'js'),
filename: 'frontend.min.js'
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
}
}, {
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'stage-0'],
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
if (process.env.NODE_ENV === 'production') {
gutil.log(chalk.red("Build for production"));
config.devtool = '#source-map'
config.entry = [
ENTRY
];
// http://vue-loader.vuejs.org/en/workflow/production.html
config.plugins = (config.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
} else {
gutil.log(chalk.red("Build for development"));
config.devtool = '#eval-source-map' //"cheap-module-eval-source-map"
config.plugins = [
]
}
module.exports = config
PUBLIC_DEV_SERVER
设置为 "http://localhost:4000/"
ENTRY
设置为 "./src/js/frontend.js"
我尝试了多种方法来解决这个问题,我认为一些设置可以解决这个问题,但恢复到以前的版本突然也开始起作用了。
最后,我认为解决方法很简单:
rm -rf node_modules/
npm i
但我不知道到底是哪一部分让它分崩离析。
我已经在现有项目上安装了 vue + vue-loader + HMR。
大部分情况下运行良好,vue 组件已正确加载和呈现。
热模块重新加载部分已配置并正在加载。
但是,当仅更改组件的文本节点时,它似乎不会应用更新。
例如,如果我有这样一个组件:
<template lang="html">
<div>
<h1>I'm a Component</h1>
</div>
</template>
<script>
export default {
}
</script>
然后我将其更改为:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
</div>
</template>
<script>
export default {
}
</script>
然后我可以在浏览器控制台中看到 HMR 更新。
但是组件没有更新,仍然显示"I'm a Component"。
但是,如果我像这样稍微改变组件的 html 结构:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
<p>do it</p>
</div>
</template>
<script>
export default {
}
</script>
然后控制台显示 HMR 日志,但这次是组件更新。
行为始终如一,文本更改 = 无更新。
加载程序在其配置中没有任何特别之处。
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
}
开发服务器通过 gulp 启动,任务如下:
// Start a webpack-dev-server
const hot_webpack_config = cloneDeep(webpack_config)
hot_webpack_config.output.filename = 'frontend.hot.js'
hot_webpack_config.output.publicPath = PUBLIC_DEV_SERVER
hot_webpack_config.entry.unshift("webpack-dev-server/client?"+PUBLIC_DEV_SERVER, "webpack/hot/dev-server");
hot_webpack_config.plugins.push(new webpack.HotModuleReplacementPlugin())
var compiler = webpack(hot_webpack_config)
var WebpackDevServer = require("webpack-dev-server")
new WebpackDevServer(compiler, {
//noInfo: true,
hot: true,
stats: {
assets: false,
colors: true,
version: false,
timings: false,
chunks: false,
chunkModules: false
},
inline: true,
publicPath: hot_webpack_config.output.publicPath,
headers: { "Access-Control-Allow-Origin": "*" }
}).listen(4000, "localhost", function(err) {
if(err) throw new gutil.PluginError("webpack-dev-server", err)
// Server listening
gutil.log(chalk.blue("Hot server listening at http://0.0.0.0:4000"))
})
不确定还有什么地方可以解决这个问题。如前所述,它有点管用,只是不适用于文本节点更新。
我查看了 vue-cli
webpack-simple
示例生成的模板,代码有点相似(除了开发服务器是从节点命令行启动而不是手动构建它),他们的会更新文本节点,我的不会:(
有什么线索吗?
更新:相关依赖的版本
vue 2.3.4
vue-loader 13.0.0
vue-template-compiler 2.3.4
webpack 2.6.1
webpack-dev-server 2.5.0
更新 2: 对组件的 <script>
部分应用任何修改确实会导致文本节点刷新。
更新 3:
// webpack_config.js
/* jshint node: true */
var webpack = require('webpack'),
path = require('path'),
package = require('./package.json'),
gutil = require('gulp-util'),
chalk = require('chalk');
const PUBLIC_DEV_SERVER = package.config.build.PUBLIC_DEV_SERVER
const ENTRY = package.config.build.ENTRY
var PROD = process.env.NODE_ENV == 'production';
let config = {
entry: [
ENTRY
],
output: {
path: path.join(__dirname, 'resources', 'js'),
filename: 'frontend.min.js'
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
}
}, {
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'stage-0'],
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
if (process.env.NODE_ENV === 'production') {
gutil.log(chalk.red("Build for production"));
config.devtool = '#source-map'
config.entry = [
ENTRY
];
// http://vue-loader.vuejs.org/en/workflow/production.html
config.plugins = (config.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
} else {
gutil.log(chalk.red("Build for development"));
config.devtool = '#eval-source-map' //"cheap-module-eval-source-map"
config.plugins = [
]
}
module.exports = config
PUBLIC_DEV_SERVER
设置为 "http://localhost:4000/"
ENTRY
设置为 "./src/js/frontend.js"
我尝试了多种方法来解决这个问题,我认为一些设置可以解决这个问题,但恢复到以前的版本突然也开始起作用了。
最后,我认为解决方法很简单:
rm -rf node_modules/
npm i
但我不知道到底是哪一部分让它分崩离析。