5

我有一个简单的 Maven webapp,它使用单个 JSP 和 RequireJS 来提供单页 Javascript-heavy 应用程序。我一直在寻找可以在构建过程中用来对资产进行指纹识别的东西(.js、.css 等),但没有找到任何可以解决这个问题的东西。

我希望在内容更改时更改资产文件名,以便我可以告诉浏览器将它们缓存很长时间,但仍会在它们更改时下载最新的。我还需要对这些资产的任何引用,以便在它们更改时进行更新。无论我使用什么,都必须与 RequireJS 一起使用。

有什么建议么?

4

2 回答 2

2

我最近通过使用 RequireJS 的urlArgs配置选项解决了这个问题。我怀疑实际上重命名文件以包含时间戳是否可行,这会使构建和 RequireJS 配置复杂化很多,并且很可能需要 hack 来进行开发或生产。所以,按逻辑顺序:

  1. 在 pom.xml 中:

    <properties>
        (...)
        <build.version>${maven.build.timestamp}</build.version>
    </properties>
    
  2. 在主 JSP 文件中:

    <script type="text/javascript">
        var require = {
            (...)
            urlArgs: 'v=${build.version}',
        };
    </script>
    
    <link rel="stylesheet" type="text/css" href="style.css?v=${build.version}"></link>    
    <script data-main="app" src="libs/require.js?v=${build.version}"></script>
    

    在 require.js 导入之前定义require对象以使 urlArgs 工作很重要

  3. pom.xml,再次:

    <resources>
      (...)
      <resource>
        <targetPath>${project.build.directory}/filteredWebapp</targetPath>
        <directory>src/main/webapp</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
    
  4. r.js 的 buildconfig(顺便说一句。我正在使用 requirejs-maven-plugin来桥接 Maven 和 r.js):

    ({
        appDir: '${project.build.directory}/filteredWebapp',
        dir: '${project.build.directory}/${project.build.finalName}',
        (...)
    })
    

    我必须将过滤 src/main/webapp 的结果存储在一个新文件夹(即filteredWebapp)中,以确保 r.js 的输入已经包含构建时间戳而不是占位符。我最初的 r.js buildconfig 版本是直接从 src/main/webapp 读取源文件;工作正常,但绕过了 maven 过滤(即 r.js 编译的输出仍然包含${build.timestamp}占位符)

注意:配置开发版本以使用这种机制可能很棘手(如果可能的话,我还没有尝试过)。不过,对我来说,“v=${build.timestamp}”参数的存在和缓存破坏的缺乏在实践中并不是问题。

在此过程中还有许多其他障碍和陷阱,但我假设您设法解决了这些问题,因为您只是专门要求指纹识别。希望有帮助!

于 2013-02-03T20:32:04.947 回答
1

实际上,我强烈反对将查询参数用作“缓存杀手”,因为这可能会导致所谓的缓存中毒。例如:假设您有一个 cdn 或一个前端缓存服务器和多个应用程序服务器。您上传文件的新版本并更改查询参数。但是新文件仍然没有。交付给所有应用服务器。缓存服务器然后转到仍然包含旧版本的服务器之一(因为它看到查询参数已更改),获取并缓存它。所以现在缓存服务器有一个旧文件,一个新的缓存杀手认为它是最新的,不再尝试从服务器获取它。

于 2013-12-31T06:54:49.190 回答