我试图为通过Django模板系统提供的捆绑前端静态资产设置热模块替换,如果可能的话。我每当编译资产发生变化时,都会通过livereload刷新页面,但编译时间越来越长,任何CSS更改都会导致整页重新加载。
这是Django中模板文件的一个示例。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- Header Links -->
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
window.CONFIG = {
/** Injected application configuration from Django. */
};
</script>
<!-- Webpack bundle url -->
<script src="{{ bundle_url }}"></script>
</body>
</html>
我已经能够通过webpack dev服务器提供资源,并通过模板变量注入bundle url http://localhost:3000/bundle.js
,所以我可以在视图中看到该应用程序。
Webpack配置
'use strict';
const webpack = require('webpack');
const CONFIG = require('./config');
/**
* Webpack configuration for a development environment.
* @type {Object}
*/
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
require.resolve('core-js/shim'),
CONFIG.PATHS.ENTRY,
],
output: {
path: CONFIG.PATHS.BUILD,
filename: CONFIG.OUTPUT_FILENAME,
},
module: {
rules: CONFIG.SHARED_RULES.concat([{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
}, {
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}]),
},
resolve: CONFIG.WEBPACK_RESOLVE,
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
};
启动脚本:
'use strict';
// Crashes the script on unhandled rejections instead of silently ignoring.
process.on('unhandledRejection', (error) => { throw error; });
process.env.NODE_ENV = 'development';
// Vendor
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const chalk = require('chalk');
// Local
const WEBPACK_CONFIG = require('../config/webpack.config.dev');
const CONFIG = require('../config/config');
const PORT = parseInt(process.env.PORT, 10) || CONFIG.DEFAULT_PORT;
const HOST = process.env.HOST || CONFIG.DEFAULT_HOST;
const URL = `http://${HOST}:${PORT}/`;
const compiler = webpack(WEBPACK_CONFIG);
const server = new WebpackDevServer(compiler, {
compress: true,
hot: true,
host: HOST,
stats: 'minimal',
});
server.listen(PORT, HOST, (error) => {
if (error) { return console.log(chalk.red(error)); }
console.log(chalk.cyan(`Starting the development server at ${URL}...`));
['SIGINT', 'SIGTERM'].forEach((signal) => {
process.on(signal, () => {
server.close();
process.exit();
});
});
});
我不确定开发服务器如何触发热重新加载。我的印象是该捆绑包包含一个脚本,该脚本连接到开发服务器上的Websocket连接,并且该连接将触发脚本下载并显示新资产。但情况可能并非如此,而且我还没有找到任何有关如何传达热重载的信息。我只发现了客户端收到更新后热重载如何工作的一般概述。
答案 0 :(得分:1)
经过大量的搜索,我终于找到了解决问题的方法。我找到了information about how to integrate webpack-dev-server with an existing server in the old webpack docs,所以我摆脱了整个构建脚本,并用package.json
中的一个脚本替换它,它只使用了webpack-dev-server而没有任何标志:
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server",
// Scripts...
}
这会自动将热模块替换代码注入我的包中,并在更改时刷新我的页面。这比我之前的livereload服务器快得多。捆绑包是通过我的应用程序模板中的URL http:localhost:8080/bundle.js
引用的,而不是通过本地路径引用的。由于捆绑包保存在内存中,本地路径无论如何都不会起作用。
该网址还解释了如何使--inline --hot
功能正常运行,但我无法让它在我的设置上运行。
如果您需要使用本地路径而不是通过url引用捆绑包,那么您必须依赖于使用webpack的监视模式并手动刷新页面或依赖Django插件。我发现的解决方案对我来说很有效,因为它反映了我们的生产环境。我们的Django部署通过我们管理的CDN引用前端资产。如果你必须使用Django代码部署前端资产,它可能不适合你,但如果你创建一个在两个不同的应用程序模板之间切换的Django设置,它可能是有效的:一个用于使用URL拉动的开发在脚本中,一个用于生成,引用STATICFILES_DIRS
。
答案 1 :(得分:0)
我不认为的问题是Webpack的错。我注意到当我让Django提供我的React文件时会出现这些速度问题。当您使用Django时,您的文件由Django服务器提供服务,与webpack-dev服务器相比,这本身就很慢。 webpack dev服务器与Django之间的整个通信过程可能需要时间,必须让Django服务器触发更改,然后再次重新提供静态文件。
一个解决方案是将React前端代码与后端代码隔离,让React使用Django的REST API。它运行非常顺畅,减少了服务器上的大量负载。