我一直在尝试使用Webpack-Dev-Server配置Webpack 2热模块替换。
webpack.config.js
如下:
const path = require('path');
const Webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HotModuleReplacement = new Webpack.HotModuleReplacementPlugin();
const NamedModulesPlugin = new Webpack.NamedModulesPlugin();
const NoEmitOnErrorsPlugin = new Webpack.NoEmitOnErrorsPlugin();
const extractCSS = new ExtractTextPlugin('main.css');
const extractSCSS = new ExtractTextPlugin('styles.css');
const config = {
entry: [
'webpack-dev-server/client?http://localhost:8080',
// bundle the client for webpack-dev-server
// and connect to the provided endpoint
'webpack/hot/only-dev-server',
// bundle the client for hot reloading
// only- means to only hot reload for successful updates
'./src/index.js',
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'http://localhost:8080/',
hotUpdateChunkFilename: 'hot/hot-update.js',
hotUpdateMainFilename: 'hot/hot-update.json',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: [
path.resolve(__dirname, 'node_modules'),
],
loader: 'babel-loader',
options: {
presets: ['react', 'es2015', 'stage-2'],
},
},
{
test: /\.scss$/,
loader: extractSCSS.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader'],
}),
},
{
test: /\.css$/,
loader: extractCSS.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader'],
}),
},
],
},
plugins: [
extractCSS,
extractSCSS,
HotModuleReplacement,
NamedModulesPlugin,
NoEmitOnErrorsPlugin,
],
devtool: 'source-map',
devServer: {
publicPath: 'http://localhost:8080/',
contentBase: './',
inline: true,
hot: true,
historyApiFallback: true,
stats: {
colors: true,
},
},
};
module.exports = config;
我有这个文件夹结构:
/
/src
/src/index.js
/src/index.scss
而且我认为我需要在index.js
中使用HMR API,如下所示:
import MockComponent from './MockComponent/MockComponent';
export default class App {
constructor() {
this.mock = new MockComponent();
}
render() {
return `<div class="element">${this.mock.render()}</div>`;
}
}
let app = {};
app = new App();
const mainDiv = document.querySelector('#root');
mainDiv.innerHTML = app.render();
// Hot Module Replacement API
if (module.hot) {
module.hot.accept();
}
问题是,当我在控制台中对代码进行更改时,我得到了:
但是HMR似乎没有对渲染进行任何改变。
有人可以帮我解决这个问题吗?
非常感谢
问题似乎是你在开发模式中没有disable
ExtractTextPlugin
。在没有禁用它的情况下,你传递的fallback
加载器将不会运行,在这种情况下是style-loader
,而ExtractTextPlugin
不支持HMR本身。
在生产中你不希望禁用ExtractTextPlugin
,所以一种方法是使用一个配置将使用--env
标志。请注意,通常建议使用单独的配置,一个用于生产,一个用于开发,尽管您可以使用webpack-merge等工具来共享公共位。
因此,在package.json中,您需要更新脚本,然后将配置更改为函数,以便它可以接受env
对象作为参数。
的package.json
{
...
scripts: {
"start": "webpack-dev-server --env.dev",
"build": "webpack"
},
...
}
webpack.config.js
...
const config = (env = {}) => ({
...
plugins: [
new ExtractTextPlugin({
filename: 'styles.css',
disable: env.dev === true
})
]
})
为简洁起见,我在这里排除了很多,但这应该给你一个很好的主意。请参阅下面我正在使用的版本...
[email protected]
[email protected]
[email protected]
[email protected]
值得注意的是,虽然您可以在hot: true
中使用devServer
并在new HotModuleReplacementPlugin()
中使用plugins
启用HMR,但是在浏览器中为不同类型的代码生成“实时”更改需要其他加载程序和配置更改...这里有一些来去提醒:
这已经解决了(请参阅此回购https://github.com/andrixb/WebpackSassStarter):
webpack.config.js
HtmlWebpackPlugin
中添加了以下配置:
new HtmlWebpackPlugin({
title: 'FE Build Setup',
hash: true,
template: './src/index.html',
}),
src
文件夹中移动了外面的index.html
并删除了静态脚本和链接标记(index.html
现在仅用于模板)webpack.config.js
的entry
中删除
'webpack-dev-server/client? http://localhost:8080',
// bundle the client for webpack-dev-server
// and connect to the provided endpoint
'webpack/hot/only-dev-server',
// bundle the client for hot reloading
// only- means to only hot reload for successful updates
在output
:
publicPath: 'http://localhost:8080/',
hotUpdateChunkFilename: 'hot/hot-update.js',
hotUpdateMainFilename: 'hot/hot-update.json',
webpack.config.js
中)ExtractTextPlugin
devServer
编辑了webpack.config.js
配置