我如何让 Grunt 重新编译相关的 SASS 文件?

How do I get Grunt to recompile dependent SASS files?

我正在努力完成 Visual Studio 2015 年的更新,包括使用 Grunt 等。

我可以让 Grunt 重新编译 .scss 文件,但我遇到了问题。我使用 SASS 作为主题,我的很多 CSS 都在中央 _main.scss。我想要的是当我编辑该文件时,它应该重新编译所有包含 _main.scss.

theme-*.scss 文件

有什么方法可以告诉 watch 或类似的东西在依赖项发生变化时重新编译东西吗?即使我必须手动指定依赖项?

我不知道是否有一种方法可以跟踪从一个文件到另一个文件的依赖关系,但您可以观察 .scss 文件中的更改,然后 运行 一个 sass 任务更新您的主题文件。

所以你的 sass 任务是这样的:

    sass : {
        build: {
            files : {
                'path/to/compiled-foo.css': 'path/to/theme-foo.scss',
                'path/to/compiled-bar.css': 'path/to/theme-bar.scss',
                // Or more generally
                'path/to': 'path/to/theme-*.scss',
            }
        }
    },

然后你的手表任务是这样的:

    watch : {
        themes: {
            files : [ 'path/to/_main.scss' ],
            tasks : [ 'sass' ],
            options : {
                // You may change these to better suit your needs
                spawn : false,
                interrupt: true,
                livereload: true
            },
        },
    },

这样做的缺点是每次更改 _main.scss 时都会编译所有主题。如果你有不同的文件来观察不同的主题,那么你可以在 watch 中有更多的任务(而不是 themes 你可以让 theme_footheme_bar 调用不同的任务(例如: sass:theme_foosass:theme_bar) 然后只重新编译那个主题。

您还可以 运行 grunt watch 执行特定任务:grunt watch theme_foo,不会更新 theme_bar,只会更新 theme_foo.


编辑:您可以将您的_main.scss模块化,使其变为_foo.scss_bar.scss_common.scss,然后更改_common.scss 当它影响所有主题时,_foo.scss 当它只影响 theme_foo 时。这样你就可以监控 _foo.scss 并在它发生变化时只更新 theme_foo ;或在 _common.scss 更改时更新所有主题。


编辑 2(基于评论):
假设我们有两个主题,bluered。我们将有两个 sass 任务(每个主题一个):

    sass : {
        red: {
            files : {
                'path/to/compiled-red.css': 'path/to/theme-red.scss',
            }
        },
        blue: {
            files : {
                'path/to/compiled-blue.css': 'path/to/theme-blue.scss',
            }
        },
    },

现在,如果您 运行 grunt sass 它将更新两个主题。但是如果你 运行 grunt sass red 它只会更新红色主题。

要使您的 watch 仅更新所需的主题,您将有两个任务:

    watch : {
        red: {
            files : [ 'path/to/theme-red.scss' ],
            tasks : [ 'sass:red' ],
            options : { /* ... */ },
        },

        blue: {
            files : [ 'path/to/theme-blue.scss' ],
            tasks : [ 'sass:blue' ],
            options : { /* ... */ },
        },
    },

注意 red 调用 sass:red(该主题的任务且仅该主题)。 blue 调用 sass:blue.

时也会发生同样的情况

要使其在 _main.scss 更改时更新每个主题,请在 watch 中再添加一项任务:

    watch : {
        red: {
            files : [ 'path/to/theme-red.scss' ],
            tasks : [ 'sass:red' ],
            options : { /* ... */ },
        },

        blue: {
            files : [ 'path/to/theme-blue.scss' ],
            tasks : [ 'sass:blue' ],
            options : { /* ... */ },
        },

        all: {
            files : [ 'path/to/_main.scss' ],
            tasks : [ 'sass' ],
            options : { /* ... */ },
        },
    },

现在 all 正在监视您的 _main.scss,当它更改时 sass 中的每个任务都将是 运行(即 sass:redsass:blue).