在grunt-usemin的配置和使用中,很难理解路径是如何处理的。
我有以下存储库布局,其中存储库根也将是 Web 应用程序根:
/dashboard/index.html
/Gruntfile.js
/vendor/...some 3rd party CSS and JS...
所以索引.html文件 -> somedomain.com/dashboard/index.html。
index.html 文件包含/vendor 文件夹中的一些 CSS 和 JS 资产。 我已经配置了咕噜声以将构建输出放在构建文件夹中:
/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.min.css/js"路径包含在索引中.html。
问题是,grunt-usemin 似乎正在使用我为两个上下文指定的"app.min.*"路径,使它们无法协同工作:
1(它将路径视为相对于构建目录的路径,以便创建文件;这些文件最终位于build/app.min.css和build/app.min.js中。
2(它将路径视为相对于索引.html文件的路径,以便生成新的链接/脚本标签;浏览器加载 build/dashboard/index.html,然后尝试加载"app.min.css",映射到build/dashboard/app.min.css。
有解决办法吗?
我真的迟到了,但我对这个问题也非常沮丧,没有找到任何令人满意的修复或解决方法。所以我想出了一些非常肮脏的技巧,希望能更好地解决这个问题。所以我想和大家分享一下。
首先,让我们快速回顾一下为什么会出现此问题。当 usemin 生成输出 JS/CSS 文件时,它会在 dest
目录和您在 usemin 块中指定的输出目录之间执行简单的路径联接。因此,如果dest
是build
并且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文件所在的位置怎么办?这不会解决这个问题吗?所以给定上面的例子,如果dest
是build/dashboard
怎么办?您可以看到它将吐出输出文件位置并正确链接。请记住,您应该创建一个复制任务来复制您的 HTML 文件,因此请确保您的 HTML 文件像以前一样复制到build/dashboard/index.html
。
当然,下一个问题是如果我在多个目录中有 HTML 文件怎么办?为每个目录(HTML 文件可以驻留(创建一个 useminPrepare 目标不是非常痛苦和不直观吗?这就是为什么我在创建自己的咕噜声脚手架时创建了一个非常特殊的咕噜声任务,只是为了解决这个问题。我称之为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文件,则也将包括生成的HTML文件。因此,要么在它们之前清理它们,要么在目录下查看dashboard
。我建议将src
目录和dest
目录分开,以便配置看起来更直观。
我不喜欢它,但到目前为止我发现让它工作的唯一方法是指定一个完整路径:
<!-- build:css(.) /dashboard/app.min.css -->
<!-- build:js(.) /dashboard/app.min.js -->
导致 app* 文件与索引一起位于/build/dashboard 中.html(这是我想要它们的地方(和 index.html 最终带有以下标签:
<link rel="stylesheet" href="/dashboard/app.min.css">
<script src="/dashboard/app.min.js"></script>
这意味着仪表板应用程序现在敏锐地意识到它在整体中的位置,因此您不能在不更新这些路径的情况下重命名或重新定位它在树中的位置。