There are plenty of tutorials online for this, but after two days of struggle - I have to get some assistance.
I am trying to to add a namespace to Bootstrap so I can use it in Salesforce without interfering with Salesforce's stylesheet.
My goal is to wrap the bootstrap.less with .bs{} so I may refer to it on my page as a resource.
It seems that no matter what, the bootstrap.css isn't compiling.
Bootstrap Test v2
├───bootstrap-3.3.7
├───Gruntfile.js
|───dist
| |───css
| |───bootstrap.css
|───less
|───bootstrap.less
Steps to reproduce:
1) Modify bootstrap.less (wrap content with .bs{})
2) Navigate to Bootstrap Test V2
3) run command 'grunt dist'
output:
C:\Users\json\Desktop\Bootstrap\Bootstrap Test v2>grunt dist
(node:8444) ExperimentalWarning: The http2 module is an experimental API.
Running "clean:dist" (clean) task
>> 1 path cleaned.
Running "less:compileCore" (less) task
>> 1 stylesheet created.
>> 1 sourcemap created.
Running "less:compileTheme" (less) task
>> 1 stylesheet created.
>> 1 sourcemap created.
Running "autoprefixer:core" (autoprefixer) task
>> 1 autoprefixed stylesheet created.
>> 1 sourcemap created.
Running "autoprefixer:theme" (autoprefixer) task
>> 1 autoprefixed stylesheet created.
>> 1 sourcemap created.
Running "csscomb:dist" (csscomb) task
>> Using custom config file "less/.csscomb.json"...
>> Sorting file "dist/css/bootstrap-theme.css"...
>> Sorting file "dist/css/bootstrap.css"...
Running "cssmin:minifyCore" (cssmin) task
>> 1 sourcemap created.
>> 1 file created. 146.01 kB → 121.2 kB
Running "cssmin:minifyTheme" (cssmin) task
>> 1 sourcemap created.
>> 1 file created. 26.13 kB → 23.41 kB
Running "copy:fonts" (copy) task
Created 1 directory, copied 5 files
Running "concat:bootstrap" (concat) task
Running "uglify:core" (uglify) task
File dist/js/bootstrap.min.js created: 69.71 kB → 37.05 kB
>> 1 file created.
Running "commonjs" task
File dist/js/npm.js created.
Done.
Execution Time (2018-05-23 23:58:31 UTC+3)
clean:dist 77ms █ 2%
less:compileCore 994ms ███████████ 25%
less:compileTheme 146ms ██ 4%
autoprefixer:core 538ms ██████ 14%
autoprefixer:theme 90ms █ 2%
csscomb:dist 1.1s ████████████ 28%
cssmin:minifyCore 421ms █████ 11%
cssmin:minifyTheme 53ms █ 1%
copy:fonts 48ms █ 1%
uglify:core 427ms █████ 11%
Total 3.9s
gruntfile:
module.exports = function(grunt) {
require('jit-grunt')(grunt);
grunt.initConfig({
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: {
"dist/css/bootstraptest.css": "less/bootstrap.less" // destination file and source file
}
}
},
watch: {
styles: {
files: ['less/**/*.less'], // which files to watch
tasks: ['less'],
options: {
nospawn: true
}
}
}
});
grunt.registerTask('default', ['less', 'watch']);
};
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
paths: ["assets/css"]
},
files: {"dist/css/bootstrap.css": "less/bootstrap.less"}
},
production: {
options: {
paths: ["assets/css"],
cleancss: true
},
files: {"dist/css/bootstrap.css": "less/bootstrap.less"}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less']);
};
Notes:
1) Using the 'grunt' command isn't working for me, it throws an error 'Running "jekyll:docs" (jekyll) task' and suggest to download jekyll which I already have installed. I have read online that 'grunt dist' should be sufficient - is it correct?
Using the 'node js command line' instead of the regular command line did the trick for me.
Windoes: Start > Node.js command prompt
I followed the steps in this article and it finally worked.
Related
1. Summary
I can't set grunt-clean-console plugin, that it works for all my .html files.
2. Details
grunt-clean-console check browser console errors for .html files.
I want to check browser console errors for all .html files of my site. In official descripition I read, how plugin works for specific values of url key. I have many pages in my site; I don't want add each .html file separately. But I can't find, how I can use patterns.
I find, that I can use patterns for built-in Grunt cwd, src, dest keys. But how I can use glob (or another) patterns for custom keys as url of this plugin?
3. Data
Gruntfile.coffee:
module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-clean-console'
grunt.initConfig
'clean-console':
all:
options:
url: 'output/index.html'
return
example project configuration:
output
│ 404.html
│ index.html
│
├───KiraFirstFolder
│ KiraFirstfile.html
│
└───KiraSecondFolder
KiraSecondFile.html
If I set specific values for url key without patterns as in example above, grunt-clean-console successfully works:
phantomjs: opening page output/index.html
phantomjs: Checking errors after sleeping for 5000ms
ok output/index.html
phantomjs process exited with code 0
Done.
3.1. Steps to reproduce
I run in console:
grunt clean-console --verbose
4. Not helped
4.1. Globbing
Official documentation
Gruntfile.coffee:
module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-clean-console'
grunt.initConfig
'clean-console':
all:
options:
url: 'output/**/*.html'
return
output:
phantomjs: opening page http://output/**/*.html
phantomjs: Unable to load resource (#1URL:http://output/**/*.html)
phantomjs: phantomjs://code/runner.js:30 in onResourceError
Error code: 3. Description: Host output not found
phantomjs://code/runner.js:31 in onResourceError
phantomjs: loading page http://output/**/*.html status fail
phantomjs://code/runner.js:50
phantomjs process exited with code 1
url output/**/*.html has 1 error(s)
>> one of the urls failed clean-console check
Warning: Task "clean-console:all" failed. Use --force to continue.
Aborted due to warnings.
4.2. Building the object dinamically
Official documentation
Gruntfile.coffee (example):
module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-clean-console'
grunt.initConfig
'clean-console':
all:
options:
url:
files: [
expand: true
cwd: "output/"
src: ['**/*.html']
dest: "output/"
]
return
output:
File: [no files]
Options: urls=[], timeout=5, url=["output/**/*.html"]
Fatal error: missing url
4.3. Templates
Official documentation
Gruntfile.coffee:
module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-clean-console'
grunt.initConfig
'clean-console':
all:
options:
url: '<%= kiratemplate %>'
kiratemplate: ['output/**/*.html'],
return
output:
phantomjs: opening page http://output/**/*.html
phantomjs: Unable to load resource (#1URL:http://output/**/*.html)
phantomjs: phantomjs://code/runner.js:30 in onResourceError
Error code: 3. Description: Host output not found
phantomjs://code/runner.js:31 in onResourceError
loading page http://output/**/*.html status fail
phantomjs://code/runner.js:50
phantomjs process exited with code 1
url output/**/*.html has 1 error(s)
>> one of the urls failed clean-console check
Warning: Task "clean-console:all" failed. Use --force to continue.
Aborted due to warnings.
Create a function before the grunt.initConfig part that utilizes grunt.file.expand. For instance:
Gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks 'grunt-clean-console'
// Add this function...
function getFiles() { return grunt.file.expand('output/**/*.html'); }
grunt.initConfig({
'clean-console': {
all: {
options: {
url: getFiles() // <-- invoke the function here.
}
}
}
// ...
});
// ...
}
Notes:
The getFiles function returns an array of file paths for all .html files matching the given glob pattern, i.e. 'output/**/*.html'.
The value of the options.url property is set to getFiles() to invoke the function.
The source config example below processes files from src dir. There is src2 dir which also should be processed with the same tasks and putted to build2. What changes required in config.
module.exports = function (grunt) {
var saveLicense = require('uglify-save-license');
grunt.initConfig({
clean : {
build : {
src : ['build']
},
},
copy : {
files : {
cwd : 'src',
src : '**/*',
dest : 'build',
expand : true
}
},
...
Both grunt-contrib-copy and grunt-contrib-clean, like many other grunt plugins, allow multiple Targets to be specified in each Task.
For your scenario you can simply configure two Targets in the copy task (one Target to copy the src folder and another Target to copy the src2 folder).
You can also configure two Targets in the clean task (one Target to clean the build folder and another Target to clean the build2 folder).
Gruntfile.js
Your Gruntfile.js can be configured as ass follows:
module.exports = function(grunt) {
var saveLicense = require('uglify-save-license');
grunt.initConfig({
// The 'clean' task now includes two targets.
// named 'build1' and 'build2'
clean: {
build1: {
src: ['build']
},
build2: {
src: ['build2']
}
},
// The 'copy' task now includes two targets.
// named 'src1' and 'src2'
copy: {
src1: {
cwd: 'src',
src: '**/*',
dest: 'build',
expand: true
},
src2: {
cwd: 'src2',
src: '**/*',
dest: 'build2',
expand: true
}
}
// ...
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
// Registering the Targets in the Tasks....
grunt.registerTask('copySrc1', ['copy:src1']);
grunt.registerTask('cleanBuild1', ['clean:build1']);
grunt.registerTask('copySrc2', ['copy:src2']);
grunt.registerTask('cleanBuild2', ['clean:build2']);
grunt.registerTask('copyBoth', ['copy']);
grunt.registerTask('cleanBoth', ['clean']);
};
Running the Grunt Tasks
You'll notice that there are six calls to the .registerTask(...) function at the end of the snippet. Namely; copySrc1, cleanBuild1, copySrc2, cleanBuild2, copyBoth, and cleanBoth.
They allow you to run the following commands via your command line:
$ grunt copySrc1
(This will copy the src folder to the build folder)
$ grunt cleanBuild1
(This will clean the build folder)
$ grunt copySrc1
(This will copy the src2 folder to the build2 folder)
$ grunt cleanBuild2
(This will clean the build2 folder)
$ grunt copyBoth
(This will copy the src folder to the build folder and copy the src2 folder to the build2 folder)
$ grunt cleanBoth
(This will clean both the build and build2 folders)
Notes
You probably only need to keep the two .registerTask(...) functions as follows:
grunt.registerTask('copyBoth', ['copy']);
grunt.registerTask('cleanBoth', ['clean']);
However, I included the other four .registerTask(...) functions as they demonstrate how you can call a single Target inside a Task using the semicolon notation (:). For example:
grunt.registerTask('copySrc1', ['copy:src1']);
In the above snippet the ['copy:src1'] part simply runs only the Target named src1 inside the copy Task.
Whereas:
grunt.registerTask('copyBoth', ['copy']);
... does not reference any Targets in the copy task, (i.e. no semicolon notation is used), therefore all Targets will be run.
To further understand Tasks, Targets, you can read my answer to this post.
Hope that helps!
I'm trying to use grunt in my ASP project, but for whatever reasons have get a stupid warning-message from Visual Studio.
How you can see down, the bower-task has been executed, but haven't uglify- and less-tasks. Gruntfile.js and folder "wwwroot" are in the same folder. What's wrong ?
This is console output in Visual Studio 2015:
> cmd.exe /c grunt -b "c:\T\BW\src\BW" --gruntfile "c:\T\BW\src\BW\gruntfile.js" bower
Running "bower:install" (bower) task
>> Installed bower packages
>> Copied packages to c:\T\BW\src\BW\wwwroot\lib
Done, without errors.
Process terminated with code 0.
> cmd.exe /c grunt -b "c:\T\BW\src\BW" --gruntfile "c:\T\BW\src\BW\gruntfile.js" uglify_default
Running "uglify:uglify_target" (uglify) task
Process terminated with code 0.
>> Destination wwwroot/lib/angular/angular.js not written because src files were empty.
>> No files created.
Done, without errors.
> cmd.exe /c grunt -b "c:\T\BW\src\BW" --gruntfile "c:\T\BW\src\BW\gruntfile.js" less
Running "less:dev" (less) task
>> Destination wwwroot/css/site.css not written because no source files were found.
Done, without errors.
Process terminated with code 0.
This is my gruntfile.js:
grunt.initConfig({
bower: {
install: {
options: {
targetDir: "wwwroot/lib",
layout: "byComponent",
cleanTargetDir: false
}
}
},
uglify: {
uglify_target: {
files: {
"wwwroot/lib/angular/angular.js":["src/angular.min.js"]
}
}
},
less: {
dev: {
files: {
"wwwroot/css/site.css": ["less/site.less"]
},
options: {
sourceMap: true,
}
}
},
});
grunt.registerTask("default", ["bower:install"]);
grunt.loadNpmTasks("grunt-bower-task");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-less");
Are you sure "wwwroot/lib/angular/angular.js":["src/angular.min.js"] is correct in your uglify step? Uglify is for minifying files, so it would seem as if you have the destination and source parameters reversed. You are also getting the message Destination wwwroot/lib/angular/angular.js not written because src files were empty. which would seem to indicate that as well.
The less step seems correct, but it can't find the less file you are trying to compile. Are you sure that site.less exists in a less folder?
Here is the less portion of the grunt file I just wrote, and it seems to work well, although getting the sourcemap to actually generate is still an issue. This is pretty much an exact equivalent of VS 2013 with Web Essentials installed. Compiling all less files in the content folder using autoprefix for the browsers we support, and puts the .css back into the content folder. It doesn't compile any less file that starts with _, as those are just includes/variables.
less: {
development: {
options: {
paths: ["content"],
compress: true,
plugins: [
new (require('less-plugin-autoprefix'))({ browsers: ["IE >= 9, firefox > 10, last 2 Chrome versions, last 2 safari versions, last 2 ios versions"], map: { inline: false } })
]
},
files: [{
expand: true,
cwd: 'content',
src: ['*.less', '!_*.less'],
dest: 'content',
ext: '.css'
}]
}
},
using gurunt syncall, I want to dynamically sync every dir(and new dir created in the futrue) in project root except 'node_modules' dir to another dir.
using grunt watchall, I want to watch those dirs, when there are some changes in a dir, I want to automaticlly run the corresponding sync task.
here is my project root's structure:
├── Gruntfile.js
├── addon1
│ └── a.toc
├── adon3
│ └── 3.toc
├── node_modules
│ ├── grunt
│ ├── grunt-contrib-watch
│ └── grunt-sync
└── package.json
the grunt syncall command is ok, here is the result:
➜ testsync grunt syncall
Running "config" task
Running "sync:addon1" (sync) task
Running "sync:adon3" (sync) task
Done, without errors.
but the grunt watchall not ok. can you tell me why watchall tasks not work and how to fix it?
I start the command, and change and save the file '3.toc' in dir 'adon3', then grunt say:
➜ testsync grunt watchall
Running "config" task
Running "watch" task
Waiting...
>> File "adon3/3.toc" changed.
Running "sync:adon3" (sync) task
Verifying property sync.adon3 exists in config...ERROR
>> Unable to process task.
Warning: Required config property "sync.adon3" missing. Use --force to continue.
Aborted due to warnings.
here is my Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({});
var destdir = "/Users/morrxy/project/testdest/";
// dynamic config sync and watch's targets for every dir except for node_modules
grunt.registerTask('config', 'config sync and watch', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config sync's targets
var sync = grunt.config.get('sync') || {};
sync[dir] = {
files: [{
cwd: dir,
src: '**',
dest: destdir + dir
}]
};
grunt.config.set('sync', sync);
// config watch's target
var watch = grunt.config.get('watch') || {};
watch[dir] = {
files: dir + '/**/*',
// is next line has problem?
// running 'grunt watchall'
// when I change and save the file '3.toc' in dir 'adon3', terminal say:
// >> File "adon3/3.toc" changed.
// Running "sync:adon3" (sync) task
// Verifying property sync.adon3 exists in config...ERROR
// >> Unable to process task.
// Warning: Required config property "sync.adon3" missing.
// but why 'grunt syncall' can work?
tasks: 'sync:' + dir
};
grunt.config.set('watch', watch);
});
});
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('syncall', ['config', 'sync']);
grunt.registerTask('watchall', ['config', 'watch']);
};
Finally, I solved this problem. I add a github repo for this question. If you want test, you can clone it run it locally. https://github.com/morrxy/dynasync
The reason watchall can watch files changes but can't run the corresponding sync task is that when watch find files changed, the config for each sync is finnished running, so the config for that sync target is gone, we didn't save the running config any where. So to solve this problem, we could add the config task into the watch task before the sync task, like this tasks: ['config_sync', 'sync:' + dir].
in new Gruntfile.js, I split the config task to two task, one for config watch, one for config sync, in the watch task, using the config sync task. Here is the new Gruntfile.js
module.exports = function(grunt) {
var destdir = "/media/data/projects/dynasync_dest/";
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
// dynamic config sync's targets for every dir except for node_modules
grunt.registerTask('config_sync', 'dynamically config sync', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config this dir's sync target
var sync = grunt.config.get('sync') || {};
sync[dir] = {
files: [{
cwd: dir,
src: '**/*',
dest: destdir + dir
}]
};
grunt.config.set('sync', sync);
});
});
// dynamic config watch's targets for every dir except for node_modules
grunt.registerTask('config_watch', 'dynamically config watch', function() {
grunt.file.expand({filter: 'isDirectory'},
['*', '!node_modules']).forEach(function(dir) {
// config this dir's watch target
var watch = grunt.config.get('watch') || {};
watch[dir] = {
files: dir + '/**/*',
// this line solve the problem
// when find file change, first dynamically config sync and then sync the dir
tasks: ['config_sync', 'sync:' + dir]
};
grunt.config.set('watch', watch);
});
});
grunt.registerTask('syncall', ['config_sync', 'sync']);
grunt.registerTask('watchall', ['config_watch', 'watch']);
grunt.registerTask('default', ['watchall']);
};
This time, when watch find file changes, it can run the corresponding sync task. like this
grunt watchall
Running "config_watch" task
Running "watch" task
Waiting...
>> File "adon3/3.toc" changed.
Running "config_sync" task
Running "sync:adon3" (sync) task
Done, without errors.
Completed in 0.888s at Thu Apr 10 2014 14:01:26 GMT+0800 (CST) - Waiting...
I use grunt-contrib-concat, but it doesn't appear to work.
All file are in the folder.
I used --verbose to see the details, but everything seems to be working correctly.
concat: {
options: {
// define a string to put between each file in the concatenated output
separator: ';'
},
dist: {
// the files to concatenate
src: [
//'assets/javascript/components/*.js',
'assets/javascript/components/jquery-ui-1.10.3.custom.js',
'assets/javascript/components/spectrum.js',
'assets/javascript/components/prefixfree.min.js',
'assets/javascript/src/jquery.menu_css3.js'
],
// the location of the resulting JS file
dest: 'assets/javascript/jquery.<%= pkg.name %>.min.js'
}
},
Running the tasks with --verbose:
Running "concat" task
Running "concat:dist" (concat) task
Verifying property concat.dist exists in config...OK
Files: assets/javascript/src/jquery.menu_css3.js -> assets/javascript/jquery.menu_css3.min.js
Options: separator=";", banner="", footer="", stripBanners=false, process=false
Reading assets/javascript/src/jquery.menu_css3.js...OK
Writing assets/javascript/jquery.menu_css3.min.js...OK
File "assets/javascript/jquery.menu_css3.min.js" created.
Running "uglify" task
Running "uglify:dist" (uglify) task
Verifying property uglify.dist exists in config...OK
Files: assets/javascript/jquery.menu_css3.min.js -> assets/javascript/jquery.menu_css3.min.js
Options: banner="", footer="", compress={"warnings":false}, mangle={}, beautify=false, report=false
Minifying with UglifyJS...Reading assets/javascript/jquery.menu_css3.min.js...OK
OK
Writing assets/javascript/jquery.menu_css3.min.js...OK
File "assets/javascript/jquery.menu_css3.min.js" created.