I've setup vue + vue-loader + HMR on an existing project.
It works mostly well, vue components are loaded and rendered correctly.
The hot module reload part is configured and loading.
However, it doesn't seem to apply updates when the change is only a text node of the component.
For example, if I have a component like this:
<template lang="html">
<div>
<h1>I'm a Component</h1>
</div>
</template>
<script>
export default {
}
</script>
And I change it to this:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
</div>
</template>
<script>
export default {
}
</script>
Then I can see the HMR updates in the browser console.
But the component doesn't update, it still says "I'm a Component".
However, if I slightly alter the html structure of the component like this:
<template lang="html">
<div>
<h1>I'm a Component updated</h1>
<p>do it</p>
</div>
</template>
<script>
export default {
}
</script>
Then the console shows the HMR log but this time the component update.
The behaviour is consistently the same, text change = no update.
The loader doesn't have anything particular in its config.
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
}
The dev server is launch via gulp with this task:
// 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"))
})
Not sure where else to look to fix this. As mentioned, it kinda works, just not for text node updates.
I've looked at the template generated by the vue-cli
webpack-simple
sample and the code is somewhat similar (except dev server is launch from node command line rather than manually building it), theirs does update text node, mine doesn't :(
Any clues?
Update: versions of relevant dependencies
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
Update 2: applying any modification to the <script>
part of the component does cause the text nodes to refresh.
Update 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
is set to "http://localhost:4000/"
ENTRY
is set to "./src/js/frontend.js"
"Hot Reload" is not simply reloading the page when you edit a file. With hot reload enabled, when you edit a *. vue file, all instances of that component will be swapped in without reloading the page. It even preserves the current state of your app and these swapped components!
Vuex supports hot-reloading mutations, modules, actions and getters during development, using webpack's Hot Module Replacement API. You can also use it in Browserify with the browserify-hmr plugin.
It's a webpack loader that supports defining Vue. js components in single files known as single-file components (SFCs). These files have the extension . vue and the vue-loader transpiles them into JavaScript so the browser can understand.
Hot reloading allows you to see the changes that you have made in the code without reloading your entire app. Whenever you make any changes, all you need to do is save your code. As soon as you save your code, React Native tracks which files have changed since your last saved, and only reload those file for you.
I've tried multiple things to fix this, I thought some settings fixed it but reverting back to previous versions suddenly started working too.
At the end, i think the fix was simply:
rm -rf node_modules/
npm i
But I don't know exactly which part of it made it fall apart.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With