简短的摘要
由于 dev-middleware 依赖于内存中的文件,是否不可能将 htmlwebpackplugin 功能与 webpack-dev-middleware 结合起来?本文底部的脚本输出截图。因为我选择在我的生产配置中实现缓存散列文件名,所以我似乎不能再使用 dev-middleware。
我的设置
我的 webpack 实例有 2 个主要配置。一种用于开发(带有热重载),一种用于生产。我利用 webpack-merge 创建了一个 common.config,我最终将提取两个配置之间的共性(现在它相当空白)。在应用程序设置方面,我有一个在 Python 中单独运行的 API。
问题
在我的生产配置中,我使用 splitchunks 进行供应商/捆绑拆分以及一些最小化。它工作得很好。但是,当我尝试运行我的开发环境时,虽然它正在根据终端创建适当的开发包[即没有散列],但无法找到 index.html 文件(可能是因为 webpack-dev-中间件在内存中寻找东西)。结果,我看不到我的开发环境,也看不到任何热重载更改?以前我会使用 npm run build:production 生成所有捆绑文件,然后使用 NPM start。我想 dev-middleware 会将它的内存版本的 bundle.js 更改覆盖在我磁盘上的文件上,但是现在我在 prod 上使用散列文件名,我真的不能再这样做了吗?
Package.json 脚本
"scripts": {
"clean": "rimraf dist/*.{js,css,eot,woff,woff2,svg,ttf,jpg,map,json}",
"build":
"webpack -p --progress --verbose --colors --display-error-details --config webpack/common.config.js",
"build:production": "npm run clean && npm run build",
"flow": "flow",
"lint": "eslint src",
"start": "nodemon bin/server.js",
server.js 的相关部分
(function initWebpack() {
const webpack = require('webpack');
const webpackConfig = require('./webpack/common.config');
const compiler = webpack(webpackConfig);
app.use(
require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath,
}),
);
app.use(
require('webpack-hot-middleware')(compiler, {
log: console.log,
path: '/__webpack_hmr',
heartbeat: 10 * 1000,
}),
);
app.use(express.static(path.join(__dirname, '/')));
})();
app.get(/.*/, (req, res) => {
res.sendFile(path.join(__dirname, '/dist/index.html'));
});
common.config.js
const path = require('path');
const merge = require('webpack-merge');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
const development = require('./dev.config');
const production = require('./prod.config');
const TARGET = process.env.npm_lifecycle_event;
const PATHS = {
app: path.join(__dirname, '../src'),
build: path.join(__dirname, '../dist'),
nodeModulesDir: path.join(__dirname, 'node_modules'),
indexFile: path.join(__dirname, './src/index'),
};
process.env.BABEL_ENV = TARGET;
const common = {
entry: [PATHS.app],
output: {
path: PATHS.build,
},
};
if (TARGET === 'start' || !TARGET) {
module.exports = merge(development, common);
}
if (TARGET === 'build' || !TARGET) {
module.exports = merge(production, common);
}
dev.config.js
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
require('babel-polyfill').default;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PATHS = {
app: path.join(__dirname, '../src'),
};
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: ['webpack-hot-middleware/client', './src/index'],
mode: 'development',
output: {
publicPath: '/dist/',
},
resolve: {
extensions: ['.jsx', '.js', '.json', '.scss', '.less'],
modules: ['node_modules', PATHS.app],
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
'postcss-loader',
],
},
{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
},
},
'postcss-loader',
'sass-loader',
],
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
},
},
'postcss-loader',
{
loader: 'less-loader',
options: {
//addlater
},
},
],
},
{
test: /bootstrap-sass\/assets\/javascripts\//,
use: [
{
loader: 'imports-loader',
options: {
jQuery: 'jquery',
},
},
],
},
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: '$',
},
{
loader: 'expose-loader',
options: 'jQuery',
},
],
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 50000,
mimetype: 'application/font-woff',
},
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
},
__DEVELOPMENT__: true,
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
jQuery: 'jquery',
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index_template.html',
}),
],
};
这是使用 npm run build:production 后我的 index.html 文件的示例。如您所见,index.html 的内存版本可能无法再与散列文件名一起使用?
<link href="/dist/vendor.a85f.css" rel="stylesheet"><link href="/dist/main.4d1e.css" rel="stylesheet"></head>
<body>
<div id="root"></div>
<script type="text/javascript" src="/dist/manifest.81a7.js"></script><script type="text/javascript" src="/dist/vendor.99aa.js"></script><script type="text/javascript" src="/dist/main.6eb4.js"></script></body>
其他注意事项:
- 在最新版本的 webpack 4 上。
- 我的生产版本工作正常
非常感谢任何帮助。
更新:我已将 rimraf dist 换成干净的 webpack 插件并将其移至我的 common.config。这样,在每次构建时,它都会在生成 index.html 之前进行清理。但是,我注意到当我使用 npm start 时,终端中的输出显示文件已发出......我在任何地方都找不到它们?在调查了 webpack-dev-middleware 之后,似乎他们将东西存储在内存中. 这大概是核心问题。如果 htmlwebpack 插件在内存中或者我可能需要维护一个单独的 index.html 文件,我如何将它与 dev-middleware 之类的东西联系在一起?我猜这个流程之前工作的原因是因为我对 prod 和 dev 都有 bundle.js 的静态名称,所以内存版本没有问题。现在这些名称是从 prod 版本中散列的......它不知道该怎么做?