I am almost absolutely new to grunt.
I used grunt with bootstrap 3.1.1 and the grunt watch-command worked out great. My bootstrap.min.css file was compiled every time. (i upload my bootstrap.min.css)
Later on i lost my 3.1.1 grunt file (long story short my computer crashed).
So now with Bootstrap 3.2.0 i was going to restablish my grunt-work-flow.
But now when i use grunt watch i only get the "bootstrap.css" and "bootstrap.theme.css" compiled.
I have spent the last hours to figure this out without success.
WHAT I WANT
I want grunt watch to compile the minified "bootstrap.min.css"
So how do i call the min.css-function on the watch?
I will be glad to get some help.
Grunt watch will only watch the files then run tasks you have set. I am assuming in your gruntfile you ahve something like this:
css: {
files: [
'bootstrap.css',
],
tasks: ['less'],
},
In the less task you should have something like below. Note the cleancss option being set to true:
options: {
cleancss: true
},
files: {
"dest/bootstrap.min.css": "src/bootstrap.css",
"dest/bootstrap.theme.min.css": "src/bootstrap.theme.css"
}
UPDATE:
Based on the file you uploaded you should be running the cssmin:core task when the watch is triggered.
UPDATE 2:
To update the watch task you can just add the cssmin:core task to the less subtask:
less: {
files: 'less/**/*.less',
tasks: ['less', 'cssmin:core]
}
Here you are telling it to run the less task, followed by the cssmin task whenever one of the less files is changed while watching.
Your gruntfile.js will have a 'watch' section as below
watch: {
src: {
files: '<%= jshint.core.src %>',
tasks: ['jshint:src', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/**/*.less',
tasks: 'less'
}
},
The tasks under less subsection define the tasks that 'grunt watch' will run. In Bootstrap 3.3.2 (I guess in 3.1.1 also it would be the same) is the 'cssmin' task that minifies the core bootstrap css. So you need to add the task to less so the code above becomes
watch: {
src: {
files: '<%= jshint.core.src %>',
tasks: ['jshint:src', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/**/*.less',
tasks: ['less', 'cssmin']
}
},
None of the above worked for me. Looks like the css minification command changed to cssmin:minifyCore so I have updated my watch task to the following:
watch: {
src: {
files: '<%= jshint.core.src %>',
tasks: ['jshint:core', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/**/*.less',
tasks: ['less', 'cssmin:minifyCore']
}
},
Hopefully this helps others!
Related
I have successfully used the webfonts-loader package to generate a font and class-definitions for icons, but it isn't served by my nuxt dev server. There is a styletag in my head with:
#font-face {
font-family: "TopLoggerIcons";
src: url("/myfont.eot?#iefix") format("embedded-opentype"), url("/myfont.woff2") format("woff2");
}
But the requested http://localhost:3010/myfont.woff2 gives a 404. I had this working in the nuxt version before 2.0 (and before webpack 4), where the file is served from http://localhost:3010/_nuxt/myfont.woff2. The font is currently also served from there, but the path in the font-face declaration is wrong. I'm wondering what has changed here removing the (required?) _nuxt part in the path.
In my nuxt.config.js file I have:
build: {
extend(config, ctx) {
config.module.rules.push({
test: /plugins\/icons\.js$/,
use: ['vue-style-loader', 'css-loader', 'webfonts-loader'],
})
},
}
Now according to the example on the webfonts-loader lib I need to use the MiniCssExtractPlugin.loader instead of the vue-style-loader, but that doesn't work. I read here that it is internally used by nuxt, but i don't know how to add it here.
Hope anyone has an idea where to look...
Ok, just figured it out: you have to use the publicPath option of the webfonts-loader package:
extend(config, ctx) {
config.module.rules.push({
test: /plugins\/icons\.js$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'webfonts-loader',
options: {
publicPath: config.output.publicPath,
},
}
],
})
}
The config.output.publicPath is /_nuxt/.
I am currently building my .vue files into single file components with Browserify.
The only problem with this is each SFC includes the Vue runtime into the file causing the filesize to be much larger than it needs to be since the Vue runtime is common code across multiple pages and SFCs.
I was hoping to use Browserify to separate it out and load the common across pages.
I've read a bunch of different articles on the topic, but haven't been able to make any of them work.
Here is how I am building my Vue SFCs and excluding the runtime:
b
.transform('vueify')
.transform(
{global: true},
envify({NODE_ENV: 'production'})
)
.external('vue')
.bundle()
Then I would like to just load the Javascript separately like so:
<script src="vue.runtime.min.js"></script>
<script src="built-sfc.js"></script>
I've tried a whole bunch of different combinations of building the SFCs and the Vue runtime, but nothing works and I have run out of ideas!
I figured it out eventually, part of the issue was other problems in the our Vue building in Grunt.
But this is the Grunt commands we have for buildings the runtime and SFCs separately
vueRuntime: {
expand: true,
cwd: 'node_modules/vue/dist/',
src: 'vue.runtime.min.js',
dest: 'js/libs',
ext: '.js',
extDot: 'first',
options: {
configure: b => b
.require('vue')
.transform(
// Required in order to process node_modules files
{global: true},
envify({NODE_ENV: 'production'})
)
.bundle(),
browserifyOptions: {
debug: false
}
}
},
vue: {
expand: true,
cwd: 'js/pages/',
src: '**/*.vue.js',
dest: 'js/pages',
ext: '.js',
extDot: 'first',
options: {
configure: b => b
.transform('vueify')
.transform(
// Required in order to process node_modules files
{global: true},
envify({NODE_ENV: 'production'})
)
.external('vue')
.bundle(),
browserifyOptions: {
debug: false
}
}
}
I've set Grunt to compile compass with watch task and now I'd like to copy useful files from bower_components/... - e.g. bower_components/jquery/jquery.min.js, because bower produces a lot of unnecessary files, which I want to get rid of, when uploading to server.
CMD produces warning and stops process;
Reading C:\Users\sjiamnocna\Documents\NetBeansProjects\PM_new\node_modules\grunt-bowercopy\package.json...OK
Parsing C:\Users\sjiamnocna\Documents\NetBeansProjects\PM_new\node_modules\grunt-bowercopy\package.json...OK
Reading bower.json...OK
Parsing bower.json...OK
Loading "bowercopy.js" tasks...OK
+ bowercopy
Loading "gruntfile.js" tasks...OK
+ default, dog
No tasks specified, running default tasks.
Running tasks: default
Running "default" task
Running "bowercopy" task
Running "bowercopy:copythat" (bowercopy) task
Verifying property bowercopy.copythat exists in config...OK
File: [no files]
Options: srcPrefix="bower_components", destPrefix="files", ignore=[], report, runBower=false, clean=false, copyOptions={}
Using srcPrefix: bower_components
Using destPrefix: files
Warning: Nothing was copied for the "copythat" target Use --force to continue.
My gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
watch: {
scss: {
files: ['files/style/sass/*.scss'],
tasks: ['compass']
}
},
compass: {
dist: {
options: {
sassDir: 'files/style/sass',
cssDir: 'files/style',
environment: 'development'
}
}
},
bowercopy: {
copythat: {
options: {
runBower: false,
srcPrefix: 'bower_components',
destPrefix: 'files'
},
script: {
'jquery/dist/jquery.min.js': 'script/lib/jquery.min.js',
'jquery-ui/jquery-ui.min.js': 'script/lib/jquery-ui.min.js',
'masonry/dist/masonry.pkgd.min.js': 'script/lib/masonry.pkgd.min.js',
'sweetalert/dist/sweetalert.min.js': 'script/lib/sweetalert.min.js'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-bowercopy');
grunt.registerTask('default', ['bowercopy']);
grunt.registerTask('dog', ['watch']);
};
Can anyone tell me what's wrong? Or, is there any other way to do it with grunt (automatically :) )?
Thanks #cartant for comment, it was one of the mistakes I've made - using whatever instead of "files"
I've changed position of resource and target
Wrong:
'source':'target'
improved:
'target':'source'
Works!
I'm trying to get Grunt to process my less files every time I make a change to one of the files.
I have a 'watch' task working, and it says it is processing files when I make a change, and it outputs the correct files which change, so my watch is working, but the changes I make are not being made on the css file.
My file structure is like this
-styles
globals.less
components.less
-menu
menu.less
-header
header.less
The components.less file is a group of less mixins to grab the other .less files like #import "menu/menu.less";
In my grunt file, I have
less: {
development: {
options: {
paths: ['./app/vendor/modern-touch-less','./app/styles']
},
files: {
'./app/styles/modern-touch.css':'./app/vendor/modern-touch-less/style.less',
'./app/styles/components.css':'./app/styles/components.less'
}
}
},
watch: {
js: {
files: ['/scripts/{,*/}*.js','/styles/{,*/}*.less'],
tasks: ['newer:jshint:all, less'],
options: {
livereload: true
}
},
styles: {
files: ['./styles/{,*/}*.*','./vendor/{,*/}*.less'],
tasks: ['less','newer:copy:styles', 'autoprefixer'],
options: {
nospawn: true,
livereload: true
}
},
}
When I first start the app, the less files are built into the correct components.css file, but after changing a file, the components.css file is not updated.
Grunt is started with
grunt.task.run([
'clean:server',
'bower-install',
'concurrent:server',
'less',
'autoprefixer',
'connect:livereload',
'watch',
'karma'
]);
Perhaps you can try simplifying your configuration, by splitting tasks out to run on the appropriate set of files.
watch: {
js: {
files: ['/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
styles: {
files: ['./styles/{,*/}*.*','./vendor/{,*/}*.less'],
tasks: ['less','newer:copy:styles', 'autoprefixer'],
options: {
nospawn: true,
livereload: true
}
},
}
In your original watch config, the watch.js.tasks array was ['newer:jshint:all, less'], which looks like a typo, should be ['newer:jshint:all', 'less']. This may fix the problem too, but I would consider just running tasks on the files that they are affected by.
related
I was able to set up a Grunt task to SFTP files up to my dev server using grunt-ssh:
sftp: {
dev: {
files: {
'./': ['**','!{node_modules,artifacts,sql,logs}/**'],
},
options: {
path: '/path/to/project',
privateKey: grunt.file.read(process.env.HOME+'/.ssh/id_rsa'),
host: '111.111.111.111',
port: 22,
username: 'marksthebest',
}
}
},
But this uploads everything when I run it. There are thousands of files. I don't have time to wait for them to upload one-by-one every time I modify a file.
How can I set up a watch to upload only the files I've changed, as soon as I've changed them?
(For the curious, the server is a VM on the local network. It runs on a different OS and the setup is more similar to production than my local machine. Uploads should be lightning quick if I can get this working correctly)
What you need is grunt-newer, a task designed especially to update the configuration of any task depending on what file just changed, then run it. An example configuration could look like the following:
watch: {
all: {
files: ['**','!{node_modules,artifacts,sql,logs}/**'],
tasks: ['newer:sftp:dev']
}
}
You can do that using the watch event of grunt-contrib-watch.
You basically need to handle the watch event, modify the sftp files config to only include the changed files, and then let grunt run the sftp task.
Something like this:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
secret: grunt.file.readJSON('secret.json'),
watch: {
test: {
files: 'files/**/*',
tasks: 'sftp',
options: {
spawn: false
}
}
},
sftp: {
test: {
files: {
"./": "files/**/*"
},
options: {
path: '/path/on/the/server/',
srcBasePath: 'files/',
host: 'hostname.com',
username: '<%= secret.username %>',
password: '<%= secret.password %>',
showProgress: true
}
}
}
}); // end grunt.initConfig
// on watch events configure sftp.test.files to only run on changed file
grunt.event.on('watch', function(action, filepath) {
grunt.config('sftp.test.files', {"./": filepath});
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ssh');
};
Note the "spawn: false" option, and the way you need to set the config inside the event handler.
Note2: this code will upload one file at a time, there's a more robust method in the same link.
You can achieve that with Grunt:
grunt-contrib-watch
grunt-rsync
First things first: I am using a Docker Container. I also added a public SSH key into my Docker Container. So I am uploading into my "remote" container only the files that have changed in my local environment with this Grunt Task:
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
rsync: {
options: {
args: ['-avz', '--verbose', '--delete'],
exclude: ['.git*', 'cache', 'log'],
recursive: true
},
development: {
options: {
src: './',
dest: '/var/www/development',
host: 'root#www.localhost.com',
port: 2222
}
}
},
sshexec: {
development: {
command: 'chown -R www-data:www-data /var/www/development',
options: {
host: 'www.localhost.com',
username: 'root',
port: 2222,
privateKey: grunt.file.read("/Users/YOUR_USER/.ssh/id_containers_rsa")
}
}
},
watch: {
development: {
files: [
'node_modules',
'package.json',
'Gruntfile.js',
'.gitignore',
'.htaccess',
'README.md',
'config/*',
'modules/*',
'themes/*',
'!cache/*',
'!log/*'
],
tasks: ['rsync:development', 'sshexec:development']
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-rsync');
grunt.loadNpmTasks('grunt-ssh');
grunt.registerTask('default', ['watch:development']);
};
Good Luck and Happy Hacking!
I have recently ran into a similar issue where I wanted to only upload files that have changed. I'm only using grunt-exec. Providing you have ssh access to your server, you can do this task with much greater efficiency. I also created an rsync.json that is ignored by git, so collaborators can have their own rsync data.
The benefit is that if anyone makes a change it automatically uploads to their stage.
// Watch - runs tasks when any changes are detected.
watch: {
scripts: {
files: '**/*',
tasks: ['deploy'],
options: {
spawn: false
}
}
}
My deploy task is a registered task that compiles scripts then runs exec:deploy
// Showing exec:deploy task
// Using rsync with ssh keys instead of login/pass
exec: {
deploy: {
cmd: 'rsync public_html/* <%= rsync.options %> <%= rsync.user %>#<%= rsync.host %>:<%=rsync.path %>'
}
You see a lot of the <%= rsync %> stuff? I use that to grab info from rysnc.json which is ingored by git. I only have this because this is a team workflow.
// rsync.json
{
"options": "-rvp --progress -a --delete -e 'ssh -q'",
"user": "mmcfarland",
"host": "example.com",
"path": "~/stage/public_html"
}
Make sure you rsync.json is defined in grunt:
module.exports = function(grunt) {
var rsync = grunt.file.readJSON('path/to/rsync.json');
var pkg = grunt.file.readJSON('path/to/package.json');
grunt.initConfig({
pkg: pkg,
rsync: rsync,
I think it's not good idea to upload everything that changed at once to staging server. And working on the staging server is not a good idea too. You have to configure your local machine server, to be the same as staging/production
It's better to upload 1 time, when you do deployment.
You can archive all the files using grunt-contrib-compress. And push them using grunt-ssh as 1 file, then extract it on the server, that will be much faster.
that's example of compress task:
compress: {
main: {
options:{
archive:'build/build.tar.gz',
mode: 'tgz'
},
files: [
{cwd: 'build/', src: ['sites/all/modules/**'], dest:'./'},
{cwd: 'build/', src: ['sites/all/themes/**'], dest:'./'},
{cwd: 'build/', src: ['sites/default/files/**'], dest:'./'}
]
}
}
PS: Didn't ever look to rsync grunt modules.
I understand that it's might not what you are looking for. But i decided to create my answer as standalone answer.