1

简短的摘要

由于 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 上。
  • 我的生产版本工作正常

非常感谢任何帮助。

运行 build:production 时的输出 当我运行 npm start 时输出

更新:我已将 rimraf dist 换成干净的 webpack 插件并将其移至我的 common.config。这样,在每次构建时,它都会在生成 index.html 之前进行清理。但是,我注意到当我使用 npm start 时,终端中的输出显示文件已发出......我在任何地方都找不到它们?在调查了 webpack-dev-middleware 之后,似乎他们将东西存储在内存中. 这大概是核心问题。如果 htmlwebpack 插件在内存中或者我可能需要维护一个单独的 index.html 文件,我如何将它与 dev-middleware 之类的东西联系在一起?我猜这个流程之前工作的原因是因为我对 prod 和 dev 都有 bundle.js 的静态名称,所以内存版本没有问题。现在这些名称是从 prod 版本中散列的......它不知道该怎么做?

4

0 回答 0