Реагировать на кеширование приложения
Я новичок в 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,
},