Open MikaelEdebro opened 6 years ago
Ok I think I have narrowed it down to the service-worker. If I check Application > Service Workers > Bypass for network, the site works again after soft refresh.
Any ideas?
If I npm run build
, and host it on localhost with serve
, the service worker doesn't cause any issues.
For localhost, it says "from Service Worker" in the Size column (in Network tab). For UAT environment (where the issue appears), it says "from Disk Cache" https://imgur.com/a/puDOr
Does this happen in production builds? Pretty sure this is somehow related to webpack-dev-server
's hot reload client script and so not something that should be of any concern.
@MaxMilton Yes this is in prod builds. Just a question. The service-worker is supposed to cache index html right? And I assume that it picks up on CommonChunksPlugins hash changes?
Cause what I think I'm experiencing is that index.html is cached, but after a new deploy, the bundles in the cached index.html are no longer there (due to changes in file name hash).
However I might add that this is a bit of a modified setup. We're building a multi-tenant app, so we're creating an index.html for each tenant (and later in our build pipeline rename for example /dist/templates/UAT-AWS/index.TenantName.html --> /dist/index.html
). Does it affect the "cache busting" of the SW if index.html is not really existing on disk?
I mean, will the precache plugin not update the cacheId/hash if index.html is not created?
I'll just post our webpack.prod.config.js:
'use strict'
const fs = require('fs')
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const loadMinified = require('./load-minified')
const env = config.build.env
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
new CleanWebpackPlugin(['dist'], { root: path.join(__dirname, '..') }),
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom assets
new CopyWebpackPlugin([
{ from: path.resolve(__dirname, '../static/tracking'), to: '' },
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{ from: path.resolve(__dirname, '../Dockerfile'), to: '' },
{ from: path.resolve(__dirname, '../.dockerignore'), to: '' },
{ from: path.resolve(__dirname, '../../docker/configure-fe-runtime.sh'), to: '' }
]),
// service worker caching
new SWPrecacheWebpackPlugin({
cacheId: 'booksecure-service-worker',
filename: 'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,html,css}'],
minify: true,
stripPrefix: 'dist/'
})
]
})
for (let environment of config.build.environments) {
for (let tenant of config.build.tenants) {
let runtimeConfig = require(`../config/runtime/${environment}/runtime-config.${tenant}.js`)
webpackConfig.plugins.push(
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: `${config.build.assetsRoot}/templates/${environment}/index.${tenant}.html`, // yes, no .html extension to not let these files be served.
template: 'index.html',
inject: true,
tenant: tenant,
runtimeConfig: `
<script id="runtimeConfig" type="text/javascript">
window.runtimeConfig = {
apiHost: '${runtimeConfig.API_HOSTNAME}',
apiKey: '${runtimeConfig.API_KEY}'
}
</script>`,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency',
serviceWorkerLoader: `<script>${loadMinified(
path.join(__dirname, './service-worker-prod.js')
)}</script>`
})
)
}
}
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + config.build.productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
Okey guys! I've just verified that this is not actually a bug in the PWA template, but instead was related to the changes that we had made.
Since we were not creating a dist/index.html
, the sw-precache-webpack-plugin could not pick up on changes, so it's "cache id" was the same.
In service-worker.js:
var precacheConfig = [
['index.html', '91b2a317a09b223bf5a5582a5930069c'],
['static/css/app.3136db4aece9d70bd7458ade08e813c8.css', 'e685314d1221643e09338010621d36b5'],
['static/js/app.5a5b57a7c4b45cfcb1d8.js', '6045c0a02a2c055cefdb6d9d9e4574c7'],
['static/js/manifest.f52ceabe5f48b3ce1af2.js', 'fc67123c2142aea9e2dccf03ba3dbc5b'],
['static/js/vendor.85a0bf6fdf1309909410.js', 'e8f4ecbec293643c5f4b7b93744a4264']
],
Once we added back the creation of index.html, the hash/id updated correctly.
Glad to hear you found the culprit. It was a bit strange since I've not experienced it in any production builds before and I've worked on a lot of projects based on this template. Thanks for posting your solution too!
i met the same problem ,i want to know how did you handle this ,counld u please explain it in detail?
what did you do to let the hash/id update correctly? you said 'Once we added back the creation of index.html, the hash/id updated correctly.'
i don't understand exactly
waiting your reply thank you very much
app.use(express.static(path.join(__dirname, 'dist/
app.use(express.static(path.join(__dirname, 'dist/todos')));
after dist you should write the project name
See this guys https://github.com/webpack/webpack/issues/2882#issuecomment-280906981
You just need to add <base href="/" />
into the <head>
of your index.html
.
This resolved my problem. It may help you too.
Thanks
@MikaelEdebro Can you please review and close this issue.
Uncaught SyntaxError: Unexpected token <
means server already send index.html file to chrome, but server can't find your frontend static path.
app.use(express.static(path.join(__dirname, 'public/'))))
server use static path, solve problem.
I get the same issue but not on every refresh, only sometimes after I deploy the app.
From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g. chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with <
).
A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones.
Has anyone been in the same situation?
@Dinduks did you find a solution to your problem? I'm having a similar issue where I get the error sometimes after deploys.
I am having issues with this too. On every page refresh, the page gives this error. After a hard page refresh (ctrl + F5), it is fixed. Does someone know how to fix this?
I am getting the same error when I deploy a new version and but a user already logged in my SPA loads a module dynamically in the previous version. I guess I would need to trap those errors and force a reload
Hey @davidjnorth, I just noticed your message.
No I haven't found a solution yet. I experimented a few hours with different Google results, in vain.
I was thinking I'll just go the @pdemilly route and find some way to detect this problem then force a refresh.
What did you guys do?
Any idea to how to fix that? I am have a same issue
I will force refresh to fix the issue but this is a forced fix.
Any idea what is happening?
See this guys webpack/webpack#2882 (comment)
You just need to add
<base href="/" />
into the<head>
of myindex.html
. This resolved my problem. It may help you too.Thanks
Man this has saved my life. For my situation, I deploy my react client on express as the documentation of create-react-app said. Everything works fine, except when I refreshing a page whose URL contains a param. I've searched for a whole day. This is the only way which solved my problem perfectly for now. Hope it will help you guys, too.
@Sonequa Thanks! Unfortunately that didn't work for me. I wonder if it's related to the fact that the error doesn't happen after every update for every users.
same issue here. already did this
You just need to add
of my index.html.into the
I get the same issue but not on every refresh, only sometimes after I deploy the app.
From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g.
chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with<
).A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones.
Has anyone been in the same situation?
@Dinduks You probably caches the index.html without the js files.
So, when you build (deploy) app the js files changes (sometimes). But index.html is loaded from cache and has references to old js files.
Error occurs sometimes because hash in the js files that you mentioned changes only when dependencies in package.json changes.
I get the same issue but not on every refresh, only sometimes after I deploy the app. From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g.
chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with<
). A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones. Has anyone been in the same situation?@Dinduks You probably caches the index.html without the js files.
So, when you build (deploy) app the js files changes (sometimes). But index.html is loaded from cache and has references to old js files.
Error occurs sometimes because hash in the js files that you mentioned changes only when dependencies in package.json changes.
A quick solution for this is to edit your index.html
file. I have added an attribute which i name it version in the meta tag and change its value in each deploy. For e.x: <meta version="1.0.1">
.
That causes a new index.html to be used without using the previous indexed one and solves the Unexpected token error.
Try adding <base href="/" />
into the <head>
in your index.html
This worked for me .
I get the same issue but not on every refresh, only sometimes after I deploy the app. From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g.
chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with<
). A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones. Has anyone been in the same situation?@Dinduks You probably caches the index.html without the js files. So, when you build (deploy) app the js files changes (sometimes). But index.html is loaded from cache and has references to old js files. Error occurs sometimes because hash in the js files that you mentioned changes only when dependencies in package.json changes.
A quick solution for this is to edit your
index.html
file. I have added an attribute which i name it version in the meta tag and change its value in each deploy. For e.x:<meta version="1.0.1">
. That causes a new index.html to be used without using the previous indexed one and solves the Unexpected token error.
I did the same here. It's quick and solves the issue.
Whenever I do a normal refresh, i get these error messages:
manifest.48cbf0211cc2b417df60.js:1 Uncaught SyntaxError: Unexpected token < vendor.e73f0cf5e42d1a1bdeee.js:1 Uncaught SyntaxError: Unexpected token < app.d644989e00d1de883ada.js:1 Uncaught SyntaxError: Unexpected token <
When looking in the Network tab, it´s like the entire HTML document (index.html) is being returned instead of the js file. https://imgur.com/a/6AR5P
I'm assuming this has to do with the src to the js-files are returning 404. Question is why though?
If I hit hard refresh (Ctrl + F5), the site loads fine.
Does anyone have any clues?
For us the issue was occurring because we had the build deployed on two instances. Sometimes the browser requested index.html from the Machine 1 and then asked the Machine 2 for styles and javascript which were different because of the difference in hashes when the build is built and minified.
@Dinduks
I get the same issue but not on every refresh, only sometimes after I deploy the app.
From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g.
chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with<
).A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones.
Has anyone been in the same situation?
Facing the same issue. Where you able to find a solution or a workaround for this ?
@Dinduks
I get the same issue but not on every refresh, only sometimes after I deploy the app. From what I understand, the first time I open the app it tries to load a JS files from the previous version (e.g.
chunk-9a00505e.02e15df7.js
), which doesn't exist anymore, and which serves a 404 HTML page (that obviously starts with<
). A refresh fixes this, except on progressive web apps on Safari because there is no reload button nor a "swipe down to refresh" action. It's very frustrating for users, as well as for me who asks them to restart their phones. Has anyone been in the same situation?Facing the same issue. Where you able to find a solution or a workaround for this ?
Are you deploying your build on multiple instances?
I am posting this in a hope help others incase if they reach this far and still have not found a fix. So along with many other issues, one possibility is if you are using html-webpack-plugin
, you may find my answer useful.
https://github.com/webpack/webpack-dev-middleware/issues/205
У меня возникает та же проблема, но не при каждом обновлении, а только иногда после развертывания приложения. Насколько я понимаю, при первом открытии приложения оно пытается загрузить файлы JS из предыдущей версии (например
chunk-9a00505e.02e15df7.js
), которая больше не существует и которая обслуживает HTML-страницу 404 (которая, очевидно, начинается с<
). Обновление исправляет это, за исключением прогрессивных веб-приложений в Safari, поскольку нет ни кнопки перезагрузки, ни действия «проведите вниз, чтобы обновить». Это очень расстраивает пользователей, а также меня, когда они просят перезагрузить свои телефоны. Кто-нибудь был в такой же ситуации?@DinduksВероятно, вы кэшируете index.html без файлов js. Итак, когда вы создаете (развертываете) приложение, файлы js меняются (иногда). Но index.html загружается из кеша и содержит ссылки на старые js-файлы. Иногда возникает ошибка, потому что хэш в js-файлах, о которых вы упомянули, меняется только при изменении зависимостей в package.json.
Быстрое решение для этого — отредактировать
index.html
файл. Я добавил атрибут, который я называю версией в метатеге, и меняю его значение при каждом развертывании. Например:<meta version="1.0.1">
. Это приводит к тому, что новый index.html используется без использования предыдущего проиндексированного и устраняет непредвиденную ошибку токена.Я сделал то же самое здесь. Это быстро и решает проблему.
Hi guys! I had the same problem and i solved it inserting "no-cache" headers to server responce index.html. I think the problem exist because browser has his own cache in addition to cacheStorage. Headers that i used:
Cache-control: cache-control: no-store, must-revalidate Expires: 0 Pragma: no-cache
I hope it will solve your problems
Whenever I do a normal refresh, i get these error messages:
When looking in the Network tab, it´s like the entire HTML document (index.html) is being returned instead of the js file. https://imgur.com/a/6AR5P
I'm assuming this has to do with the src to the js-files are returning 404. Question is why though?
If I hit hard refresh (Ctrl + F5), the site loads fine.
Does anyone have any clues?