【问题标题】:Much older version of my Website shows when rebuilding Production Bundle with Webpack使用 Webpack 重建 Production Bundle 时显示我的网站的旧版本
【发布时间】:2020-02-16 08:13:54
【问题描述】:

我注意到,当我使用 webpack 重建我的 node.js 应用程序的生产包时,浏览器中的站点会恢复为旧版本(稍后 300 多个 git 提交)。我使用 pm2 在我的 VPS 上运行我的网站。

如何在新的生产构建完成之前保持最旧的版本有效?

这是我的 webpack 设置:

    const { resolve } = require('path');
    const webpack = require('webpack');
    const CompressionPlugin = require('compression-webpack-plugin');
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

    const cssOutputLocation = process.env.NODE_ENV === 'production' ?
      'public/stylesheets/style-prod.css' :
      'stylesheets/style.css';

    const jsProdOutput = {
      filename: 'public/javascripts/build-prod.js',
      path: resolve(__dirname),
      publicPath: '/',
    };

    const jsDevOutput = {
      filename: 'javascripts/build.js',
      path: '/',
      publicPath: '/',
    };

    const jsOutputLocation = process.env.NODE_ENV === 'production' ? jsProdOutput : jsDevOutput;

    module.exports = {
      context: resolve(__dirname, 'src'),
      entry: [
        './index.jsx',
      ],
      output: jsOutputLocation,
      resolve: {
        extensions: ['.js', '.jsx'],
      },
      module: {
        rules: [
          {
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components|public\/)/,
            loader: 'babel-loader',
            query: {
              presets: ['es2015', 'es2017'],
            },
          },
          {
            test: /\.js?$/,
            exclude: /(node_modules|bower_components|public\/)/,
            loader: 'babel-loader',
            query: {
              presets: ['es2015', 'es2017'],
            },
          },
          {
            test: /\.css$/,
            use: ExtractTextPlugin.extract({
              fallback: 'style-loader',
              use: 'css-loader',
            }),
          },
          {
            test: /\.scss$/,
            use: ExtractTextPlugin.extract({
              use: [
                {
                  loader: 'css-loader',
                },
                {
                  loader: 'sass-loader',
                },
              ],
              fallback: 'style-loader',
            }),
          },
        ],
      },
      plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        new ExtractTextPlugin(cssOutputLocation),
        new BundleAnalyzerPlugin(),
        new webpack.ContextReplacementPlugin(/^\.\/locale$/, (context) => {
          if (!/\/moment\//.test(context.context)) { return; }
          // context needs to be modified in place
          Object.assign(context, {
            // include only CJK
            regExp: /^\.\/(nl|en-gb)/,
            // point to the locale data folder relative to moment's src/lib/locale
            request: '../../locale',
          });
        }),
      ],
    };

    if (process.env.NODE_ENV === 'production') {
      module.exports.plugins.push(new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false,
          screw_ie8: true,
          conditionals: true,
          unused: true,
          comparisons: true,
          sequences: true,
          dead_code: true,
          evaluate: true,
          if_return: true,
          join_vars: true,
        },
        output: {
          comments: false,
        },
      }));
      module.exports.plugins.push(new webpack.HashedModuleIdsPlugin());
      module.exports.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
      module.exports.plugins.push(
        new webpack.DefinePlugin(
          { 'process.env.NODE_ENV': JSON.stringify('production') },
        ),
      );
      module.exports.plugins.push(
        new CompressionPlugin({
          asset: '[path].gz[query]',
          algorithm: 'gzip',
          test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
          threshold: 10240,
          minRatio: 0.8,
        }),
      );
    }

    if (process.env.NODE_ENV !== 'production') {
      module.exports.entry.unshift(
        'react-hot-loader/patch',
        'react-hot-loader/babel',
        'webpack-hot-middleware/client',
      );
      module.exports.plugins.unshift(new webpack.HotModuleReplacementPlugin());
    }

【问题讨论】:

    标签: node.js npm webpack production-environment pm2


    【解决方案1】:

    您可以在输出配置的 filename 属性中使用 hash 占位符。

    const jsProdOutput = {
      filename: 'public/javascripts/build-prod-[hash].js',
      path: resolve(__dirname),
      publicPath: '/',
    };
    

    这样,您生成的文件将在每个构建中都是唯一的,并且不会被覆盖。

    【讨论】:

    • 感谢您的回复。但这如何解释我看到的是 1 年前的版本,而不是新版本之前的版本?
    • 因为将哈希添加到生成的文件名的整个过程是为了避免浏览器使用 1 年前输出文件的缓存版本。我的建议中缺少的一条是您必须指出您的 index.html 以加载正确的文件(具有最新哈希的文件)。
    • 我不确定这是我的问题。因为当我清空缓存时,我仍然看到那个旧版本。此外,即使我当前的 webpack 设置没有在包名称中使用哈希,我也不需要删除缓存来查看新版本的更新。
    • 如果不是浏览器缓存问题,请确保正在构建正确的源代码。
    猜你喜欢
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2020-01-05
    • 2011-10-04
    • 2020-10-18
    • 2013-01-27
    相关资源
    最近更新 更多