grunt-usemin阻止路径与html文件无关?

时间:2013-09-25 20:48:26

标签: node.js gruntjs yeoman grunt-usemin

在grunt-usemin的配置和使用中,了解如何在各个点处理路径时遇到很多麻烦。

我有以下repo布局,其中repo root也将是web app root:

/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文件中,我有一些包含所有CSS链接和JS脚本标记的usemin块:

<!-- 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“path。

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

1)为了创建文件,它将路径视为相对于构建目录;文件最终在build / app.min.css和build / app.min.js。

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

有解决方案吗?

2 个答案:

答案 0 :(得分:3)

我参加派对的时间已经很晚了,但我对这个问题感到非常沮丧,并没有找到任何令人满意的修复或解决方法。所以我制定了一些非常肮脏的技巧,希望能更好地解决这个问题。所以我想和你分享。

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

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

然后它与build加入app.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目录分开,以便配置看起来更直观。

答案 1 :(得分: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>

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