Gruntjs 我应该如何配置grunt usemin以使用相对路径

Gruntjs 我应该如何配置grunt usemin以使用相对路径,gruntjs,yeoman,assemble,grunt-usemin,Gruntjs,Yeoman,Assemble,Grunt Usemin,我有一个grunt项目,由一个yeoman生成器支持,我是基于构建的,如果有任何帮助,你可以在上面找到它 grunt项目使我们无法完成这项任务 我的项目涉及到建立一个多语言网站,为了保持网站的整洁,我决定将所有用一种语言编写的页面放在一个文件夹名中,该文件夹名位于该语言的两个字母的短码之后 | project/ |--dist/ |----en/ |------index.html |------404.html |------... |----fr/ |------index.html |--

我有一个grunt项目,由一个yeoman生成器支持,我是基于构建的,如果有任何帮助,你可以在上面找到它

grunt项目使我们无法完成这项任务

我的项目涉及到建立一个多语言网站,为了保持网站的整洁,我决定将所有用一种语言编写的页面放在一个文件夹名中,该文件夹名位于该语言的两个字母的短码之后

| project/
|--dist/
|----en/
|------index.html
|------404.html
|------...
|----fr/
|------index.html
|------404.html
|------...
这些文件由车把模板制作而成,并使用进行处理。在布局中,我有
usemin
的构建块,例如


在一个完美的世界里


但事实上,这只是一场表演


对我来说,这并不理想。
grunfile.js
的相关部分如下所示

useminPrepare:{
选项:{
目标:“”
},
html:[
“/fr/{,*/}*.html”,
“/en/{,*/}*.html”
]
},
usemin:{
选项:{
目录:['']
},
html:[
“/fr/{,*/}*.html”,
“/en/{,*/}*.html”
],
css:['/styles/{,*/}*.css']
}
我尝试过使用这个选项 通过将其设置为
以及将构建块更改为


但不幸的是,我们无法获得正确的输出

更具体地说,第一个没有改变任何东西,第二个将文件夹
scripts
styles
在层次结构中输出的级别太高

| project/
|--app/
|--dist/
|--styles/
|--scripts/
而不是

| project/
|--app/
|--dist/
|----styles/
|----scripts/

有谁知道该怎么办吗?这似乎是一个相当简单的用例,但我无法通过谷歌、GitHub等找到我需要的帮助…

我看到了很多关于这方面的问题,但没有真正的答案。在我的项目中,我已将“dist”文件夹映射到“/static”服务器端。所以我不需要在index.html中计算相对路径

但问题仍然在于usemin

<!-- build:css(.tmp) static/css/main.css -->
<link rel="stylesheet" href="css/main.css">
<!-- endbuild -->

我找到的唯一解决方法是不要触摸usemin块,运行grunt并手动更新路径。

如果我正确理解您的问题,我认为您需要“root”选项:

{
  useminPrepare: {
    html: 'html/index.html',
    options: {
    root: 'app'
    dest: 'dist'
    }
  }
}

虽然index.html位于html/文件夹中,但文件查找将从app/而不是html/

中进行,我当时正在构建自己的Grunt脚手架,对此问题感到沮丧。我设法创造了一个工作环境,我想与大家分享

我想用我自己的一个例子来说明他的问题背后的原因,以及我是如何设法解决的。假设我的目录结构如下所示:

| in/
+---- pages/
|    +---- login.html
+---- js/
|    +---- s1.js
|    +---- s2.js
+---- index.html
| out/
| Gruntfile.js
其中
in/
是我的所有源文件所在的目录,
out/
dest
目录,所有输出文件都将存储在这里。假设我想将
s1.js
导入
login.html
,我会这样写:

