Объединить файлы S CSS на основе индексного файла и просмотреть все @imports, не переносить с помощью sass - PullRequest
0 голосов
/ 12 июля 2020

Я хочу сгенерировать один файл S CSS на основе дерева небольших модульных файлов S CSS, которые импортируются через центральный индексный файл. Каждый из этих модульных / частичных файлов также может иметь свой собственный импорт. По сути, это стандартная компиляция S CSS, за исключением того, что я не хочу, чтобы она компилировалась в CSS; Вместо этого я просто хочу, чтобы все S CSS были сгруппированы в один файл, который можно импортировать в другие проекты, которые также содержат файлы S CSS, а затем этот файл был передан вместе с остальными.

Рассмотрели использование concat() с Gulp, но он не знает, что делать с импортом, и вместо этого просто добавляет все содержимое каждого файла в один.

Пример:

// _colors.scss
$primary: red;

// _buttons.scss
$buttonBg: $primary;

// _extras.scss
.foo {
    color: $primary;
}

// index.scss
@import "colors";
@import "buttons";
@import "extras";

// OUTPUT FILE
// dist.scss
$primary: red;
$buttonBg: $primary;

.foo {
    color: $primary;
}

1 Ответ

0 голосов
/ 13 июля 2020

Взгляните на это:

const gulp = require("gulp");
const concat = require("gulp-concat");
const fs = require("fs");
// const path = require("path");           // not used (yet)
const replace = require("gulp-replace");


let arrayOfImports = [];

function getArrayOfImports(master) {

    // how to handle no such file?  what does sass do?
  let fileContents = fs.readFileSync(master, 'utf8');

  let regexp = /^\s*@use ['"](.*?)['"];/gm;     // @use "colors";
  let useArray = fileContents.matchAll(regexp);  // get all @use... matches in the file

  for (let use of useArray) {
    let usePath = `_${ use[1] }.scss`;  // use[1] = colors, change to _colors.scss
    getArrayOfImports(usePath);         // recursive
    arrayOfImports.push(usePath);       // after recursive call so deeper levels are pushed first
  };
};

function concatSources(cb) {

  getArrayOfImports("index.scss");
  arrayOfImports.push("index.scss");

  console.log(arrayOfImports);
  
  return (
    gulp
      .src(arrayOfImports)
      .pipe(concat('dist.scss'))
      .pipe(replace(/^\s*@use (.*?);\s*\n?/gm, ""))     // strip out @use lines
      .pipe(gulp.dest('./css'))
  );
  cb();
}


exports.default = gulp.series(concatSources);

Я использовал @use вместо @import, поскольку теперь использование @import не рекомендуется, см. https://sass-lang.com/documentation/at-rules/import

И если вы переключаетесь, используйте gulp-dart-sass. Но вы можете легко изменить приведенный выше код, чтобы использовать @imports.

Он обрабатывает рекурсивные @use в правильном порядке и удаляет их из окончательного dist.scss.

Теперь он может искать только @use ....; в ваших файлах - если вы поместите что-то, что соответствует ^\s*@use ['"](.*?)['"]; где-нибудь в файле, где его не должно быть - оно все равно будет захвачено, но я полагаю, что это будет ваша вина.

TODO: я еще не исследовал такие вызовы, как @use 'folder/subFolder/colors4', но они все равно должны работать (возможно добавление ./ в начало функции).

...