What is the best way for recursively directory removing with Meteor ?
Use an existing npm module like rimraf. Here's how you do it starting from an empty project:
$ meteor add meteorhacks:npm meteorhacks:async
$ meteor
Once meteor starts, stop it and edit packages.json to look like:
{
"rimraf": "2.2.8"
}
Then add something like this in a file under your server directory:
var removeDirectory = Async.wrap(Meteor.npmRequire('rimraf'));
Meteor.startup(function() {
removeDirectory('/dir/to/remove');
});
Where /dir/to/remove is, you guessed it, the directory you want to recursively remove.
Here's how I do it (in CoffeeScript):
fs = requre('fs')
_emptyDirectory = (target) ->
_rm(path.join(target, p)) for p in fs.readdirSync(target)
_rm = (target) ->
if fs.statSync(target).isDirectory()
_emptyDirectory(target)
fs.rmdirSync(target)
else
fs.unlinkSync(target)
Related
Is it possible to connect to an existing Electron application using Spectron? I am not particularly sure on how to go about implementing this..
I'd like to be able to do something like:
import { Application } from 'spectron';
import electronPath from 'electron';
import path from 'path';
// but don't spawn new electron application
new Application({
path: electronPath,
args: [path.join(__dirname, '..', '..', 'app')],
});
There are some documentation out there for using debuggerAddress option in Spectron, but I'm not really sure on whether that is what I am looking for, since the arguments for debuggerAddress is url, like so: '127.0.0.1:1234'.
I struggled making this work for Electron 6, was able to in the end, here is a working repo (made changes on top of an older one)
https://github.com/florin05/electron-spectron-example
Please make sure that you have created Test Folder in the same directory and create spectron file in this file.
Json File Changes:
"scripts": {"test": "mocha"}
const app = new Application({path: electronPath,args:[path.join(__dirname,'..')],})
beforeEach(function () {return app.start()})
afterEach(function () {if (app && app.isRunning()) {return app.stop()}})
I'm toying around with ASP.NET 5 and am using gulp. I added angularjs and angular-route to my package.json file which stored the files at Dependencies->NPM. I added this to my gulpfile.js thinking that it would copy over the the correct JS files. It did copy over the files, however, it also crashed the project. I had to manually go into the lib folder and remove everything that gulp added. What's the proper way to copy files from the NPM folder a destination folder. I'd like to be able to just run the task from Task Runner.
I'm assuming this is incorrect: (which is what I ran)
gulp.task("copyJs", function () {
return gulp.src('./node_modules/**/*.js')
.pipe(gulp.dest('./wwwroot/lib/'))
});
*I think the trailing '/' in gulp.dest('./wwwroot/lib/') might be the cause of the problem, try gulp.dest('./wwwroot/lib') instead.
This is the gulp workflow I use for Angular 2 with Asp.Net 5.
var gulp = require("gulp"),
merge = require("merge-stream"),
rimraf = require("rimraf");
var paths = {
webroot: "./wwwroot/",
node_modules: "./node_modules/"
};
paths.libDest = paths.webroot + "lib/";
gulp.task("clean:libs", function (cb) {
rimraf(paths.libDest, cb);
});
gulp.task("copy:libs", ["clean:libs"], function () {
var angular2 = gulp.src(paths.node_modules + "angular2/bundles/**/*.js")
.pipe(gulp.dest(paths.libDest + "angular2"));
var es6_shim = gulp.src([
paths.node_modules + "es6-shim/*.js",
"!**/Gruntfile.js"])
.pipe(gulp.dest(paths.libDest + "es6-shim"));
var systemjs = gulp.src(paths.node_modules + "systemjs/dist/*.js")
.pipe(gulp.dest(paths.libDest + "systemjs"));
var rxjs = gulp.src(paths.node_modules + "rxjs/bundles/**/*.js")
.pipe(gulp.dest(paths.libDest + "rxjs"));
return merge(angular2, es6_shim, systemjs, rxjs);
});
There are many ways to do it but one of the good simple ways I found was this: http://www.hanselman.com/blog/ControlHowYourBowerPackagesAreInstalledWithAGulpfileInASPNET5.aspx
Which do an update to the bowerrc file and everything after this update makes more sense.
UPDATE YOUR .BOWERRC AND PROJECT.JSON
In the root of your project is a .bowerrc file. It looks like this:
> { "directory": "wwwroot/lib" } Change it to something like this, and
> delete your actual wwwroot/lib folder.
>
> { "directory": "bower_components" } EXCLUDE YOUR SOURCE BOWER FOLDER
> FROM YOUR PROJECT.JSON
You'll also want to go into your project.json file for ASP.NET 5 and
make sure that your source bower_components folder is excluded from
the project and any packing and publishing process.
> "exclude": [
> "wwwroot",
> "node_modules",
> "bower_components" ],
UPDATE YOUR GULPFILE.JS
In your gulpfile, make sure that path is present in paths. There are
totally other ways to do this, including having gulp install bower and
figure out the path. It's up to you how sophisticated you want your
gulpfile to get as long as the result is that production ready .js
ends up in your wwwroot ready to be served to the customer. Also
include a lib or destination for where your resulting JavaScript gets
copied. Could be scripts, could be js, could be lib as in my case.
var paths = {
webroot: "./" + project.webroot + "/",
bower: "./bower_components/",
lib: "./" + project.webroot + "/lib/" }; ADD A COPY TASK TO YOUR GULPFILE
Now open your Gulpfile and note all the tasks. You're going to add a
copy task to copy in just the files you want for deployment with your
web app.
Here is an example copy task:
> gulp.task("copy", ["clean"], function () {
> var bower = {
> "bootstrap": "bootstrap/dist/**/*.{js,map,css,ttf,svg,woff,eot}",
> "bootstrap-touch-carousel": "bootstrap-touch-carousel/dist/**/*.{js,css}",
> "hammer.js": "hammer.js/hammer*.{js,map}",
> "jquery": "jquery/jquery*.{js,map}",
> "jquery-validation": "jquery-validation/jquery.validate.js",
> "jquery-validation-unobtrusive": "jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"
> }
>
> for (var destinationDir in bower) {
> gulp.src(paths.bower + bower[destinationDir])
> .pipe(gulp.dest(paths.lib + destinationDir));
> } });
Do note this is a very simple and very explicit copy tasks. Others
might just copy more or less, or even use a globbing wildcard.
It's up to you. The point is, if you don't like a behavior in ASP.NET
5 or in the general build flow of your web application you have more
power than ever before.
Right click the Bower node in the Solution Explorer and "Restore
Packages." You can also do this in the command line or just let it
happen at build time.
Looking in this simplified screenshot, you can see the bower
dependencies that come down into the ~/bower_components folder. Just
the parts I want are moved into the ~/wwwroot/lib/** folder when the
gulpfile runs the copy task.
I manage very complex monorepos, I don't like hardcoded file paths and prefer to mirror my source code for transparency. I explored a LOT of solutions for doing a lot of files at once and find them all opaque and bloated. I recommend a factory that ultimately does this with source-like file module references:
gulp.parallel(
() =>
gulp
.src(require.resolve('#bootstrap/core/dist/bootstrap.all.min.js'))
.pipe(gulp.dest(DIST)),
() =>
gulp
.src(require.resolve('foobar/dist/foobar.all.min.js'))
.pipe(gulp.dest(DIST))
You can make them named functions for visibility as well.
My project uses Bower to install deps and Grunt to build. My project tree looks like this
|
|-bower_components
| |
| |-jquery
| |-semantic
| |-...
|-Bower.json
|-Gruntfile.js
|-public
| |
| |-css // Compiled, concatenated and minified semantic-ui
| |-js // and other libs should be here
|-...
|-etc..
Is it possible to build custom semantic-ui (ie customize fonts, colors, remove unused components) using Grunt (or maybe using Gulp called from Grunt)?
Where to place semantic theme config and overrides files?
It's not difficulty to use grunt to build semantic-ui. I don't know about bower, but this is how I did it.
Install grunt-contrib-less.
Create a new directory somewhere in your project, e.g. '/less/semantic'. Copy 'site' directory from your semantic packagea, i.e. 'bower_components/semantic/src/site' to the new directory. All your overrides will be done here.
Create a config.json file in '/less/semantic' to configure what components you want to be included in your build. The file content will be something like this:
{
"elements": ["button", "divider"],
"collections": ["form"],
"modules": ["checkbox"]
}
Add following to your gruntFile.js file:
var fs = require('fs');
// Defines files property for less task
var getSemanticFiles = function() {
var files = {};
var config = JSON.parse(fs.readFileSync('less/semantic/config.json'));
var srcDir = 'bower_components/semantic/definitions/';
var outputDir = 'less/semantic/output/';
for (var type in config) {
config[type].forEach(function(ele) {
files[outputDir + type + '.' + ele + '.output'] = [srcDir + type + '/' + ele + '.less'];
});
}
return files;
};
Configure less task as following:
less: {
semantic: {
options: { compile: true }
files: getSemanticFiels()
},
dist: {
options: { compile: true }
files: { 'public/css/semantic.css': ['less/semantic/output/*'] }
}
}
Edit theme.config in 'bower_components/semantic/src', change #siteFoler to '../../../less/site/', and make any additional changes as needed per semantic document.
You run grunt less:semantic to compile all needed components, and then run less:dist to put them into a single css file.
Of course you can configure a watch task to automate the process. Then every time you make a change, the css will be automaticly re-built.
I am sure someone will build a grunt build to semantic one day, but for now, I just use this to call all the gulp commands using grunt. https://github.com/sindresorhus/grunt-shell. Just make sure you are calling the gulp build task and not the default gulp task. It has a watch task that will cause grunt to not finish the shell task.
I'm currently struggling with using Phantom.js with a Meteor app of mine. I have it installed on my local machine (Ubuntu 14.04), it's added to my path (I can run it from my terminal), I also ran and installed the smart wrapper for Phantomjs: mrt add phantomjs.
I can see that in my .meteor > local > build > programs > server > npm directory there is a phantomjs directory.
My question is, how do I actually use Phantom? I'm attempting to scrape from the server side of things. I've tried the following things (using coffeescript):
phantom = Npm.require "phantomjs"
phantom = Npm.require "phantom"
phantom = Meteor.require "phantomjs"
phantom = Meteor.require "phantom"
(I've also tried using capital "P's")
All attempts in this way yield: Error: Cannot find module 'phantomjs'
Any clarification would be greatly appreciated!
[EDIT] now meteor is supporting npm packages out of the box: https://guide.meteor.com/using-npm-packages.html#installing-npm
Here is the procedure for Meteor > 1.0.0
Add the npm package
meteor add meteorhacks:npm
Run meteor to let the npm package to pre-initialise
meteor
A file packages.json has been created at the root. Edit it to:
{
"phantomjs": "1.9.13"
}
To use phantom into your server side code:
var phantomJS = Meteor.npmRequire("phantomjs");
Bonus: an example of usage (thanks Ben Green), put anywhere in your code:
if (Meteor.isServer) {
Meteor.startup(function () {
var phantomjs = Meteor.npmRequire('phantomjs');
var spawn = Meteor.npmRequire('child_process').spawn;
Meteor.methods({
runTest: function (options) {
command = spawn(phantomjs.path, ['assets/app/phantomDriver.js']);
command.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
command.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
command.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
}
});
Meteor.call("runTest");// run the test as soon as meteor server starts
});
}
Create the phantomjs script file ./private/phantomDriver.js and edit it to
var page = require('webpage').create();
page.open('http://github.com/', function (){
console.log('Page Loaded');
page.render('github.png');
phantom.exit();
});
The phantomjs wrapper in atmosphere doesn't look like it produces anything that works.
But you can easily add npm packages useing the npm meteorite package
First add the npm package to your project
mrt add npm
Then add the required phantomjs version to the packages.json file
{
"phantomjs": "1.9.7-6"
}
Then use the following code to require the phantomjs npm module:
var phantomjs = Meteor.require('phantomjs');
I would like to add an entire folder of files to my package. Instead of adding each file individually, is it possible to add an entire folder of files using api.add_files in the package.js file? Perhaps something like:
Package.on_use(function(api) {
api.add_files(["files/*","client");
});
I don't think there's something like that currently in the public API.
However, you can use plain old Node.JS to achieve what you want to do.
Our package structure looks like this :
/packages/my-package
|-> client
| |-> nested
| | |-> file3.js
| |-> file1.js
| |-> file2.js
|-> my-package.js
|-> package.js
We build a helper function as follow :
function getFilesFromFolder(packageName,folder){
// local imports
var _=Npm.require("underscore");
var fs=Npm.require("fs");
var path=Npm.require("path");
// helper function, walks recursively inside nested folders and return absolute filenames
function walk(folder){
var filenames=[];
// get relative filenames from folder
var folderContent=fs.readdirSync(folder);
// iterate over the folder content to handle nested folders
_.each(folderContent,function(filename){
// build absolute filename
var absoluteFilename=folder+path.sep+filename;
// get file stats
var stat=fs.statSync(absoluteFilename);
if(stat.isDirectory()){
// directory case => add filenames fetched from recursive call
filenames=filenames.concat(walk(absoluteFilename));
}
else{
// file case => simply add it
filenames.push(absoluteFilename);
}
});
return filenames;
}
// save current working directory (something like "/home/user/projects/my-project")
var cwd=process.cwd();
// chdir to our package directory
process.chdir("packages"+path.sep+packageName);
// launch initial walk
var result=walk(folder);
// restore previous cwd
process.chdir(cwd);
return result;
}
And you can use it like this :
Package.on_use(function(api){
var clientFiles=getFilesFromFolder("my-package","client");
// should print ["client/file1.js","client/file2.js","client/nested/file3.js"]
console.log(clientFiles);
api.add_files(clientFiles,"client");
});
We simply use Node.JS fs utils to work with the file system.