编译不同 SCSS 文件的 Gulp 组合任务

Posted

技术标签:

【中文标题】编译不同 SCSS 文件的 Gulp 组合任务【英文标题】:Gulp combined task which compiles different SCSS files 【发布时间】:2019-10-27 16:25:32 【问题描述】:

我正在研究一个类似于https://nystudio107.com/blog/a-better-package-json-for-the-frontend 中描述的过程,但希望对其进行修改,以便能够将不同的SCSS 文件编译为同名的 CSS 文件,例如fileA.scss 编译为 fileA.css

如果我只使用一个SCSS 文件master.scss 编译为site.combined.min.css,我目前所拥有的工作正常。

来自package.json

"paths": 
    "src": 
        "base": "./src/",
        "css": "",
        "img": "./src/img/",
        "js": "./src/js/",
        "scss": "./src/scss/"
    ,
    "dist": 
        "base": "./public/",
        "css": "./public/assets/css/",
        "js": "./public/assets/js/",
        "fonts": "./public/assets/fonts/",
        "img": "./public/assets/img/"
    ,
    "build": 
        "base": "./build/",
        "css": "./build/css/",
        "js": "./build/js/",
        "html": "./build/html/",
        "img": "./build/img/"
    ,
    "tailwindcss": 
        "src": "./build/css/master.css",
        "conf": "./tailwind.config.js"
    ,
    "scss": [
        
            "src": "./src/scss/master.scss"
        
    ],
    "templates": "./public/site/templates/"
,
"vars": 
    "siteCssName": "site.combined.min.css",
    "scssName": "master.scss",
    "cssName": "master.css"
,
"globs": 
    "distCss": [
        "./node_modules/normalize.css/normalize.css",
        "./build/css/*.css"
    ],
    "purgecss": [
        "./html/index.html",
        "./html/site/templates/**/*.twig",
        "./src/js/site.js",
        "./html/assets/js/*.js"
    ],
    "purgecssWhitelist": []
,

还有 Gulp 任务

gulp.task("scss", () => 
    $.fancyLog("-> Compiling scss");
    // return gulp.src(pkg.paths.src.scss + pkg.vars.scssName)
    return gulp.src(pkg.paths.src.scss + '*.scss')
        .pipe($.plumber(errorHandler: onError))
        .pipe($.sourcemaps.init(loadMaps: true))
        .pipe($.sass(
                includePaths: pkg.paths.scss
            )
            .on("error", $.sass.logError))
        .pipe($.cached("sass_compile"))
        .pipe($.autoprefixer())
        .pipe($.sourcemaps.write("./"))
        .pipe($.size(gzip: true, showFiles: true))
        .pipe(gulp.dest(pkg.paths.build.css));
);

gulp.task("tailwind", () => 
    $.fancyLog("-> Compiling tailwind css");
    return gulp.src(pkg.paths.tailwindcss.src)
        .pipe($.postcss([
            $.tailwindcss(pkg.paths.tailwindcss.conf),
            require("autoprefixer"),
        ]))
        .pipe($.if(process.env.NODE_ENV === "production",
            $.purgecss(
                extractors: [
                    extractor: TailwindExtractor,
                    extensions: ["twig", "scss", "css", "js"]
                ],
                whitelist: pkg.globs.purgecssWhitelist,
                content: pkg.globs.purgecss
            )
        ))
        .pipe(gulp.dest(pkg.paths.build.css));
);

class TailwindExtractor 
    static extract(content) 
        return content.match(/[A-z0-9-:\/]+/g);
    


gulp.task("css", ["tailwind", "scss"], () => 
    $.fancyLog("-> Building css");
    return gulp.src(pkg.globs.distCss)
        .pipe($.plumber(errorHandler: onError))
        .pipe($.newer(dest: pkg.paths.dist.css + pkg.vars.siteCssName))
        .pipe($.print())
        .pipe($.sourcemaps.init(loadMaps: true))
        .pipe($.concat(pkg.vars.siteCssName))
        .pipe($.if(process.env.NODE_ENV === "production",
            $.cssnano(
                discardComments: 
                    removeAll: true
                ,
                discardDuplicates: true,
                discardEmpty: true,
                minifyFontValues: true,
                minifySelectors: true
            )
        ))
        .pipe($.header(banner, pkg: pkg))
        .pipe($.sourcemaps.write("./"))
        .pipe($.size(gzip: true, showFiles: true))
        .pipe(gulp.dest(pkg.paths.dist.css))
        .pipe($.filter("**/*.css"))
        .pipe($.livereload());
);

您可以看到我已经替换了 scss 任务的第 3 行,以便它可以处理多个源并将多个文件输出到 build 文件夹。

但我遇到的问题是tailwind 任务如何知道使用与scss 任务中使用的名称相同的文件以及当它到达css 任务时,如何它知道不使用 build 文件夹中的所有 CSS 文件,而只使用之前任务中使用的那个?

有没有办法将要使用的文件名从一个任务传递到下一个任务?还是应该换一种方式?

【问题讨论】:

【参考方案1】:

除了将编译后的 scss 输出到 pkg.paths.build.css 之外,您还可以将其输出到不同的文件夹(即 ./build/scss/),并将该文件夹设置为您的 pkg.paths.tailwind.src

或者,您可以尝试将pkg.paths.tailwind.src 设置为命名文件数组,例如

"tailwindcss": 
  "src":[pkg.paths.build.css + "fileA.css", pkg.paths.build.css + "fileB.css"],
  "conf": "./tailwind.config.js"
,

无论哪种方式,这将取决于tailwind 任务的 PostCSS 部分如何处理传递的多个文件..

【讨论】:

执行第二个建议已将正确编译的 CSS 文件保存到 build 文件夹,但是当它执行 CSS 任务时,它会获取在 build 文件夹中找到的所有 CSS 文件(其中还包括normalise.css,它是从 node_modules 文件夹中提取的)并将它们组合成一个由dest: pkg.paths.dist.css + pkg.vars.siteCssName 指定的文件。所以它现在会尝试将主 CSS 文件与 CKEditor 的主文件合并。【参考方案2】:

事实证明我比我想象的更接近。我需要做的唯一更改是在 css 任务中。

return gulp.src(pkg.globs.distCss) 变成了return gulp.src(pkg.paths.build.css + '**/*.css')

.pipe($.newer(dest: pkg.paths.dist.css + pkg.vars.siteCssName)) 变成了.pipe($.newer(dest: pkg.paths.dist.css))

我删除了.pipe($.concat(pkg.vars.siteCssName)),因为我不再合并多个 CSS 文件了。

这会将 CSS 文件保存到 build 文件夹中,文件名与原始 SCSS 文件相同,然后将其编译并保存到 dist 文件夹中,再次使用相同的文件名。

【讨论】:

以上是关于编译不同 SCSS 文件的 Gulp 组合任务的主要内容,如果未能解决你的问题,请参考以下文章

Gulp-sass 无法编译 scss 文件

通过@import或通过构建工具concat scss文件

scss 使用Autoprefixer在SASS中编译Shopify Liquid标签的Gulp任务

是否可以将标志传递给 Gulp 以使其以不同的方式运行任务?

Gulp 3 到 Gulp 4:如何观看 scss 并将其缩小/编译成 css?

Gulp SASS - 使用 @import 而不编译 scss -> css