【问题标题】:grunt-usemin block paths not relative to html file?grunt-usemin 块路径不相对于 html 文件?
【发布时间】:2013-09-25 20:48:26
【问题描述】:

很难理解在 grunt-usemin 的配置和使用中的不同点如何处理路径。

我有以下 repo 布局,其中 repo 根也将是 web 应用程序根:

/dashboard/index.html
/Gruntfile.js
/vendor/...some 3rd party CSS and JS...

所以 index.html 文件 -> somedomain.com/dashboard/index.html.

index.html 文件包含来自 /vendor 文件夹的一些 CSS 和 JS 资产。我已将 grunt 配置为将构建输出放在构建文件夹中:

/build/dashboard/index.html

在 index.html 文件中,我用 usemin 块包裹了所有 CSS 链接和 JS 脚本标签:

<!-- build:css(.) app.min.css -->
<!-- build:js(.) app.min.js -->

我必须用“(.)”指定一个“替代搜索路径”,以便“/vendor/backbone.js”的脚本标签可以在正确的位置找到它。在我这样做之前,它一直在寻找 /dashboard/vendor/backbone.js。

我希望将处理 CSS/JS 资产的输出输出到 build/dashboard/app.min.css 和 build/dashboard/app.min.js,并使用简单的相对“app”包含在 index.html 中.min.css/js" 路径。

问题是,grunt-usemin 似乎正在使用我为这两个上下文指定的“app.min.*”路径,这使得它们无法一起工作:

1) 出于创建文件的目的,它将路径视为相对于构建目录的路径;这些文件最终位于 build/app.min.css 和 build/app.min.js 中。

2) 将路径视为相对于 index.html 文件的路径,以生成新的链接/脚本标签;浏览器加载 build/dashboard/index.html,然后尝试加载映射到 build/dashboard/app.min.css 的“app.min.css”。

有解决办法吗?

【问题讨论】:

    标签: node.js gruntjs yeoman grunt-usemin


    【解决方案1】:

    我真的迟到了,但我也对这个问题感到非常沮丧,没有找到任何令人满意的修复或解决方法。所以我想出了一些非常肮脏的技巧,希望能更好地解决这个问题。所以想和大家分享一下。

    首先,让我们快速回顾一下为什么会出现这个问题。当 usemin 生成输出 JS/CSS 文件时,它会在您的 dest 目录和您在 usemin 块中指定的输出目录之间执行简单的路径连接。所以如果destbuild 而usemin 块是

    <!-- build:css(.) app.min.css -->
    

    然后它将buildapp.min.css 连接起来以在build/app.min.css 处输出输出文件

    但随后 usemin 任务只是将块中的路径替换为您最终的路径

    <link rel="stylesheet" href="app.min.css"/>
    

    现在链接错误的目录,因为您的 HTML 文件位于 build/dashboard/index.html

    所以我的工作围绕着这个想法展开:如果dest 目录与 HTML 文件所在的位置相关怎么办?这不是解决这个问题吗?那么在上面的例子中,如果destbuild/dashboard 呢?您可以看到它会吐出输出文件位置并正确链接。请记住,您应该创建一个复制任务来复制您的 HTML 文件,因此请确保您的 HTML 文件像以前一样复制到build/dashboard/index.html

    当然,下一个问题是如果我在多个目录中有 HTML 文件怎么办?为 HTML 文件所在的每个目录创建一个 useminPrepare 目标不是非常痛苦和不直观吗?这就是为什么我在创建自己的 grunt 脚手架时创建了一个非常特殊的 grunt 任务来解决这个问题。我称它为useminPreparePrepare 是的,它是故意命名为愚蠢的,因为我希望有一天当用户对这个问题进行实际修复时,我会完全删除这个东西。

    顾名思义,这是一项准备 useminPrepare 配置的任务。它完全符合我上面的描述。它的所有配置都反映了 useminPrepare 配置(实际上,它们中的大多数只是简单地复制到 useminPrepare),但有一个例外:您需要指定一个 src 目录来标识所有源的根目录,以便它可以生成HTML 文件的相对路径。所以在你的例子中src: "." 会很好。要使用 useminPreparePrepare,首先将其导入您的构建(您可能只想复制并粘贴我的代码,我不介意),将您的 useminPrepare 任务重命名为 useminPreparePrepare 并添加我刚才提到的 src 属性。确保使用您喜欢的任何目标运行 useminPreparePrepare,然后立即运行 useminPrepare 而不指定目标,以便运行它的 所有 目标。这是因为 useminPreparePrepare 将为每个与找到 HTML 文件的位置相关的目录生成一个目标,并复制您运行的 useminPreparePrepare 目标的配置。这样,您的配置可以简单地查找所有 HTML 文件。

    例子

    "useminPreparePrepare": {
        // Search for HTML files under dashboard even though src is .
        // because we want to avoid including files generated under build directory.
        html: "dashboard/**/*.html",
        options: {
            src: ".",
            dest: "build",
            ...
    
    "usemin": {
        html: ["build/**/*.html"],
        ...
    
    "copy": {
        html: {
            files: [{
                    expand: true,
                    src: ["dashboard/**/*.html"],
                    dest: "build"
                }
            ]
        },
        ...
    

    希望这会有所帮助!祝你有美好的一天。

    编辑:我意识到在上面的例子中,如果你实际上包含了当前目录中的所有 HTML 文件,如果没有提前清理它们,你也会包含生成的 HTML 文件。因此,要么在它们之前清理它们,要么在 dashboard 目录下查看。我建议将srcdest 目录分开,以便配置看起来更直观。

    【讨论】:

      【解决方案2】:

      我不喜欢它,但到目前为止我发现让它工作的唯一方法是指定一个完整路径:

      <!-- build:css(.) /dashboard/app.min.css -->
      <!-- build:js(.) /dashboard/app.min.js -->
      

      导致 app* 文件位于 /build/dashboard 旁边的 index.html(我想要它们的位置)中,并且 index.html 最终带有以下标签:

      <link rel="stylesheet" href="/dashboard/app.min.css">
      <script src="/dashboard/app.min.js"></script>
      

      这意味着仪表板应用现在可以敏锐地意识到它在整体中的位置,因此您不能在不更新这些路径的情况下重命名或重新定位它在树中的位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-25
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 2015-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多