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

我们两清 提交于 2019-12-11 04:25:22

问题


I'm trying to create a prototype at the moment and keep running into walls.

I'm working on a project where we hope to have one code base that all of our end-users use and where the organization that user is affiliated with will determine the skin(css file) that gets applied to the site. Semantic-UI seems like a great fit for this as it has the concept of themes and a build process around it. I wanted to tap into the power of this build process without having to completely rewrite it.

Is there a way to run a semantic ui build task and have it produce multiple css files?

Here is what I've tried so far:

ATTEMPT 1 After running npm install --save-dev semantic-ui and choosing all of the default options on the install, I updated the semantic/tasks/build.js file to the following:

/*******************************
          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);
};

The idea behind this being that for every organization it would have its own semantic.json and theme.config files. These would overwrite the default files(/semantic.json and /semantic/src/theme.config respectively) and then create a new build-css task for each one.

The problem with this approach is that the build process only seems to use the original semantic.json file that was in place before the build started even though it is successfully getting overwritten. For instance, in the original semantic.json file, the value for output.packaged is 'dist/'. semantic.json is successfully getting overwritten and the output.packaged value is dist/org1 before the build-css task gets executed, but all of the output files still end up in 'dist/'.


ATTEMPT 2 After running npm install --save-dev semantic-ui and choosing all of the default options on the install, I updated the semantic/tasks/build/css.js file to the following:

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))
            ;
        });
};

The idea behind this being that for every organization it would update a few parameters before running the css build task.

The problem with this approach is that the build process only seems to use the acknowledge a theme.config file. I tried pointing the build to 'theme.org1.config', etc, but it doesn't work and doesn't provide any error.


ATTEMPT 3 ??? Please let me know if I'm ignoring some obvious route. I've been working on this for a while and no matter how close I think I'm getting, nothing seems to work fully.

Any help would be greatly appreciated!!!


回答1:


I finally got this to work with the following...

I updated ./semantic/build.js to contain the following:

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);
};

It takes the idea that I had in ATTEMPT 1 above and just reverses the order of operations a bit. While the build doesn't seem to acknowledge the updated semantic.json file, it does utilize the updated theme.config file, so the above script runs the build for each organization and then after that build is done it copies the built files to another directory, updates the theme.config file and then performs the same process again.

I have the above saved to ./build/override-semantic-ui-build.js and then I added the following to my package.json file: "postinstall": "ncp build/override-semantic-ui-build.js semantic/tasks/build.js" so that when semantic-ui gets installed on the ci server, that build file will get overwritten with the above adaptation.



来源:https://stackoverflow.com/questions/44031816/is-there-a-way-to-build-multiple-semantic-ui-themes-in-the-same-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!