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

时间:2017-05-17 17:55:28

标签: gulp semantic-ui

我正在尝试创建一个原型并继续撞墙。

我正在开发一个项目,我们希望有一个代码库,我们所有的最终用户都使用这个代码库,而用户所在的组织将确定应用于该站点的外观(css文件)。 Semantic-UI似乎非常适合这个,因为它具有主题的概念和围绕它的构建过程。我想利用这个构建过程的强大功能,而不必完全重写它。

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

这是我到目前为止所尝试的内容:

ATTEMPT 1 运行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任务。

这种方法的问题在于构建过程似乎只使用原始的semantic.json文件,该文件在构建开始之前就已存在,即使它已被成功覆盖。 例如,在原始semantic.json文件中,output.packaged的值为'dist /'。在semantic.json任务执行之前,output.packaged成功被覆盖且dist/org1值为build-css,但所有输出文件仍然以'dist /'结尾。< / p>

ATTEMPT 2 运行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构建任务之前更新一些参数。

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

ATTEMPT 3 ??? 如果我忽略了一些明显的路线,请告诉我。我一直在研究这个问题,无论我认为我有多接近,似乎没有什么能够完全发挥作用。

任何帮助都将非常感谢!!!

1 个答案:

答案 0 :(得分:2)

我终于可以使用以下内容...

我更新了./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 中只是略微颠倒了操作的顺序。虽然构建似乎不承认更新的semantic.json文件,但它确实使用了更新的theme.config文件,因此上面的脚本为每个组织运行构建,然后在构建完成后复制将文件构建到另一个目录,更新theme.config文件,然后再次执行相同的过程。

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