【问题标题】:How to rewrite urls of images in vendor CSS files using Grunt如何使用 Grunt 重写供应商 CSS 文件中的图像 url
【发布时间】:2013-08-17 17:22:35
【问题描述】:

我正在尝试将前端依赖项移出版本控制系统。 Bower.io 和 Grunt 的组合应该能够做到这一点。

然而,我还无法通过捆绑多个供应商库来解决一个问题。例如,假设我有以下目录结构,其中 components 目录是 Bower.io 保存依赖项的目录:

├── assets
└── components
    ├── bootstrap
    │   ├── img
    │   │   └── glyhs.gif
    │   └── less
    │       └── bootstrap.css
    └── jquery-ui
        ├── css
        │   └── style.css
        └── images
            ├── next.gif
            └── prev.gif

现在假设我想捆绑 jQuery 的 style.css 和 Bootstrap 的 bootstrap.css。我会将这个捆绑的文件保存在 assets/bundled.css 中。

但是,在此文件中,对原始图像(../images/next.gif 和 ../img/glyhs.gif)的引用不正确。它们必须被重写才能工作(所以../images/next.gif => ../components/jquery-ui/images/next.gif)。我相信(d)这种对 URL 的重写是 Grunt 应该能够做到的。 但我似乎无法使用 cssmin/less/copy 任务来实现这一点。例如,以下 Grunt 设置(仅移动 1 个文件)无法正常工作:

module.exports = function (grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            options: {
                compile: false,
                relativeUrls: true
            },
            bootstrap: {
                src: 'components/bootstrap/less/bootstrap.less',
                dest: 'assets/bootstrap.css'
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.registerTask('dist-css', ['less']);
};

要么:

  • 我是否错误地配置了 Grunt 或做错了什么?

  • 或者我所描述的工作流程根本不是正确的,我应该改用另一个工作流程。

谢谢!

【问题讨论】:

标签: relative-path gruntjs bower


【解决方案1】:

您需要对 dist css 文件进行一些搜索/替换,以生成正确的相对路径。有许多 grunt 插件可以为你做到这一点,我个人更喜欢grunt-replace。使用变量设置非压缩资产,然后使用动态生成的 URL 生成 dist css。所以:

body {
    background:url(@@IMG_PATH/background.jpg);
}

在 dist 中变成这个:

body {
    background:url(path/to/background.jpg);
}

希望这会有所帮助。

【讨论】:

  • 对于我们自己构建的样式表,这确实是一个解决方案。但是,对于供应商库(例如示例中提到的 Bootstrap 和 jQuery UI),如果不更改这些文件的内容,就无法做到这一点。
  • 我认为修改 Bootstrap 的副本没有任何问题(动态地作为 dist 文件夹中的副本,或者只是继续在原始文件中进行搜索和替换),之后这只是帮助您建立网站的工具。替代方法可能只是复制原始目录结构以保留图像但保留未压缩版本,或者在您将组件目录上传到生产站点时对其进行符号链接。
  • 我认为手动更新供应商库不是一个好习惯。除其他外,这使得更新变得更加困难。 Offcourse 如果操作以系统的方式自动完成,那很好。除了相对路径之外,一种选择是自动将所有图像路径重写为绝对路径。也许这可以通过 Grunt 完成?
  • 但是您只能在应用处于生产模式时对其进行测试,对吧?没有可以测试的开发者模式
【解决方案2】:

你可能想看看这个 grunt 包https://github.com/Ideame/grunt-css-urls。 该软件包似乎旨在解决您的问题。

编辑:看了这个插件后,我不喜欢重写我的标记以使我的构建过程更顺畅的想法。所以我最终编写了自己的小函数来为我重写。

我使用 grunt 的 concat 插件来捆绑我的 css 文件。这个插件的好处是它支持连接前的文件处理功能。现在我的 gruntfile 看起来像这样:

grunt.initConfig({
concat: {
    options: {
    separator: '\n',
    process: function (src, filepath) {
        var cssPatt = new RegExp('app(\/.*\/).*\.css$');

        //filter out everithing except css files
        var file = cssPatt.exec(filepath);

        if (file) {
            var urlPatt = /url\(\'(.*)\'\)/g;

        console.log('In file: ' + filepath);

        //replace every url(...) with its absolute path
        return src.replace(urlPatt, function (match, p1) {
            console.log(' * ' + match + ' -> ' + 'url(\'' + file[1] + p1 + '\')');
            return 'url(\'' + file[1] + p1 + '\')';
        });
        }

        return src;
    }
    },
}

【讨论】:

  • 感谢您的评论。但是:我的问题现在以更优雅的方式解决了。我应该更新我的问题:对不起!
  • 我更新了我的答案。我希望你同意这种方法更干净。再次感谢!
  • 感谢您的回答!帮助我自己找出解决方案。但是,您的答案不会在一行中检查多个 url() 定义,就像 Bootstrap 3 对其字体定义所做的那样:src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
【解决方案3】:

仅供参考:现在有现成的解决方案。我将同样的问题发布到 CleanCss grunt 插件,他们已经接受并在新的 1.1 版本中发布了此行为。

您可以在 GitHub 跟踪器上找到问题:https://github.com/GoalSmashers/clean-css/issues/129

这个库可以使用绝对重写(从根目录)或根据新的输出目录更改相对图像路径。查找 --root--ouput 指令。

感谢大家的提示和解答!

【讨论】:

  • 是否可以共享您的配置文件?我几乎处于相同的情况,但无法使用 cssmin 配置 usemin。
  • 请提供一个 Grunt 配置,显示您所做的一切,我们无法通过查看您提供的链接来弄清楚。
猜你喜欢
  • 1970-01-01
  • 2013-04-28
  • 2015-06-26
  • 1970-01-01
  • 2012-01-03
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
相关资源
最近更新 更多