gulp compile multiple css from multiple sass folders with single command? - build

I have the following files structure:
themes
folder1
-scss
-style.scss
folder2
-scss
-style.scss
foldern
-scss
-style.scss
package.json
gulpfile.js
Need Output in this format:
themes
folder1
-scss
-style.scss
css
-style.css
folder2
-scss
-style.scss
css
-style.css
foldern
-scss
-style.scss
css
-style.css
package.json
gulpfile.js
gulpfile.js:
(function () {
'use strict';
var gulp = require('gulp'),
eslint = require('gulp-eslint'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps')
gulp.task('sass', function () {
return gulp
.src('./**/scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass({
outputStyle: 'uncompressed'
}).on('error', sass.logError))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./**/css'));
});
gulp.task('watch', gulp.series('sass', function () {
gulp.watch('./scss/**/*.scss', gulp.series('sass'));
}));
})();
When I compiled using above gulpfile then it's creating **/css/folder1/stle.css **/css/folder2/style.css folders in the theme directory. how can I compile in this format? Is there any specific plugin there in gulp for this.
Thanks in advance.

Try this:
var gulp = require('gulp'),
sass = require('gulp-sass'),
// etc.
// two more plugins
rename = require('gulp-rename')
path = require('path');
gulp.task('sass', function () {
return gulp
.src('./**/scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass({
outputStyle: 'uncompressed'
}).on('error', sass.logError))
.pipe(sourcemaps.write('./'))
// rename the current file's parent directory
.pipe(rename(function (file) {
// file.dirname = current folder, your "scss"
// then get the parent of the current folder, e.g., "folder1", "folder2", etc.
let parentFolder = path.dirname(file.dirname)
// set each file's folder to "folder1/css", "folder2/css", etc.
file.dirname = path.join(parentFolder, 'css');
}))
.pipe(gulp.dest('.'));
});

Related

Using custom theme with ember-bootstrap add-on

I'm using ember-bootstrap add-on which is working fine but I would like to use the Cerulean theme from https://bootswatch.com/cerulean/. If I just overwrite the .CSS files in bower_components/bootstrap/dist/css then I expect they will be overwritten the next time I do a bower install or upgrade ember. How do I get around that please?
First of all you need to manually install bootstrap:
$ bower install bootstrap --save
Then edit ember-cli-build.js so it looks like that:
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
// If you do not use ember-bootstrap - then you can omit these lines
'ember-bootstrap': {
'importBootstrapCSS': false
}
});
app.import(app.bowerDirectory + '/bootstrap/dist/css/bootstrap.css');
app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
app.import(app.bowerDirectory + '/bootstrap/dist/fonts/glyphicons-halflings-regular.woff', {
destDir: 'fonts'
});
return app.toTree();
};
Now you have fully working bootstrap. To add Celurian theme copy its bootstrap.css to vendor/ directory.
Then remove original bootstrap.css from ember-cli-build.js and add theme css:
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
// If you do not use ember-bootstrap - then you can omit these lines
'ember-bootstrap': {
'importBootstrapCSS': false
}
});
//app.import(app.bowerDirectory + /bootstrap/dist/css/bootstrap.css');
// The name does not matter, default bootstrap.css will work as well
app.import('vendor/celurian.css');
app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
app.import(app.bowerDirectory + '/bootstrap/dist/fonts/glyphicons- halflings-regular.woff', {
destDir: 'fonts'
});
return app.toTree();
};
So, in essence, you need to add required files to vendor directory and import them in ember-cli-build.js.
The other way would be to use SASS and just import required files from app.scss.

Ember addon to add files to root directory

