I wrote simple task in Grunt. Now, I would like to export this task to another file, and I have a problem with it.
How can I find file with my task? This task just searches string from website and putting it in the file. I'm trying load it by: grunt.loadTasks('grunt-find');
I have file (grunt-find) with find.js inside. But it doesn’t work... Can I have to add find.js somewhere else?
Thanks in advance.
grunt.loadTask() will load every JS file in the directory provided as argument; so, basically, you have to do something like:
grunt.loadTasks("tasks");
and you may have a directory called "tasks":
project root
|- tasks
|--- file.js
|- Gruntfile.js
If you find the "directory only" behavior of grunt.loadTask() annoying (i.e. want to keep external tasks definitions next to external task configuration), you can try something like that :
module.exports = function(grunt) {
var env = process.env.NODE_ENV || 'dev';
var _ = require('lodash');
/*** External config & tasks filepaths ***/
//we have 1 base config, and possibly many module-specific config
var configLocations = ['./grunt-config/default_config.js', './grunt-config/**/config.js'];
//we have 1 base tasks definition, and possibly many module-specific config
var tasksLocations = ['./grunt-config/default_tasks.js', './grunt-config/**/tasks.js'];
/* Typical project layout (matching with the globbing pattern above - adapt to your project structure) :
├── Gruntfile.js
├── package.json
├── grunt-config
│ ├── homepage
│ │ └── config.js
│ ├── navigation
│ │ └── config.js
│ ├── module1
│ │ ├── config.js
│ │ └── tasks.js
│ ├── default_config.js
│ ├── default_tasks.js
│ └── template_module_grunt.txt
├── website_directory1
│ ├── mdp
│ ├── multimedia-storage
│ ├── mv-commit.sh
│ ├── query
│ ├── temp
│ └── tmp
└── website_directory2
├── crossdomain.xml
├── css
├── favicon.ico
├── fonts
:
:
:
*/
/***************** External configuration management ***********************************/
var configFiles = grunt.file.expand({
filter: "isFile"
}, configLocations );
grunt.log.writeln('Gathering external configuration files'.underline.green);
grunt.log.writeln("configFiles : " + grunt.log.wordlist(configFiles, {
separator: ', ',
color: 'cyan'
}));
var configArray = configFiles.map(function(file) {
grunt.log.writeln("=> importing : " + file);
return require(file)(grunt, env);
});
var config = {};
configArray.forEach(function(element) {
config = _.merge(config, element);
});
grunt.initConfig(config);
/***************** Task loading & registering *******************************************/
// We load grunt tasks listed in package.json file
require('load-grunt-tasks')(grunt);
/****** External tasks registering ****************/
grunt.log.writeln('Gathering external task files'.underline.green);
var taskFiles = grunt.file.expand({
filter: "isFile"
}, tasksLocations);
grunt.log.writeln("task files : " + grunt.log.wordlist(taskFiles, {
separator: ', ',
color: 'cyan'
}));
taskFiles.forEach(function(path) {
grunt.log.writeln("=> loading & registering : " + path);
require(path)(grunt);
});
grunt.registerTask('default', ['jshint:gruntfile', 'logConfig']);
grunt.registerTask('checkGruntFile', 'Default task - check the gruntfile', function() {
grunt.log.subhead('* Tâche par défaut - aide et vérification du gruntfile *');
grunt.log.writeln('Exécutez "grunt -h" pour avoir plus d\'informations sur les tâches disponibles');
grunt.log.writeln('...');
grunt.log.subhead('Vérification du gruntfile...');
grunt.task.run(['jshint:gruntfile']);
});
//write the generated configuration (for debug)
grunt.registerTask('logConfig', 'Write the generated conf', function() {
//grunt.task.run(['attention:gruntfile']);
grunt.log.subhead('* Configuration générée : *');
grunt.log.writeln(JSON.stringify(config, undefined, 2));
});
};
Source : https://gist.github.com/0gust1/7683132
Related
If I have the following folder structure...
├── README.md
│
├── project.RProj
│
├── data
│ ├── some_data.csv
│
│
├── notebooks
│ ├── analysis.Rmd
│
├── output
How do I change the yaml in my RMarkdown file to output the HTML file to the output folder instead of in the notebook folder when using the knit button?
I would like to be able to click knit in RMarkdown and end up with...
├── README.md
│
├── project.RProj
│
├── data
│ ├── some_data.csv
│
│
├── notebooks
│ ├── analysis.Rmd
│
├── output
│ ├── analysis.html
I have seen that Yihui has a good example of how to edit outputs to add the date in the R Markdown cookbook (https://bookdown.org/yihui/rmarkdown-cookbook/custom-knit.html). Pasted below. But I would like to have an example for this specific use case.
knit: (function(input, ...) {
rmarkdown::render(
input,
output_file = paste0(
xfun::sans_ext(input), '-', Sys.Date(), '.html'
),
envir = globalenv()
)
})
You can specify the output_dir argument, in your case a basic YAML header looks like this:
---
title: "Test"
output: html_document
knit: (function(input, ...) {
rmarkdown::render(
input,
output_dir = "../output"
)
})
---
Here is how you can specify both: the output directory, and add the current date to the name of your output file within YAML heading:
---
title: "test"
author: "myName"
date: "`r Sys.Date()`"
output: html_document
knit: (function(input, ...) {
rmarkdown::render(
input,
output_dir = "../outReports",
output_file =file.path("../outReports",glue::glue('test_{Sys.Date()}'
)))
})
---
This is similar to this question, but I believe we are encountering different issues.
Setup:
I have a Kotlin class that interfaces with a TinyMCE instance running in a JavaFX Webview. I am setting up upcalls from Javascript to JavaFX as shown below, in the TinyMCEInterface class:
inner class BridgeObject {
fun setEditorAndSelection(ed : JSObject?) {
editorObj = ed
selectionObj = editorObj?.getMember("selection") as JSObject?
}
fun setInterfaceContent(newContent : String) {
contentProp.value = newContent
}
}
// after WebEngine loads successfully
val bridgeObj : BridgeObject = BridgeObject()
(webEngine.executeScript("window") as JSObject).setMember("bridgeObj", bridgeObj)
I am then calling these methods from Javascript, in TinyMCE setup:
ed.on('init', function() {
ed.setContent(initContent)
window.bridgeObj.setEditorAndSelection(ed)
window.bridgeObj.setInterfaceContent(ed.getContent())
});
ed.on('Change SelectionChange', function(e) {
window.bridgeObj.setInterfaceContent(ed.getContent())
});
Problem:
This works perfectly fine when the TinyMCEInterface class file lies in the root directory of my application (in package com.myself.app). That is, when the file structure looks like this:
com.myself.app/
│
├─ TinyMCEInterface.kt
│
├─ Main.kt
But breaks when I move TinyMCEInterface into a package (in package com.myself.app.somepackage):
com.myself.app/
│
├─ somepackage/
│ ├─ TinyMCEInterface.kt
│
├─ Main.kt
When I say "breaks", there are no errors; the calls to member functions of window.bridgeObj simply do not happen and quietly fail. I am completely bewildered as to how this can be happening.
Thanks in advance for any advice!
I created a new ASP.NET Empty Web Application in Visual Studios 2013. I have an angular project with the following directory structure:
├───TestProject
│ ├───index.html
│ ├───package.json
│ ├───Web.config
│ ├───app
│ │ ├───app.module.js
│ │ ├───main.js
│ ├───bin
│ ├───node_modules
│ │ ├───google-distance
│ │ │ └───test
│ │ ├───json-stringify-safe
│ │ │ └───test
│ │ ├───qs
│ │ ├───request
│ │ │ └───lib
│ ├───obj
│ │ └───Debug
│ │ └───TempPE
│ ├───Properties
│ └───Scripts
└───packages
├───angularjs.1.6.1
│ └───content
│ └───Scripts
│ └───i18n
│ └───ngLocale
├───AngularJS.Core.1.6.1
│ └───content
│ └───Scripts
└───RequireJS.2.3.2
└───content
└───Scripts
Here's what my packages.json looks like:
{
"name": "google-distance",
"version": "1.0.1",
"main": "index",
"description": "A simple node.js wrapper for Google's Distance Matrix API",
"author": {
"name": "Edward Look",
"email": "edwlook#gmail.com",
"url": "http://edwardlook.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/edwlook/node-google-distance.git"
},
"keywords": [
"google",
"maps",
"distance",
"matrix",
"api"
],
"dependencies": {
"google-distance": "~1.0.1"
}
}
I ran npm install and it created the node_modules folder. At the top of my main.js file I have:
var distance = require('../node_modules/google-distance/index.js');
But every time I load the page the console says:
require.js:168 Uncaught Error: Module name "../node_modules/google-distance/index.js" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
at makeError (require.js:168)
at Object.localRequire [as require] (require.js:1433)
at requirejs (require.js:1794)
at main.js:2
What am I doing wrong? How do I use the google-distance module?
Normally you should require it as follows;
var distance = require('google-distance');
The way node will look for modules is as follows;
It will perform a hierarchical directory search for "node_modules" and "google-distance" in the following ways:
./node_modules/google-distance.js
./node_modules/google-distance/index.js
./node_modules/google-distance/package.json
Also, it looks like you should use the asynchronous callback version of require to load this library.
require(['google-distance'], function (distance) {
//package is now loaded.
});
From the require FAQ:
MODULE NAME ... HAS NOT BEEN LOADED YET FOR CONTEXT: ... This occurs
when there is a require('name') call, but the 'name' module has not
been loaded yet. If the error message includes Use require([]), then
it was a top-level require call (not a require call inside a define()
call) that should be using the async, callback version of require to
load the code.
http://requirejs.org/docs/errors.html#notloaded
I have a subdir and in there, there are many more folders and files. So what I want is to copy the subdir with all the folders and files.
This is what it looks like now:
.
├── Gruntfile.js
└── src
├── a
└── subdir
└── b
└──subdir2
└── c
└──subdir3
└── d
└──subdir4
└── e
This is how I want it to look after using Grunt:
.
├── Gruntfile.js
└── src
├── a
└── subdir
└── b
└──subdir2
└── c
└──subdir3
└── d
└──subdir4
└── e
└── dist
└── subdir
└── b
└──subdir2
└── c
└──subdir3
└── d
└──subdir4
└── e
This is what I've tried so far, but it just isn't working. It copies everything also src folder and file a:
copy: {
expand: true,
src: 'src/subdir/*',
dest: 'dist/'
}
Use:
{
expand: true,
cwd: 'src/',
src: 'subdir/**',
dest: 'dist/'
},
The cwd option is here for that
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...