6

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

我有以下存储库布局,其中存储库根也将是 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.min.js”包含在 index.html 中。 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”。

有解决办法吗?

4

2 回答 2

3

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

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

<!-- 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是的,它是故意愚蠢地命名的,因为我希望有一天当 usemin 人对这个问题进行实际修复时,我会完全删除这个东西。

顾名思义,这是一项准备 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目录,以便配置看起来更直观。

于 2014-02-08T19:51:31.203 回答
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>

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

于 2013-09-25T20:56:26.640 回答