此问题仅在Netlify上的生产中发生。它不会出现在开发环境中。通常,我潜伏着寻找答案,或者将相关答案放在一起,但是这个让我很沮丧...
我有一个在Netlify上运行过的Vue CLI项目,该项目使用过去已部署的PWA进行设置。服务工作者应该正在运行,并且可以安装该应用程序以供离线使用。
现在它在控制台中给我这个错误:
Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://<domain>/_redirects?__WB_REVISION__=d38a2b58df330c85e0029eecf71d7c26","status":404}]
at l.o (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1749)
at async Promise.all (index 0)
at async l.install (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1221)
所以当工作箱执行此操作时,似乎将我的'_redirects'文件用404踢出了。
我已经尝试将_redirects更改为netlify.toml文件,并在.toml文件中以正确的格式设置了重定向内容,但仍然失败,只是将'netlify.toml'替换为'_redirects'中的错误消息相同错误。
我还尝试将相同的代码库部署到新的Netlify构建中(认为这可能是其资源的缓存问题),但是问题仍然存在。
我猜想这可能是Workbox的问题,要么无法编译资产,要么为与重定向相关的文件提供了错误的名称。但这也没有意义,因为当我在本地和Netlify生产环境中运行build命令时,它们都应由cdn上托管的相同代码处理。
这是从工作箱发送错误的代码块:
const isValidResponse = cacheWillUpdateCallback ?
// Use a callback if provided. It returns a truthy value if valid.
cacheWillUpdateCallback({event, request, response}) :
// Otherwise, default to considering any response status under 400 valid.
// This includes, by default, considering opaque responses valid.
response.status < 400;
// Consider this a failure, leading to the `install` handler failing, if
// we get back an invalid response.
if (!isValidResponse) {
throw new WorkboxError('bad-precaching-response', {
url,
status: response.status,
});
}
这是我的package.json:
{
"name": "<app-name>",
"version": "0.2.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"capacitor-copy": "vue-cli-service capacitor-copy",
"capacitor-init": "vue-cli-service capacitor-init",
"capacitor-open": "vue-cli-service capacitor-open",
"capacitor-update": "vue-cli-service capacitor-update",
"css:build": "postcss src/css/styles.css -o public/styles.css"
},
"dependencies": {
"@capacitor/cli": "^1.0.0-alpha.38",
"@capacitor/core": "^1.0.0-alpha.38",
"@fullhuman/postcss-purgecss": "^1.3.0",
"axios": "^0.19.1",
"core-js": "^3.4.4",
"moment": "^2.24.0",
"postcss": "^7.0.26",
"postcss-cli": "^6.1.3",
"register-service-worker": "^1.6.2",
"tailwindcss": "^1.1.4",
"vue": "^2.6.10",
"vue-router": "^3.1.3",
"vue-uuid": "^1.1.1",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.2",
"@vue/cli-plugin-eslint": "^4.2.2",
"@vue/cli-plugin-pwa": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.2",
"@vue/cli-plugin-vuex": "^4.2.2",
"@vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-cli-plugin-pwa": "^1.0.0-alpha.1",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
和我的manifest.json文件:
{
"short_name": "<name>",
"name": "<name>",
"description": "I have no idea what I'm doing with these build tools.",
"icons": [
{
"src": "./img/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "./img/icons/favicon-16x16.png",
"sizes": "16x16",
"type": "image/png"
},
{
"src": "./img/icons/favicon-32x32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "./img/icons/msapplication-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "./img/icons/safari-pinned-tab.png",
"sizes": "144x144",
"type": "image/png"
}
],
"start_url": ".",
"background_color": "#2d3748",
"display": "standalone",
"scope": "/",
"theme_color": "#2d3748"
}
并且index.html文件也可能有帮助:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="theme-color" content="#2d3748"/>
<link rel="manifest" href="manifest.json">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>styles.css">
<title>NAME</title>
</head>
<body>
<noscript>
<strong>This app doesn't work at all without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
老实说,我认为这与我的代码库无关。我认为配置将其部署到netlfiy时生成动态URL的工作箱将是一个问题。如前所述,“ npm run build”脚本在本地计算机上的构建没有问题。我很想知道最近是否有人在netlify或workbox上遇到这种错误。
非常感谢您的协助。
我发现了问题:这是我在测试时的想法,也发布在其他地方:
我需要已发布的生成目录中的_redirects文件,但是我想从生成的清单中排除该文件,服务工作者使用该清单来过滤流量到本地或Internet资产。因此,我将尝试为_redirects指定一个排除项
尝试:从此更改我的vue.config.js(vue CLI项目中webpack.config的代理):
module.exports = {
devServer: {
host: 'lite.bdfi.test'
},
pwa: {
name: 'BDFI',
themeColor: '#2d3748',
msTileColor: '#2d3748',
appleMobileWebAppCapable: 'no',
appleMobileWebAppStatusBarStyle: 'default',
manifestPath: 'manifest.json',
workboxPluginMode: 'GenerateSW'
}
}
为此:
module.exports = {
devServer: {
host: 'lite.bdfi.test'
},
pwa: {
name: 'BDFI',
themeColor: '#2d3748',
msTileColor: '#2d3748',
appleMobileWebAppCapable: 'no',
appleMobileWebAppStatusBarStyle: 'default',
manifestPath: 'manifest.json',
workboxPluginMode: 'InjectManifest',
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: 'service-worker.js',
// ...other Workbox options...
exclude: [/_redirects/],
}
}
}
这意味着我现在正在为服务人员指定输入,因此我需要从某个地方找服务人员。这是我的服务人员(这是自动生成的服务的精简版)
workbox.core.setCacheNameDetails({prefix: "lite-bdfi-app"});
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
构建后,与注入的清单和工作箱脚本相同:
importScripts("/precache-manifest.54b556dfe16cf1359c2f3257fa76ade9.js", "https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
而且,本地的'dist'目录也确认省略了'_redirects'文件。
现在,我在本地运行此构建,并在本地服务器中启动它,现在它会引发不同的错误。在本地,这从未发生过...
PrecacheController.mjs:194 Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"http://127.0.0.1:8887/css/app.159bf243.css.map?__WB_REVISION__=b04e3357da21d1241e39","status":404}]
at l.o (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1749)
at async Promise.all (index 0)
at async l.install (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1221)
n @ WorkboxError.mjs:30
o @ PrecacheController.mjs:194
看起来很熟悉,现在有5个,它们都在寻找扩展名为.map的文件…现在,我将从清单构建中删除.map文件,并查看其作用:
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: 'service-worker.js',
// ...other Workbox options...
exclude: [/\.map$/, /_redirects/], //this fixed it.
}
再次运行构建,检查dist文件夹清单,清单中不包含.map文件。然后使用已清除的缓存和本地存储检查应用的本地版本。那里没有错误……似乎很有希望。推送至GitHub。 Netlify构建触发器,不是自动发布的,因此请访问登台链接。寻找_redirects文件的页面加载没有更多错误。检查“ / invalid-url”的重定向,它会按预期转移到404页。发布部署后,我现在可以将应用程序作为PWA安装在桌面上。
问题已为我解决。希望以后对遇到相同问题的人有所帮助。