Blazor WASM PWA 无法更改图标,无法更改名称

Blazor WASM PWA Cannot Change Icon, Cannot Change Name

我正在努力解决一个案例,我已经很好地研究了如何做到这一点。它适用于所有人,但不适合我!!

环境:

因此,我创建了一个项目并从一开始就选择了渐进式 Web 应用程序 (PWA),以便自动生成我需要的一切。还使应用 ASP.NET 核心托管。

启动项目是 Rihal.Server 独立模式(不是 IIS 或 Docker)。

当我启动应用程序时,我在 Chrome 中收到默认提示以安装应用程序。当我单击“+”图标时,我会看到默认的 Blazor 图标和应用程序名称“Rihal”。到目前为止,一切都很好。当我更改图标和名称时,我仍然使用默认设置!

  1. 我已经尝试一个一个地清理和重建所有项目,没有错误。
  2. 我试过重新启动 Visual Studio。
  3. 我试过更改清单中的其他内容(例如背景颜色)以查看是否有任何变化,但没有任何变化。
  4. 我检查了生成操作(内容)。默认复制到输出目录是(不复制),更改为(始终复制)没有效果。

好像清单被完全忽略了。

我已经开发了这个应用程序的其他部分,然后过来更改图标和名称:

  1. 替换了默认图标(用于 192 的相同图标,但分辨率较低)

  2. 更新了我的 manifest.json 192 尺寸和 name/short 名称:(我也尝试添加多个尺寸)。

{
  "name": "Rihal Timesheet",
  "short_name": "Timesheet",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "icons": [
    {
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    },
    {
      "src": "icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    }
  ]
}

其他相关文件:

Rihal.Client服务-worker.js

// In development, always fetch from the network and do not enable offline support.
// This is because caching would make development more difficult (changes would not
// be reflected on the first load after each change).
self.addEventListener('fetch', () => { });

Rihal.Client 服务-worker.published.js

// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations

self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));

const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];

async function onInstall(event) {
    console.info('Service worker: Install');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
        .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
        .map(asset => new Request(asset.url, { integrity: asset.hash }));
    await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}

async function onActivate(event) {
    console.info('Service worker: Activate');

    // Delete unused caches
    const cacheKeys = await caches.keys();
    await Promise.all(cacheKeys
        .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName)
        .map(key => caches.delete(key)));
}

async function onFetch(event) {
    let cachedResponse = null;
    if (event.request.method === 'GET') {
        // For all navigation requests, try to serve index.html from cache
        // If you need some URLs to be server-rendered, edit the following check to exclude those URLs
        const shouldServeIndexHtml = event.request.mode === 'navigate';

        const request = shouldServeIndexHtml ? 'index.html' : event.request;
        const cache = await caches.open(cacheName);
        cachedResponse = await cache.match(request);
    }

    return cachedResponse || fetch(event.request);
}

Rihal.Client csproj 文件

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
    <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>embedded</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.2.0-preview3.20168.3" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.Authentication.WebAssembly.Msal" Version="3.2.0" />
    <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.5" />
    <PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Shared\Rihal.Shared.csproj" />
  </ItemGroup>

  <ItemGroup>
    <ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
  </ItemGroup>
</Project>

我认为您必须在任何时候希望客户端下载最新文件时增加缓存的版本。

在您的导航器中,在 const CACHE_VERSION = 1.01 中注册一个 JavaScript 文件。您可以在希望客户端更新时增加该值

https://blog.jeremylikness.com/blog/implement-progressive-web-app-hugo/

打开浏览器调试 window。 Chrome 或新的 Edge。当它打开时,右键单击页面上的刷新按钮 select => 清空缓存并重新加载。

我发现您可以在客户端 csproj 文件中执行此操作。在服务工作者中强制和更新。


<Target Name="PublishServiceWorker" AfterTargets="CopyFilesToPublishDirectory">
        <WriteLinesToFile File="$(PublishDir)wwwroot\service-worker.js" Lines="/* $([System.Guid]::NewGuid()) */" />
</Target>

所以我 运行 在 2020 年 11 月(VS2019 的所有更新)构建了一个新的 Blazor WASM PWA 时遇到了这个问题。我无法获取该站点或安装 PWA 以可靠地显示新内容。我写了一个小程序来修改service-worker.js中的离线缓存版本。我在客户端和服务器项目的 post 构建事件中调用此应用程序。因此,当我发布时,我的缓存版本总是会更新,并且 PWA 会按照我的预期进行更新。

static void Main(string[] args)
    {
        string startPoint = "const cacheName =";
        string endPoint = ";";
        string fileNameToEdit = args[0];
        string newContents = string.Empty;

        using(var sr = new StreamReader(fileNameToEdit))
        {
            newContents = sr.ReadToEnd();
            int start = newContents.IndexOf("const cacheName = ");
            int end = newContents.IndexOf(";", start) + 1;
            string stringToReplace = newContents.Substring(start, end - start);

            string newString = "const cacheName = 'cache-version-" + $"{DateTime.Now.Ticks}" + "';";

            newContents = newContents.Replace(stringToReplace, newString);

            sr.Close();
        }

        File.WriteAllText(fileNameToEdit, newContents);

        Environment.Exit(0);
    }