有没有办法在同一个项目中建立多个语义-ui 主题?

Is there a way to build multiple semantic-ui themes in the same project?

我目前正在尝试创建一个原型并运行固定在墙上。

我正在开展一个项目,我们希望拥有一个所有最终用户都使用的代码库,并且用户所属的组织将确定皮肤(css 文件)被应用到网站。 Semantic-UI 似乎非常适合这个,因为它具有主题的概念和围绕它的 build 过程。我想利用这个 build 过程的力量,而不必完全重写它。

有没有办法 运行 语义 ui build 任务并让它生成多个 css 文件?

这是我到目前为止尝试过的方法:

尝试 1 在 运行ning npm install --save-dev semantic-ui 并选择所有安装的默认选项后,我将 semantic/tasks/build.js 文件更新为以下内容:

/*******************************
          Build Task
*******************************/

var
  // dependencies
  gulp         = require('gulp-help')(require('gulp')),
  runSequence  = require('run-sequence'),
  print        = require('gulp-print'),
  // config
  config       = require('./config/user'),
  install      = require('./config/project/install'),

  // task sequence
  tasks        = []
;


// sub-tasks
if(config.rtl) {
  require('./collections/rtl')(gulp);
}
require('./collections/build')(gulp);

const orgs = require('../../organizations.json').orgs;
module.exports = function(callback) {
    tasks.push('build-javascript');
    tasks.push('build-assets');
    var lastTaskName = '';
  for(var i = 0; i < orgs.length; i ++) {
    console.info('Building Semantic');
    const org = orgs[i];

    gulp.task(`copy semantic ${org}`, function() {
      console.info(`copy semantic ${org}`);
      return gulp.src(`./orgs/${org}/semantic.json`)
                 .pipe(print())
                 .pipe(gulp.dest('../'));
    });

    gulp.task(`copy theme ${org}`, function() {
      console.info(`copy theme ${org}`);
      return gulp.src(`./orgs/${org}/theme.config`)
                 .pipe(print())
                 .pipe(gulp.dest('./src/'));
    });

    gulp.task(`build css ${org}`, [`build-css`]);

    if( !install.isSetup() ) {
      console.error('Cannot find semantic.json. Run "gulp install" to set-up Semantic');
      return 1;
    }
    tasks.push(`copy semantic ${org}`);
    tasks.push(`copy theme ${org}`);
    tasks.push(`build css ${org}`);
  };

  runSequence(...tasks, callback);
};

这背后的想法是,每个组织都有自己的 semantic.jsontheme.config 文件。这些将覆盖默认文件(分别为 /semantic.json/semantic/src/theme.config),然后为每个文件创建一个新的 build-css 任务。

这种方法的问题是 build 进程似乎只使用在 b 之前存在的原始 semantic.json 文件uild 已启动,即使已成功覆盖。 例如,在原始 semantic.json 文件中,output.packaged 的值是 'dist/'.在 build-css 任务执行之前,semantic.json 被成功覆盖并且 output.packaged 值为 dist/org1,但所有输出文件仍以 'dist/' 结束。


尝试 2 在 运行ning npm install --save-dev semantic-ui 并选择所有安装的默认选项后,我将 semantic/tasks/build/css.js 文件更新为以下内容:

const console = require('better-console');
const extend = require('extend');
const fs = require('fs');
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const chmod = require('gulp-chmod');
const minifyCSS = require('gulp-clean-css');
const clone = require('gulp-clone');
const concat = require('gulp-concat');
const concatCSS = require('gulp-concat-css');
const dedupe = require('gulp-dedupe');
const flatten = require('gulp-flatten');
const header = require('gulp-header');
const gulpif = require('gulp-if');
const less = require('gulp-less');
const plumber = require('gulp-plumber');
const print = require('gulp-print');
const rename = require('gulp-rename');
const replace = require('gulp-replace');
const uglify = require('gulp-uglify');
const requireDotFile = require('require-dot-file');
const runSequence = require('run-sequence');

const config = require('../config/project/config');
const defaults = require('../config/defaults');
const install = require('../config/project/install');
const tasks = require('../config/tasks');
const banner = tasks.banner;
const comments = tasks.regExp.comments;
const log = tasks.log;
const settings = tasks.settings;
const filenames = tasks.filenames;

const orgs = requireDotFile(`organizations.json`, __dirname).orgs;

