Flutter Web 打包为哈希资源

Flutter Web资源哈希处理的自动化

在当今快速变化的互联网时代,Web应用的持续迭代和实时更新是提供优质用户体验的关键因素。作为一个flutter开发,你会希望用户在每次访问你的网站时,都能无缝体验到最新的功能和内容。然而,一个常见的挑战是,当你部署了更新后的Web应用,用户可能需要清除浏览器缓存才能看到最新的更改。这不仅影响用户体验,也增加了用户支持的负担。

为了克服这个问题,自动化资源哈希处理成为了一种有效的解决策略。通过在资源文件名中添加哈希值,我们可以确保浏览器在每次部署后都加载最新的资源,而无需用户手动清除缓存。这项技术利用了浏览器对文件名变化的敏感性,通过改变文件名来提示浏览器获取更新的内容。接下来,让我们探讨如何在Flutter Web项目中实现资源哈希处理的自动化,以确保即使频繁更新,用户也总是访问到最新版本的应用。

为什么需要资源哈希处理?

Web应用的一个常见问题是浏览器缓存,它可以加快网页加载速度,但也可能导致用户无法即时看到更新的内容。通过为文件名添加哈希值,我们可以使每次文件内容更改时文件名都不同,从而绕过浏览器缓存,确保用户总是加载到最新的文件。

自动化资源哈希处理流程

在Flutter Web项目中实现资源哈希处理,主要涉及以下步骤:

1. 自动化构建

使用Flutter命令行工具进行项目构建,并生成的资源文件位于build/web目录中。

2. 脚本处理资源文件

编写一个Node.js脚本add_hashes.js,该脚本用于计算资源文件的哈希值,并重命名文件,以包含这个哈希值。这个过程包括两个主要功能:

  • 注意放根目录
  • 计算哈希值:对每个指定的资源文件内容计算哈希值。
  • 文件重命名 :将计算得到的哈希值添加到文件名中,例如将main.dart.js重命名为 main.dart.12345678.js
  • 这里实现直接使用了 随机数实现类似hsah的效果
ini 复制代码
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");

function generateRandomHash() {
  // 生成一个4字节的随机数,转换为8位16进制数
  return crypto.randomBytes(4).toString("hex");
}

function addHashToFilename(filePath) {
  const hash = generateRandomHash();
  const parsedPath = path.parse(filePath);
  const newPath = `${parsedPath.dir}/${parsedPath.name}.${hash}${parsedPath.ext}`;
  fs.renameSync(filePath, newPath);
  return newPath;
}

function updateFileReferences(filesToUpdate, newPaths) {
  filesToUpdate.forEach((fileToUpdate) => {
    if (fs.existsSync(fileToUpdate)) {
      let content = fs.readFileSync(fileToUpdate, "utf8");
      newPaths.forEach((path) => {
        const regex = new RegExp(path.original.replace(".", "\\."), "g");
        content = content.replace(regex, path.new);
      });
      fs.writeFileSync(fileToUpdate, content);
    }
  });
}

const filesToHash = ["main.dart.js", "flutter.js"];
const newPaths = filesToHash.map((file) => {
  const originalFilePath = `build/web/${file}`;
  if (fs.existsSync(originalFilePath)) {
    const newFilePath = addHashToFilename(originalFilePath);
    return { original: file, new: path.basename(newFilePath) };
  } else {
    return { original: file, new: file };
  }
});

updateFileReferences(["build/web/index.html"], newPaths);

const filesToUpdate = ["build/web/flutter_service_worker.js"];
newPaths.forEach((pathInfo) => {
  if (pathInfo.original !== pathInfo.new) {
    filesToUpdate.push(`build/web/${pathInfo.new}`);
  }
});

updateFileReferences(filesToUpdate, newPaths);

3. 更新引用

更新index.html和其他可能引用了被哈希处理的文件的HTML或JavaScript文件,以确保它们引用新的文件名。

4. 构建自动化脚本

package.json中,定义自动化脚本来串联整个过程:

perl 复制代码
{
  "desc": "请使用build 命令打包,会将所有的资源随机字符串命名处理 ,这样客户端不用清缓存也能得到最新的资源!",
  "scripts": {
    "build": "flutter clean && flutter create . && flutter build web --web-renderer canvaskit --release && node add_hashes.js && npm run zip",
    "zip": "zip_name=app_h5 && current_date=$(date +\"%y_%m月_%d日_%H点%M\") && cd build && zip -r \"${zip_name}_$current_date.zip\" web && echo ---${zip_name}打包完成----"
  }
}

这里的deploy脚本就封装了整个流程,从构建到哈希处理,再到最终的部署。

5. 运行打包

请确保安装了Node.js

arduino 复制代码
npm run build

下图为为打包后的样子

部署和缓存控制

在部署更新后的Flutter Web应用时,我们需要确保服务器或CDN能够理解并尊重新文件的哈希值。通常,这涉及到配置HTTP响应头,特别是Cache-Control头,来指导浏览器正确地缓存资源。

同时,如果应用了Service Worker,它的缓存策略也需要相应更新,以便于它能够抓取并缓存新的资源文件,同时废弃旧的资源文件。

结语

通过自动化资源哈希处理,我们能够有效地解决Flutter Web应用的缓存问题,确保每次部署都能够即时地为用户提供最新的内容。这不仅提高了用户体验,也简化了开发和部署流程,使得管理Web应用的资源变得更加高效和可靠。 Flutter Web打包哈希, Flutter Web 打包 hash, Flutter Web hash

相关推荐
2401_8827275728 分钟前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
NoneCoder31 分钟前
CSS系列(36)-- Containment详解
前端·css
anyup_前端梦工厂42 分钟前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand1 小时前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui
GDAL1 小时前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿1 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫2 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
m0_748256142 小时前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
小白学前端6663 小时前
React Router 深入指南:从入门到进阶
前端·react.js·react
web130933203983 小时前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端