将Htmlwebpackplugin与Webpack-Dev-Middleware一起使用

时间:2018-08-13 19:36:00

标签: javascript webpack html-webpack-plugin hot-module-replacement webpack-hot-middleware

简短摘要

由于dev-middleware依赖于内存中的文件,因此无法将htmlwebpackplugin功能与webpack-dev-middleware结合使用吗?文章底部的脚本输出的屏幕截图。因为我选择在生产配置中实现缓存哈希文件名,所以我似乎再也不能使用dev-middleware。

我的设置

我的webpack实例有2种主要配置。一种用于开发(带热装),另一种用于生产。我利用webpack-merge创建common.config,最终将提取这两种配置之间的共性(目前为止还很空白)。在应用设置方面,我有一个在Python中单独运行的API。

问题

在生产配置中,我使用splitchunks进行供应商/捆绑包拆分以及一些最小化。它工作得很好。但是,当我尝试运行自己的开发环境时,尽管它正在为开发创建适当的捆绑软件[即根据终端],找不到index.html文件(可能是因为webpack-dev-middleware在内存中寻找东西)。结果,我看不到我的开发环境,也看不到任何热重载更改?以前,我将使用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。
  • 我的生产版本运行正常

非常感谢任何帮助。

Output when I run build:production Output when I run npm start

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

0 个答案:

没有答案