I have an addon which needs to copy a set of JS files from their bower directory to the Ember app's root of /dist (this is for scoping rules associated with service workers). I thought maybe I could use the treeForApp hook but while I'm getting no errors I'm also not getting the desired result.
The index.js is:
const Funnel = require('broccoli-funnel');
module.exports = {
name: 'ember-upup',
treeForApp: function(tree) {
tree = new Funnel(tree, { include:
[
'bower_components/upup/dist/upup.min.js',
'bower_components/upup/dist/upup.sw.min.js'
]});
return this._super.treeForApp.call(this, tree);
},
Note: I thought I might be able to solve this problem by simply copying the javascript files as part of index.js postBuild hook but while this DOES put the JS files into the dist folder's root it is not served by ember-cli's ember serve apparently if not pushed through one of it's build pipelines.
Stefan Penner has now pointed out the the dist directory is for developers to look at but serving is actually done within the tmp directory structure ... this explains why my "hack" didn't work.
It looks like my initial attempt wasn't entirely far off. To make it work you need to hook into the treeForPublic hook like so:
const path = require('path');
const Funnel = require('broccoli-funnel');
const mergeTrees = require('broccoli-merge-trees');
const JS_FILES = ['upup.min.js', 'upup.sw.min.js'];
module.exports = {
treeForPublic: function() {
const upupPath = path.join(this.app.bowerDirectory, 'upup/dist');
const publicTree = this._super.treeForPublic.apply(this, arguments);
const trees = [];
if (publicTree) {
trees.push(publicTree);
}
trees.push(new Funnel(upupPath, {
include: JS_FILES,
destDir: '/'
}));
return mergeTrees(trees);
}
}
Hope that helps.

How to resolve path in gruntjs file?

I have the following file structure:
application
|- deploy
|----- Gruntfile.js
|-- package.json
|-- public
|----- js
|-- views
|----- templates
In my Gruntfile.js file I'm trying to compile jade templates likes the following:
module.exports = function(grunt) {
var templatizer = require('templatizer');
grunt.loadNpmTasks('grunt-execute');
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
execute: {
templatizer: {
options: {
templatesDir: 'need path for ../views/templates', // ?
outputFile: 'need path for ../public/js/templates.js' // ?
},
call: function(grunt, options) {
templatizer(options.templatesDir, options.outputFile);
grunt.log.writeln('Templatizer done');
}
}
}
});
// Default task(s).
grunt.registerTask('default', ['execute:templatizer']);
};
I don't understand how could I resolve pathes for templatesDir and outputFile options?
it would be easier for you to use the templatizer-plugin
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-templatizer');
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
templatizer: {
files: {
'public/js/templates.js': ['views/templates/*'] // paths are relative from your gruntfile
}
}
}
});
// Default task(s).
grunt.registerTask('default', ['templatizer']);
whatever you do, it is almost always wrong to "misuse" the execute-plugin. search the grunt-plugins, and if no plugin exists, create one using grunt-init gruntplugin. it is really easy.
EDIT:
i dont like the gruntfile to be in the deploy-dir. in my opinion it should always be in the root directory of your project. if you want to leave it in the deploy directory, you run it there right? then your config would look like this (remember: paths are relative from your gruntfile!):
templatizer: {
files: {
'../public/js/templates.js': ['../views/templates/*']
}
}

Adding vendor CSS libraries with Ember CLI and broccoli-compass

I'm having trouble adding CSS libraries to my Ember CLI project when using the broccoli-compass plugin.
I've added this line to my brocfile:
app.styles = function() {
return compileCompass(this.appAndDependencies(), this.name + '/styles/app.scss', {
outputStyle: 'expanded',
sassDir: this.name + '/styles',
imagesDir: 'public/images',
cssDir: '/assets',
importPath: 'vendor'
});
};
but now I'm stuck. I've tried
app.import('vendor/bootstrap/docs/assets/css/bootstrap.css');
but this doesn't work, because (I think) I've overwritten app.styles.
I've tried adding an importPath to my Compass config, so that I can #import in my SASS files, but that hasn't worked either.
It seems the app.styles = ... line above overwrites some Ember CLI code, so the app.import suggestion from Ember CLI guides doesn't work.
After spending some time with Broccoli I figured out how to serve the vendor folder:
var pickFiles = require('broccoli-static-compiler');
var vendor = pickFiles('vendor', {srcDir: '/', destDir: '/vendor'});
Now broccoli serve serves everything in my vendor folder, and
#import 'vendor/bootstrap/docs/assets/css/bootstrap.css';
works in my app.scss file.
Of course, I will need to do more work so that only the distribution versions of the vendor assets are included in the final build.
Version 0.0.5 fixes the issue, here's what worked for me:
var compileCompass = require('broccoli-compass');
app.styles = function() {
return compileCompass(this.appAndDependencies(), this.name + '/styles/app.scss', {
outputStyle: 'expanded',
sassDir: this.name + '/styles',
imagesDir: 'public/images',
cssDir: '/assets',
importPath: [
process.cwd() + '/vendor/foundation/scss'
],
});
};
Now I'm able to do #import foundation in my scss file.
You can add a vendor file in addon.scss adding a treeForAddon hook in index.js of the addon, merging the vendor directory with a Funnel before the compilation.
treeForAddon: function(tree) {
this._requireBuildPackages();
if (!tree) {
return tree;
}
var addonTree = this.compileAddon(tree);
var vendorCss = new Funnel(this._treeFor('vendor'), {
srcDir: '/css'
});
var mergedStylesTree = new MergeTrees([this._treeFor('addon-styles'), vendorCss]);
var stylesTree = this.compileStyles(mergedStylesTree);
return MergeTrees([addonTree, stylesTree].filter(Boolean));
}