<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->
"useminPrepare": {
    t1: {
        dest: "out",
        files: [{src: ["in/*.html"]}],
        ...
    },
    t2: {
        dest: "out/pages",
        files: [{src: ["in/pages/*.html"]],
        ....
    }
}
"useminPreparePrepare": {
    html: "in/**/*.html",   // All HTML files under in/ and its subdirectories.
    options: {
        src: "in",
        dest: "out",
        ....
    }
},
"copy": {
    html: { // Copies all HTML files from in/ to out/ preserving their relative paths.
        files: [{
                expand: true,
                cwd: "in",
                src: ["**/*.html"],
                dest: "out"
            }
        ]
    }
},
"usemin": {
    html: "out/**/*.html",  // Process all HTML files under out/ and its subdirectories.
    ...
}
app/ - webroot source (devmode)
app/views/layouts - layouts for server-generated pages (also has usermin tags init)
app/js - source javascript

dist/ - production build dir
所有目标都必须运行。现在你可能会说;如果我在其他子目录下有更多的HTML文件呢?这是否意味着我必须为找到HTML文件的每个目录创建一个目标?这是一种痛苦和愚蠢。它是!我同意。所以我写了一个非常特别的咕噜任务来帮忙。我称之为我故意称之为愚蠢,因为它是愚蠢的。我真的希望有一天usemin people解决这个问题的时候,能摆脱这项工作。顾名思义,useminPrepare为useminPrepare准备配置。它自己的配置镜像useminPrepare(事实上,大多数配置都是简单复制的),只有一个例外;您必须添加一个
src
属性,该属性指向所有源文件所在的源根目录,以便它能够找出源根目录和HTML文件之间的相对路径。它将基本上实现我上面提到的功能。另外,它对暂存目录也有同样的作用,因此暂存文件不会“脱离暂存目录”。您甚至可以使用多个目标MinPrepare,它将复制您运行的目标的选项

为了使用此变通方法,首先必须导入UseMinPrepare。我没有把它放在npm上,所以你只能复制并粘贴它。我不介意。然后简单地将useminPrepare配置重命名为useminPrepare,并添加
src
属性。对于上面的示例,
src:“in”
。然后,您需要使用您通常喜欢的任何目标运行useminPrepare,然后立即运行useminPrepare而不指定目标,这样所有目标都将运行。鉴于上述示例,Grunt配置可能如下所示:

<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->
"useminPrepare": {
    t1: {
        dest: "out",
        files: [{src: ["in/*.html"]}],
        ...
    },
    t2: {
        dest: "out/pages",
        files: [{src: ["in/pages/*.html"]],
        ....
    }
}
"useminPreparePrepare": {
    html: "in/**/*.html",   // All HTML files under in/ and its subdirectories.
    options: {
        src: "in",
        dest: "out",
        ....
    }
},
"copy": {
    html: { // Copies all HTML files from in/ to out/ preserving their relative paths.
        files: [{
                expand: true,
                cwd: "in",
                src: ["**/*.html"],
                dest: "out"
            }
        ]
    }
},
"usemin": {
    html: "out/**/*.html",  // Process all HTML files under out/ and its subdirectories.
    ...
}
app/ - webroot source (devmode)
app/views/layouts - layouts for server-generated pages (also has usermin tags init)
app/js - source javascript

dist/ - production build dir
您可以看到,上面的配置非常简单,可以在源目录下递归地包含所有HTML文件。useminPrepare在看起来像useminPrepare的同时,会处理所有愚蠢的工作


我希望这有帮助

我使usemin块相对于模板

我有一个这样的结构:

<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->
"useminPrepare": {
    t1: {
        dest: "out",
        files: [{src: ["in/*.html"]}],
        ...
    },
    t2: {
        dest: "out/pages",
        files: [{src: ["in/pages/*.html"]],
        ....
    }
}
"useminPreparePrepare": {
    html: "in/**/*.html",   // All HTML files under in/ and its subdirectories.
    options: {
        src: "in",
        dest: "out",
        ....
    }
},
"copy": {
    html: { // Copies all HTML files from in/ to out/ preserving their relative paths.
        files: [{
                expand: true,
                cwd: "in",
                src: ["**/*.html"],
                dest: "out"
            }
        ]
    }
},
"usemin": {
    html: "out/**/*.html",  // Process all HTML files under out/ and its subdirectories.
    ...
}
app/ - webroot source (devmode)
app/views/layouts - layouts for server-generated pages (also has usermin tags init)
app/js - source javascript

dist/ - production build dir
我在app/layouts/main.html中使我的html看起来像这样:

    <!-- build:js js/static.min.js -->
      <script src="../../js/controllers/StaticCtrl.js"></script>
      <script src="../../js/directives/backImg.js"></script>
      <script src="../../js/smooth-scroll.js"></script>
    <!-- endbuild -->


在dev上(没有用,只是提供文件)“../../”巧妙地解析为“/”,所以它仍然有效。这样,在开发过程中(使用监视任务或其他任何任务),您不需要进行预处理。

我的解决方案是手动修改grunt usemin插件

在您喜爱的文本编辑器中打开
node\u modules/grunt usemin/fileprocessor.js
。在第152行附近的某个地方可以找到:

if (assetSearchPath && assetSearchPath.length !== 0) {
  this.file.searchPath = assetSearchPath;
}
并将其替换为:

if (assetSearchPath && assetSearchPath.length !== 0) {
  this.file.searchPath.splice(0, 0, assetSearchPath);
}

默认情况下,
this.file.searchPath
是一个数组,包含当前文件的绝对路径。用
['dist']
覆盖它没有意义,最好在数组前面加上'dist'。这样,如果在“dist”目录中找不到某个项,则可能会断定该路径是相对的或是错误的。因此,我们使用
searchPath
数组中的第二个值来查找文件,如果它是一个相对路径,我们就会得到我们想要的。我使用了多个目标,如下所示: