Реагировать на кеширование приложения

Я новичок в React. У меня есть приложение React, которое недавно отправлено в производство. Были некоторые исправления веб-интерфейса и снова запущены в производство. Но он показывает ту же страницу после новой сборки. Это берет из кеша. Но если я удаляю кеш, он работает.

Использование реактивного шаблона ( https://github.com/react-boilerplate/react-boilerplate)

Я попытался найти работника службы и res.header(кэш-контроль). Но, похоже, ничего не работает.

Ниже мой файл prod webpack

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const OfflinePlugin = require('offline-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const webpack = require('webpack');
const S3Plugin = require('webpack-s3-plugin');
// const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const config = require('../../app/config');

module.exports = require('./webpack.base.babel')({
  mode: 'production',

  // In production, we skip all hot-reloading stuff
  entry: [
    require.resolve('react-app-polyfill/ie11'),
    path.join(process.cwd(), 'app/app.js'),
  ],

  // Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].chunk.js',
  },

  // optimization: {
  //   minimize: true,
  //   minimizer: [
  //     new TerserPlugin({
  //       terserOptions: {
  //         warnings: false,
  //         compress: {
  //           comparisons: false,
  //         },
  //         parse: {},
  //         mangle: true,
  //         output: {
  //           comments: false,
  //           ascii_only: true,
  //         },
  //       },
  //       parallel: true,
  //       cache: true,
  //       sourceMap: true,
  //     }),
  //   ],
  //   nodeEnv: 'production',
  //   sideEffects: true,
  //   concatenateModules: true,
  //   splitChunks: {
  //     chunks: 'all',
  //     minSize: 30000,
  //     minChunks: 1,
  //     maxAsyncRequests: 5,
  //     maxInitialRequests: 3,
  //     name: true,
  //     cacheGroups: {
  //       commons: {
  //         test: /[\\/]node_modules[\\/]/,
  //         name: 'vendor',
  //         chunks: 'all',
  //       },
  //       main: {
  //         chunks: 'all',
  //         minChunks: 2,
  //         reuseExistingChunk: true,
  //         enforce: true,
  //       },
  //     },
  //   },
  //   runtimeChunk: true,
  // },

  plugins: [
    // Minify and optimize the index.html
    new HtmlWebpackPlugin({
      template: 'app/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
      inject: true,
    }),
    new S3Plugin({
      exclude: /.*\.html$/,
      s3Options: {
        accessKeyId: config.aws.s3.aws_access_key_id,
        secretAccessKey: config.aws.s3.aws_secret_access_key,
        region: 'us-west-2',
      },
      s3UploadOptions: {
        Bucket: config.aws.s3.bucket,
      },
    }),

    // Put it in the end to capture all the HtmlWebpackPlugin's
    // assets manipulations and do leak its manipulations to HtmlWebpackPlugin
    new OfflinePlugin({
      relativePaths: false,
      publicPath: '/',
      appShell: '/',

      // No need to cache .htaccess. See http://mxs.is/googmp,
      // this is applied before any match in `caches` section
      excludes: ['.htaccess'],

      caches: {
        main: [':rest:'],

        // All chunks marked as `additional`, loaded after main section
        // and do not prevent SW to install. Change to `optional` if
        // do not want them to be preloaded at all (cached only when first loaded)
        additional: ['*.chunk.js'],
      },

      // Removes warning for about `additional` section usage
      safeToUseOptionalCaches: true,
      AppCache: false,

      ServiceWorker: {
        events: true,
        publicPath: '/sw.js',
        navigateFallbackURL: '/',
        prefetchRequest: {},
      },
      // Hack
      // This is to skip the warning that OfflinePlugin throws if sw registration is not done
      __tests: {
        ignoreRuntime: true,
      },
    }),

    new CompressionPlugin({
      algorithm: 'gzip',
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8,
    }),

    new WebpackPwaManifest({
      name: 'React Boilerplate',
      short_name: 'React BP',
      description: 'My React Boilerplate-based project!',
      background_color: '#fafafa',
      theme_color: '#b1624d',
      inject: true,
      ios: true,
      icons: [
        {
          src: path.resolve('app/images/icon-512x512.png'),
          sizes: [72, 96, 128, 144, 192, 384, 512],
        },
        {
          src: path.resolve('app/images/icon-512x512.png'),
          sizes: [120, 152, 167, 180],
          ios: true,
        },
      ],
    }),

    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/),

    new HashedModuleIdsPlugin({
      hashFunction: 'sha256',
      hashDigest: 'hex',
      hashDigestLength: 20,
    }),
  ],

  performance: {
    assetFilter: assetFilename =>
      !/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename),
  },
});```

2 ответа

Используйте webpack и используйте хеширование (и добавьте его к именам файлов) для генерации файлов.

Следовательно, всякий раз, когда вы перестраиваете приложение и внедряете его в производство, эти хэшированные файлы не будут присутствовать в кеше, и у вас больше не будет проблем с кешем.

Вы можете отключить кеширование, если оно вам не нужно, но я предполагаю, что здесь вы хотели обновить кеш при новых развертываниях, пожалуйста, попробуйте ниже

app/app.js — в конце файла

      if (process.env.NODE_ENV === 'production') {
  require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}

заменить

      if (process.env.NODE_ENV === 'production') {
  const runtime = require('offline-plugin/runtime'); // eslint-disable-line global-require
  runtime.install({
    onUpdating: () => {
      console.log('SW Event:', 'onUpdating');
    },
    onUpdateReady: () => {
      console.log('SW Event:', 'onUpdateReady');
      // Tells to new SW to take control immediately
      runtime.applyUpdate();
    },
    onUpdated: () => {
      console.log('SW Event:', 'onUpdated');
      // Reload the webpage to load into the new version
      window.location.reload();
    },

    onUpdateFailed: () => {
      console.log('SW Event:', 'onUpdateFailed');
    },
  });
}

внутренности/webpack/webpack.prod.babel.js

добавить строку 90 под новый OfflinePlugin({

      ServiceWorker: {
        events: true,
      },
Другие вопросы по тегам