Ember-CLI: Is there a way to copy a (vendor) directory to /public/assets?

In an Ember-CLI project, if I add a directory containing webfonts and their CSS stylesheets to the public/assets directory, I can use them with something like #import 'assets/font/regular/stylesheet.css. This works fine.
Ideally though, I'd like to keep these assets out my git repository, and instead bower install them as client-side dependencies, but how can these assets be used in the Ember-CLI build?
The documentation mentions app.import(FILE) in Brocfile.js, which works for CSS stylesheets, but not for a WOFF font file:
$ ember build
version: 0.0.28
Build failed.
Error: Path or pattern "nicefont.woff" did not match any files
at Object.multiGlob (/(PATH)/node_modules/ember-cli/node_modules/broccoli-static-compiler/node_modules/broccoli-kitchen-sink-helpers/index.js:216:13)
at /(PATH)/demo/node_modules/ember-cli/node_modules/broccoli-static-compiler/index.js:25:27
at invokeCallback (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:228:21)
at publish (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:176:9)
at publishFulfillment (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/promise.js:312:5)
at flush (/(PATH)/node_modules/ember-cli/node_modules/rsvp/dist/commonjs/rsvp/asap.js:41:9)
Also, I would like to specify a directory, which is app.import() refuses.
Is there an Ember-CLI / Brocolli way of doing this?
I thought I was stuck on this issue, but apparently a cup of tea and explicitly phrasing the question on StackOverflow pushed me in the right direction…
If you install a client-side dependency with bower, then in an Ember-CLI project these will end up in vendor/. To use (parts of) them without changing them, we can use Broccoli's slightly awkwardly named broccoli-static-compiler. First, install two build-time dependencies:
npm install --save-dev broccoli-static-compiler
npm install --save-dev broccoli-merge-trees
In Brocfile.js add at the top below the EmberApp import:
var mergeTrees = require('broccoli-merge-trees');
var pickFiles = require('broccoli-static-compiler');
And at the bottom of Brocfile.js:
// Remove this line:
// module.exports = app.toTree()
// Copy only the relevant files:
var fontOpenSans = pickFiles('vendor/font-opensans', {
srcDir: '/',
files: ['**/*.woff', '**/stylesheet.css'],
destDir: '/assets/fonts'
});
// Merge the app tree and our new font assets.
module.exports = mergeTrees([app.toTree(), fontOpenSans]);
Here our client-side dependency is a font-opensans, which refers to a local git repository containing a copy of the Open Sans webfont.
That is all! To use the web-font, link to assets/ from index.html:
<link rel="stylesheet" href="assets/fonts/opensans_regular/stylesheet.css">
This was tested with ember-cli 0.0.40 and a few earlier versions.
The supported answers are a bit out of date. At the time of this writing Ember CLI 0.2.2, there is support for directly copying/fingerprinting vendor folders you want in your assets directory.
// Brocfile.js
var app = new EmberApp();
...
var extraAssets = new Funnel('bower_components/a-lovely-webfont', {
srcDir: '/',
include: ['**/*.woff', '**/stylesheet.css'],
destDir: '/assets/fonts'
});
module.exports = app.toTree(extraAssets);
Documentation here
Similar to answer from JeroenHoek, in ember-cli, version 0.0.40, I ended up doing it right under the app.import before module.exports. I use the augmentation pattern to encapsulate what I'm trying to do so that when/if it's no longer necessary, or there is a more preferred way to do it, I can clean it up easily, and remove modules that aren't used anymore.
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var app = new EmberApp();
// Use `app.import` to add additional libraries to the generated
// output files.
//
// ... [comments omitted]
app.import('vendor/moment/moment.js');
var tree = app.toTree();
tree = (function mergeFontAwesomeTree(tree) {
var mergeTrees = require('broccoli-merge-trees');
var pickFiles = require('broccoli-static-compiler');
var fontawesome = pickFiles('vendor/fontawesome/fonts', {
srcDir: '/',
destDir: '/fonts'
});
return mergeTrees([tree, fontawesome]);
})(tree);
module.exports = tree;