21

我有一个基于 yeoman-generator 支持的 grunt 项目generator-webapp,如果它有任何帮助,你可以在GitHub 上找到它

grunt 项目使我们完成了grunt-usemin任务。

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

| project/
|--dist/
|----en/
|------index.html
|------404.html
|------...
|----fr/
|------index.html
|------404.html
|------...

这些文件由车把模板制作并使用assemble. 在布局中,我有构建块,usemin例如

<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->

在一个完美的世界中,这将转化为

<link rel="stylesheet" href="../styles/main.css">
<script src="../scripts/vendor/modernizr.js"></script>

而是显示

<link rel="stylesheet" href="styles/main.css">
<script src="scripts/vendor/modernizr.js"></script>

在我的情况下,这不太理想。的相关部分Gruntfile.js看起来像这样

    useminPrepare: {
        options: {
            dest: '<%= yeoman.dist %>'
        },
        html: [
            '<%= yeoman.app %>/fr/{,*/}*.html',
            '<%= yeoman.app %>/en/{,*/}*.html'
        ]
    },
    usemin: {
        options: {
            dirs: ['<%= yeoman.dist %>']
        },
        html: [
            '<%= yeoman.dist %>/fr/{,*/}*.html',
            '<%= yeoman.dist %>/en/{,*/}*.html'
        ],
        css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
    }

我试图通过将其设置为以及将构建块更改为来使用该basedir选项<%= yeoman.dist %>

<!-- build:css(.tmp) ../styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js ../scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->

但不幸的是无法获得正确的输出。

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

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

代替

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

有人会碰巧知道该怎么做吗?这似乎是一个相当简单的用例,但我无法通过 Google、GitHub 或 SO 找到我需要的帮助......

4

9 回答 9

4

我相信你可以通过这种方式实现你所需要的:

html文件:

    <!-- build:css styles/main.css -->
    <link href='../styles/css/style.css' rel='stylesheet' type='text/css'>
    <link href='../styles/css/responsive.css' rel='stylesheet' type='text/css'>

    <link href="../styles/css/skins/welld.css" rel='stylesheet' type='text/css' id="skin-file">
    <!-- endbuild -->

Gruntfile.js

        useminPrepare: {
            options: {
                dest: '<%= yeoman.dist %>/'
            },
            html: ['<%= yeoman.app %>/snippets/head.html','<%= yeoman.app %>/snippets/tail.html']
        },
        usemin: {
            options: {
                dirs: ['<%= yeoman.dist %>/'],
                blockReplacements: {
                    css: function (block) {
                        return '<link rel="stylesheet" href="../' + block.dest + '"/>';
                    },
                    js: function (block) {
                        return '<script src="../' + block.dest + '"></script>';
                    }
                }
            },
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
        }

关键解决方案在于blockReplacementsusemin 任务的选项。基本上,该任务会将您的文件放在 <%= yeoman.dist %>/styles/main.css 下,而您的 html 将位于 <%= yeoman.dist %>/en/somefileinEnglish.html 和 'styles 的每个实例此文件中的 /main.css' 将替换为 '../styles/main.css',添加正确的相对路径。

作为一个额外的提示,如果您正在构建一个多语言网站,您可能需要考虑grunt-i18n在构建时翻译您的文件,因此您不需要为每种语言维护不同的 html 文件。

于 2014-11-25T12:24:05.680 回答
3

我正在构建自己的 Grunt 脚手架,我对这个问题感到沮丧。我设法创建了一个我想与你分享的工作。

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

| in/
+---- pages/
|    +---- login.html
+---- js/
|    +---- s1.js
|    +---- s2.js
+---- index.html
| out/
| Gruntfile.js

in/我的所有源文件都驻留在哪里,并且out/dest目录,所有输出文件都将存储在哪里。假设我想导入s1.jslogin.html我会写这样的东西:

<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->

在这里, usemin 块执行简单的字符串替换,因此输出路径应该正是我想要链接输出文件的位置。当useminPrepare 最终登陆而不是login.js登陆时,就会出现问题。这背后的原因是 useminPrepare 只是在(which is ) 和输出路径 (which is ) 之间执行路径连接,而它应该针对找到 HTML 文件的位置执行路径连接。out/js/login.jsjs/login.jsdestout../js/login.js