module.exports = function(callback) {
    orgs.forEach(org => {
        const userConfig = requireDotFile(`semantic.${org}.json`, __dirname);
        const gulpConfig = (!userConfig) ? extend(true, {}, defaults) : extend(false, {}, defaults, userConfig);
        const compiledConfig = config.addDerivedValues(gulpConfig);
        const globs = compiledConfig.globs;
        const assets = compiledConfig.paths.assets;
        const output = compiledConfig.paths.output;
        const source = compiledConfig.paths.source;

        const cssExt = { extname: `.${org}.css` };
        const minCssExt = { extname: `.${org}.min.css` };

        let tasksCompleted = 0;
        let maybeCallback  = function() {
            tasksCompleted++;
            if(tasksCompleted === 2 * orgs.length) {
                callback();
            }
        };
        let stream;
        let compressedStream;
        let uncompressedStream;

        console.info('Building CSS');

        if( !install.isSetup() ) {
            console.error('Cannot build files. Run "gulp install" to set-up Semantic');
            return;
        }

        // unified css stream
        stream = gulp.src(source.definitions + '/**/' + globs.components + '.less')
            .pipe(plumber(settings.plumber.less))
            .pipe(less(settings.less))
            .pipe(autoprefixer(settings.prefix))
            .pipe(replace(comments.variables.in, comments.variables.out))
            .pipe(replace(comments.license.in, comments.license.out))
            .pipe(replace(comments.large.in, comments.large.out))
            .pipe(replace(comments.small.in, comments.small.out))
            .pipe(replace(comments.tiny.in, comments.tiny.out))
            .pipe(flatten())
        ;

        // two concurrent streams from same source to concat release
        uncompressedStream = stream.pipe(clone());
        compressedStream   = stream.pipe(clone());

        // uncompressed component css
        uncompressedStream
            .pipe(plumber())
            .pipe(replace(assets.source, assets.uncompressed))
            .pipe(rename(cssExt))
            .pipe(gulpif(compiledConfig.hasPermission, chmod(compiledConfig.permission)))
            .pipe(gulp.dest(output.uncompressed))
            .pipe(print(log.created))
            .on('end', function() {
            runSequence(`package uncompressed css ${org}`, maybeCallback);
            })
        ;

        // compressed component css
        compressedStream
            .pipe(plumber())
            .pipe(clone())
            .pipe(replace(assets.source, assets.compressed))
            .pipe(minifyCSS(settings.minify))
            .pipe(rename(minCssExt))
            .pipe(gulpif(compiledConfig.hasPermission, chmod(compiledConfig.permission)))
            .pipe(gulp.dest(output.compressed))
            .pipe(print(log.created))
            .on('end', function() {
            runSequence(`package compressed css ${org}`, maybeCallback);
            })
        ;
        });

        gulp.task(`package uncompressed css ${org}`, function() {
            return gulp.src(`${output.uncompressed}/**/${globs.components}.${org}${globs.ignored}.css`)
            .pipe(plumber())
            .pipe(dedupe())
            .pipe(replace(assets.uncompressed, assets.packaged))
            .pipe(concatCSS(`semantic.${org}.css`, settings.concatCSS))
                .pipe(gulpif(compiledConfig.hasPermission, chmod(compiledConfig.permission)))
                .pipe(header(banner, settings.header))
                .pipe(gulp.dest('dist/'))
                .pipe(print(log.created))
            ;
        });

        gulp.task(`package compressed css ${org}`, function() {
            return gulp.src(`${output.uncompressed}/**/${globs.components}.${org}${globs.ignored}.css`)
            .pipe(plumber())
            .pipe(dedupe())
            .pipe(replace(assets.uncompressed, assets.packaged))
            .pipe(concatCSS(`semantic.${org}.min.css`, settings.concatCSS))
                .pipe(gulpif(compiledConfig.hasPermission, chmod(compiledConfig.permission)))
                .pipe(minifyCSS(settings.concatMinify))
                .pipe(header(banner, settings.header))
                .pipe(gulp.dest(output.packaged))
                .pipe(print(log.created))
            ;
        });
};

这背后的想法是,对于每个组织,它都会在 运行 执行 css build 任务之前更新一些参数。

这种方法的问题是 build 进程似乎只使用确认一个 theme.config 文件。我尝试将 build 指向 'theme.org1.config',等等,但它不起作用,也没有提供任何错误。


尝试 3 ??? 如果我忽略了一些明显的路线,请告诉我。我已经为此工作了一段时间,无论我认为自己有多接近,似乎都无法完全发挥作用。

任何帮助将不胜感激!!!

我终于得到了它与以下...

我更新了 ./semantic/build.js 以包含以下内容:

var
  gulp         = require('gulp-help')(require('gulp')),
  runSequence  = require('run-sequence'),
  print        = require('gulp-print'),
  config       = require('./config/user'),
  install      = require('./config/project/install'),
  tasks        = []
;

if(config.rtl) {
  require('./collections/rtl')(gulp);
}
require('./collections/build')(gulp);

const orgs = require('../../build/organizations.json').orgs;
module.exports = function(callback) {
    tasks.push('build-javascript');
    tasks.push('build-assets');
  for(var i = 0; i < orgs.length; i++) {
    console.info('Building Semantic');
    const org = orgs[i];

    gulp.task(`copy theme ${org}`, function() {
      return gulp.src(`./src/themes/${org}/theme.config`)
                 .pipe(gulp.dest('./src/'));
    });

    gulp.task(`build css ${org}`, [`build-css`]);

    gulp.task(`copy output ${org}`, [`build css ${org}`], function() {
      return gulp.src(`./dist/**/*.css`)
                 .pipe(gulp.dest(`../${org}/dist`));
    });

    if( !install.isSetup() ) {
      console.error('Cannot find semantic.json. Run "gulp install" to set-up Semantic');
      return 1;
    }
    tasks.push(`copy theme ${org}`);
    tasks.push(`copy output ${org}`);
  };

  runSequence(...tasks, callback);
};

它采用了我在上面 ATTEMPT 1 中的想法,只是稍微颠倒了操作顺序。虽然 build 似乎不承认更新的 semantic.json 文件,但它确实利用了更新的 theme.config 文件,所以上面的脚本运行 build每个组织然后在 build 完成后将 built 文件复制到另一个目录,更新 theme.config 文件,然后再次执行相同的过程。

我将上面的内容保存到 ./build/override-semantic-ui-build.js,然后我将以下内容添加到我的 package.json 文件:"postinstall": "ncp build/override-semantic-ui-build.js semantic/tasks/build.js" 这样当 semantic-ui 安装在ci 服务器,build 文件将被上述改编覆盖。