为了解决这个问题,请注意,如果我设置destout/pages哪些方面在哪里login.html找到,它会正常工作。但是请注意,如果以类似的方式index.html导入js/s2.js,那将会搞砸。因此,为了解决这个问题,我们需要为with创建一个 useminPrepare 目标,为index.htmlwith创建dest: "out"另一个目标。因此我的 useminPrepare 配置现在看起来像这样:login.htmldest: "out/pages"

"useminPrepare": {
    t1: {
        dest: "out",
        files: [{src: ["in/*.html"]}],
        ...
    },
    t2: {
        dest: "out/pages",
        files: [{src: ["in/pages/*.html"]],
        ....
    }
}

所有目标都必须运行。现在你可能会说;如果我在其他子目录下还有更多 HTML 文件怎么办?这是否意味着我必须为找到 HTML 文件的每个目录创建一个目标?这是痛苦和愚蠢的。这是!我同意。所以我写了一个很特别的 grunt 任务来帮忙。我把它叫做 useminPreparePrepare我故意把它命名为愚蠢的,因为它是愚蠢的。我真的希望有一天当 usemin 人解决此问题时,可以摆脱这项工作。顾名思义,useminPreparePrepare 为 useminPrepare 准备配置。它自己的配置镜像 useminPrepare (事实上,大多数配置只是简单地复制过来),但有一个例外;你必须添加一个src指向所有源文件所在的源根目录的属性,以便它可以找出源根和 HTML 文件之间的相对路径。它将基本上执行我上面提到的内容。另外,它对暂存目录也有同样的作用,所以暂存文件不会脱离暂存目录。你甚至可以在 useminPreparePrepare 中有多个目标,它会复制你运行的目标的选项。

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

"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.
    ...
}

可以看到,上面的配置非常简单,可以递归地包含源目录下的所有 HTML 文件。useminPreparePrepare 处理所有愚蠢的工作,同时看起来就像 useminPrepare。

我希望这有帮助!

于 2014-02-09T05:17:09.917 回答
1

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

node_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数组中的第二个值来查找文件,如果它是相对路径 - 我们得到我们想要的。

于 2014-04-21T20:29:01.727 回答
1

我使用了多个目标,如下所示:

 useminPrepare: {
        target1 : {
                src : ['target1/*.html'],
                options : {
                    dest: 'out'
                }
            },

            target2 : {
                src : ['target2/folder/*.html'],
                options : {
                    dest: 'out/subfolder'
                }
            }
    },

然后在 HTML 块中你可以这样:

<!-- build:js ../subfolder/script.js -->
<script src="../subfolder/scripts/main.js></script>
<!-- endbuild -->
于 2014-06-04T11:02:36.517 回答
0
useminPrepare: {
        loyalty: {
            src: '<%= loyalty.app %>/Views/index.tpl',
            options: {
                dest: '.',
                flow: {
                    html: {
                        steps: {
                            js: ['concat', 'uglifyjs'],
                            css: ['cssmin']
                        },
                        post: {}
                    }
                }
            }
        }
    },
<!-- build:css /resources/v4/css/loyalty/index.css -->
<link rel="stylesheet" href="../Resources/css/main.css">
<link rel="stylesheet" href="../Resources/css/product.css">
<link rel="stylesheet" href="../Resources/css/use_code.css">
<!-- endbuild -->

利用 '。' 作为 gruntfile 中的目标。

于 2014-09-16T10:46:01.047 回答
0

我对相对路径进行了错误修复。 https://www.npmjs.com/package/grunt-usemin-fix

您可以将更改复制并粘贴到 use-min 的源以使用相对路径

于 2015-01-10T20:08:51.657 回答
0

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

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

尽管 index.html 位于 html/ 文件夹中,但文件查找将来自 app/ 而不是 html/

于 2013-12-01T14:41:13.447 回答
0

我制作了相对于模板的 usemin 块。

我有这样的结构:

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 上(没有 usemin,只是提供文件)“../../”巧妙地解析为“/”,所以它仍然有效。这样您就不需要在开发时进行预处理(使用监视任务或其他方式。)

于 2014-03-11T09:01:36.557 回答
0

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

但是,问题仍然存在于 usemin

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

usemin 文件将被写入dist/static/css/main.css

并且 HTML 将显示错误的(但预期的)路径

<link rel="stylesheet" href="static/css/main.css">

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

于 2013-09-24T14:27:53.820 回答