launch node-inspector in the background
$ node-inspector &
run your mocha tests in debug mode
$ mocha --debug-brk /path/to/test.js
point Chrome to node-inspector
http://localhost:8080/debug?port=5858
This blog serves as a dumping ground for my own interests. On it you will find anything which I want to keep track of; links, articles, tips and tricks. Mostly it focuses on C++, Javascript and HTML, linux and performance.
Showing posts with label web. Show all posts
Showing posts with label web. Show all posts
Thursday, 29 May 2014
Wednesday, 28 May 2014
MongoDb quick reference
In the mongo shell
# show all databases
show dbs
# switch to a database
use <database>
# drop database
db.dropDatabase();
# show all databases
show dbs
# switch to a database
use <database>
# drop database
db.dropDatabase();
Tuesday, 13 May 2014
angular-fullstack yeoman generator - use less version of bootstrap
I use the angular-fullstack yeoman generator, but it installs the compiled bootstrap css and I want to use the less version.
Here is how I hack the yeomen generated source to change it to use the less version of bootstrap:
# install less and less grunt task:
sudo npm install -g less
# rename the old app/styles/main.css to app/styles/inputs.less:
mv app/styles/main.css app/styles/inputs.less
# create less grunt tasks in Gruntfile.js:
files: ['<%= yeoman.app %>/styles/{,*/}*.{css,less}'],
# add 'less:dev' to tasks in the styles section of the watch grunt task:
tasks: ['less:dev', 'newer:copy:styles', 'autoprefixer']
Here is how I hack the yeomen generated source to change it to use the less version of bootstrap:
# install less and less grunt task:
sudo npm install -g less
npm install --save-dev grunt-contrib-less
# create app/styles/main.less file:
@import "../bower_components/bootstrap/less/bootstrap.less";
@import "inputs.less";
@import "../bower_components/bootstrap/less/utilities.less";
# rename the old app/styles/main.css to app/styles/inputs.less:
mv app/styles/main.css app/styles/inputs.less
# create less grunt tasks in Gruntfile.js:
// build our css
less: {
dev: {
files: {
"<%= yeoman.app %>/styles/main.css": "<%= yeoman.app %>/styles/main.less"
}
},
dist: {
options: {
cleancss: true
},
files: {
"<%= yeoman.dist %>/styles/main.css": "<%= yeoman.app %>/styles/main.less"
}
}
},
# add 'less' file extension to files in the styles section of the watch grunt task:
# add 'less:dev' to tasks in the styles section of the watch grunt task:
# also, add 'less:dev' to the debug and serve grunt tasks, and 'less:dist' to the build grunt task
# add exclude entry to the bower-install grunt task to prevent it from being injected into index.html:
exclude: [ 'bower_components/bootstrap/dist/css/bootstrap.css' ]
exclude: [ 'bower_components/bootstrap/dist/css/bootstrap.css' ]
# add generated css to .gitignore:
echo app/styles/main.css >> .gitignore
echo app/styles/main.css >> .gitignore
Monday, 31 March 2014
MEAN stack build system
MEAN stack build system
The MEAN stack is [M]ongo, [E]xpress, [A]ngular, [N]ode.Back end:
The server is built using Express, which is built on top of Node.
The database used by the server is MongoDB.
Front end:
The client is built using Angular.
The less version of Bootstrap is used for CSS.
I use Yeoman and the angular-fullstack generator to generate my MEAN stack scaffold.
yo angular-fullstack [app]
Development tools: npm is used for the server dependencies; these are listed in
package.json Bower is used for the client dependencies; these are listed in
bower.json Grunt is used for the build system. The configuration is stored in
Gruntfile.jsThe file system structure is as follows:
site/
app/ # client source code
lib/ # server source code
test/ # tests
public/ # client production build destination
Gruntfile.js # Grunt configuration
package.json # server dependencies
bower.json # client dependencies
server.js # Express server entry-point
Grunt plugins:grunt-bower-install:
When new dependencies are added with
bower, grunt-bower-install will automatically inject their css and js into index.html.In the
grunt.initConfig block of Gruntfile.js:'bower-install': {
app: {
html: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
}
},
grunt-file-blocks: When new front end components added in the source tree, grunt-file-blocks will automatically inject the javascript into
index.html and the less into main.less.In the
grunt.initConfig block of Gruntfile.js:fileblocks: {
options: {
removeFiles: true,
templates: {
less: '@import \'${file}\';'
}
},
js: {
src: 'app/index.html',
blocks: {
components: { cwd: 'app', src: 'components/**/*.js' }
}
},
less: {
src: 'app/css/main.less',
blocks: {
components: { cwd: 'app', src: 'components/**/*.less' }
}
}
},
Development workflow:File are monitored for changes and the front or back end are reloaded as required.
nodemon and LiveReload are run concurrently:In the
grunt.initConfig block of Gruntfile.js:concurrent: {
dev: {
tasks: ['nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
}
},
Back end changes are monitored by nodemon. If a file required by the server is changed, node will be relaunched, restarting the server.In the
grunt.initConfig block of Gruntfile.js:nodemon: {
dev: {
options: {
file: 'server.js',
ignoredFiles: ['app', 'test', 'node_modules'],
watchedExtensions: ['js']
}
}
},
Front end changes are monitored by LiveReload. If a file required by the client is changed, assets will be rebuild (eg less converted to css) and the browser will be refreshedIn the
grunt.initConfig block of Gruntfile.js:watch: {
app: {
options: { livereload: true },
files: [
'app/index.*',
'app/css/*',
'app/components/**/*.js',
'app/images/*'
]
},
less: {
tasks: ['less'],
files: ['app/css/main.less', 'app/components/**/*.less']
}
},
less: {
build: {
files: { 'app/css/main.css': 'app/css/main.less' }
}
}
This article is inspired by Shawn Dahlen’s post on the build system 4dashes uses.
Tuesday, 28 January 2014
Angular configuration - default http headers
Help prevent CSRF attacks by setting the X-Requested-By / X-Posted-By header
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-By'] = 'myApp';
});
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.post['X-Posted-By'] = 'myApp';
});
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.put['X-Posted-By'] = 'myApp';
});
Change the default headers at runtime:
$http.defaults.common['X-Auth'] = "foobar";
Security.StackExchange discussion
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-By'] = 'myApp';
});
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.post['X-Posted-By'] = 'myApp';
});
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.headers.put['X-Posted-By'] = 'myApp';
});
$http.defaults.common['X-Auth'] = "foobar";
Security.StackExchange discussion
Monday, 27 January 2014
Angular directives - require
If we want to expose an API to other directives, we should require a controller on the directive.
We can bind a controller to the directive with require. Multiple controllers can be required by using an array of strings.
app.directive('foo', function() {
return {
require: 'bar',
}
});
Link function
When a controller is required, it will be passed as the 4th argument to the link function:
app.directive('foo', function() {
return {
require: 'bar',
link: function (scope, element, attrs, bar) {
}
}
});
When multiple controllers are required, they will be passed as an array to the link function:
app.directive('foo', function() {
return {
require: ['bar, baz'],
link: function (scope, element, attrs, controllers) {
var bar = controllers[0];
var baz = controllers[1];
}
}
});
Controller location
We can control where the controller can be found by prefixing the controller name as follows:
no prefix
The required controller must be specified on the directive itself. An exception is thrown if no controller is found.
?
Make the controller optional - if it is not found in the directive provided, null is passed as the 4th argument to
the link function.
ˆ
Walk up the parent chain until the controller is found
?ˆ
Combine the previous two options - walk up the parent chain until the controller is found, and pass null if none is found
We can bind a controller to the directive with require. Multiple controllers can be required by using an array of strings.
app.directive('foo', function() {
return {
require: 'bar',
}
});
Link function
When a controller is required, it will be passed as the 4th argument to the link function:
app.directive('foo', function() {
return {
require: 'bar',
link: function (scope, element, attrs, bar) {
}
}
});
When multiple controllers are required, they will be passed as an array to the link function:
app.directive('foo', function() {
return {
require: ['bar, baz'],
link: function (scope, element, attrs, controllers) {
var bar = controllers[0];
var baz = controllers[1];
}
}
});
Controller location
We can control where the controller can be found by prefixing the controller name as follows:
no prefix
The required controller must be specified on the directive itself. An exception is thrown if no controller is found.
?
Make the controller optional - if it is not found in the directive provided, null is passed as the 4th argument to
the link function.
ˆ
Walk up the parent chain until the controller is found
?ˆ
Combine the previous two options - walk up the parent chain until the controller is found, and pass null if none is found
Wednesday, 22 January 2014
Angular directives - isolate scope
If you don't want a directive to use its parent's scope, create isolate scope:
app.directive("widget", function() {
return {
scope : {}, // creates isolate scope
...
}
When using isolate scope, obtain access to the parent scope by binding some members:
app.directive("widget", function() {
return {
scope : {
foo: '@' // binds to parent's $scope.foo
},
...
}
app.directive("widget", function() {
return {
scope : {}, // creates isolate scope
...
}
When using isolate scope, obtain access to the parent scope by binding some members:
app.directive("widget", function() {
return {
scope : {
foo: '@' // binds to parent's $scope.foo
},
...
}
3 bindings to parent scope exist:
'@': 1-way, by value, as a string (updates in the directive are not propagated to the parent scope)
'=': 2-way, by reference (updates in the directive will update the parent scope)
'&': expression (the expression is executed in the context of the parent scope)
1-way binding:
app.directive("widget", function() {
return {
restrict: 'E', // can only be used as an element
},
link: function(scope, element, attrs) {
// do something with attrs.foo
}
}
<widget foo="blah"></widget>
return {
restrict: 'E', // can only be used as an element
scope: {
foo: '@' // imports $scope.foo by value},
link: function(scope, element, attrs) {
// do something with attrs.foo
}
}
<widget foo="blah"></widget>
In the directive's link function, attrs.foo === "blah".
Model expressions can be parsed too:
<widget foo="{{ model }}"></widget>
In the directive's link function, attrs.foo is a string containing the value in $scope.model.
2-way binding:
app.directive("widget", function() {
return {
restrict: 'E', // can only be used as an element
},
link: function(scope, element, attrs) {
// do something with attrs.foo
}
}
<widget foo="bar"></widget>
return {
restrict: 'E', // can only be used as an element
scope: {
foo: '=' // imports $scope.foo by reference},
link: function(scope, element, attrs) {
// do something with attrs.foo
}
}
<widget foo="bar"></widget>
In the directive's link function, attrs.foo === $scope.bar. Updating attrs.foo will result in $scope.bar being updated too.
expression binding:
app.directive("widget", function() {
return {
restrict: 'E', // can only be used as an element
},
link: function(scope, element, attrs) {
// attrs.foo() will execute the expression
}
}
<widget foo="bar()"></widget>
return {
restrict: 'E', // can only be used as an element
scope: {
foo: '&' // foo() executed as expression on $scope},
link: function(scope, element, attrs) {
// attrs.foo() will execute the expression
}
}
<widget foo="bar()"></widget>
In the directive's link function, attrs.foo() will execute $scope.bar()
pass parameters to expression:
Special syntax is required to pass parameters to the expression.
In the directive, foo({p1: val}) will pass val to expression foo, which is function bar(p1) on $scope
Sunday, 8 December 2013
Debugging node servers with node-inspector
Install node inspector
$ npm install -g node-inspector
Run node in debug mode
$ node --debug your/node/program.js
Send USR1 signal to node
$ pkill -USR1 node
Launch node-inspector in background mode
$ node-inspector &
Open up the debugger in your browser by navigating to http://localhost:8080/debug?port=5858
If you have something like livereload restarting your node server when you change a source file, then re-launching node-inspector can be done with something like this:
$ PID=`ps -ef | grep node-inspector | grep -v grep | awk '{print $2}'`; if [[ $PID -ne '' ]]; then echo "Killing node-inspector (pid $PID)"; kill $PID; wait $PID; fi; echo "Sending USR1 signal to node"; pkill -USR1 node; echo "Launching node-inspector"; node-inspector&
Node inspector GitHub page: https://github.com/node-inspector/node-inspector
$ npm install -g node-inspector
Run node in debug mode
$ node --debug your/node/program.js
Send USR1 signal to node
$ pkill -USR1 node
Launch node-inspector in background mode
$ node-inspector &
Open up the debugger in your browser by navigating to http://localhost:8080/debug?port=5858
If you have something like livereload restarting your node server when you change a source file, then re-launching node-inspector can be done with something like this:
$ PID=`ps -ef | grep node-inspector | grep -v grep | awk '{print $2}'`; if [[ $PID -ne '' ]]; then echo "Killing node-inspector (pid $PID)"; kill $PID; wait $PID; fi; echo "Sending USR1 signal to node"; pkill -USR1 node; echo "Launching node-inspector"; node-inspector&
Monday, 21 October 2013
Create angular app and express server / mongodb with yeoman
install (or update) yeoman
npm install -g yo
install (or update) yeoman angular fullstack generator (angular frontend / express server)
npm install -g generator-angular-fullstack
create angular app
yo angular-fullstack [name] // creates ng-app="nameApp", if blank uses curdir
npm install -g yo
npm update -g yo
npm install -g generator-angular-fullstack
npm update -g generator-angular-fullstack
yo angular-fullstack [name] // creates ng-app="nameApp", if blank uses curdir
I chose yes to add bootstrap, no for scss authoring, angular-resource (ngResource) and angular-route (ngRoute) and yes for mongoose/mongodb
add angular-bootstrap (angular directives for twitter bootstrap)
bower install angular-bootstrap --save
Github page for the angular-fullstack generator here:
bower install angular-bootstrap --save
run karma tests
grunt karma
get rid of the missing file warning by commenting out the following line from the files array:
'test/mock/**/*.js',
grab phantom.js for headless testing
http://phantomjs.org/download.html
configure karma to run Phantom.js instead of Chrome to
in karma.conf.js change browsers array to PhantomJS
run karma tests again to validate there are no warnings, and we're running through Phantom.js
grunt karma
serve angular app
grunt servergrunt karma
get rid of the missing file warning by commenting out the following line from the files array:
'test/mock/**/*.js',
grab phantom.js for headless testing
http://phantomjs.org/download.html
configure karma to run Phantom.js instead of Chrome to
in karma.conf.js change browsers array to PhantomJS
run karma tests again to validate there are no warnings, and we're running through Phantom.js
grunt karma
serve angular app
Github page for the angular-fullstack generator here:
Wednesday, 16 October 2013
MongoDb on Fedora 19
Install and start server
yum install mongodb-server
systemctl start mongod
systemctl enable mongod
systemctl status mongod
yum install mongodb-server
systemctl start mongod
Install client and verify it can connect to the server
yum install mongodb
mongo
You should now be in the mongo shell - test you can save and retrieve an object
db.test.save( { a: 1 } )
db.test.find()
Should display something like this:
{ "_id" : ObjectId("525f2fb01ec8e4af43c529c0"), "a" : 1 }
Thursday, 3 October 2013
hello world app with node.js and express.js
requires node and express to be installed (see here for instructions)
go to the root directory where your hello world app will be created
$ cd ~/src/web
create an express app called 'helloWorld' (and use the less css tool)
$ express helloWorld -c less
obtain the required dependencies and install
go to the root directory where your hello world app will be created
$ cd ~/src/web
create an express app called 'helloWorld' (and use the less css tool)
$ express helloWorld -c less
obtain the required dependencies and install
$ cd helloWorld
$ npm install
run the server
$ npm start # npm calls 'node app'
add nodemon to our devDependencies so the server gets restarted automatically during development
$ vim package.json
add the following
"devDependencies": {
"nodemon": "*"
}
change the scripts / start value:
"start": "nodemon app.js"
download dependency nodemon
$ npm install
start the server via nodemon
$ npm start
Wednesday, 2 October 2013
node.js / express.js / yeoman / angular installation on Fedora 19
download the prebuilt binary:
http://nodejs.org/dist/v0.10.20/node-v0.10.20-linux-x64.tar.gz
download and build from source
cd /tmp
wget http://nodejs.org/dist/v0.10.20/node-v0.10.20.tar.gz
tar -xf node-v0.10.20-linux-x64.tar.gz
cd node-v0.10.20-linux-x64/
configure, build and install
export PREFIX=/usr/local # or whatever your prefix is
./configure --prefix=$PREFIX
export LINK=g++ # only required if you're building on NFS
make
make install
clean up temporary files
rm -rf /tmp/node-v0.10.20-linux-x64*
add node to your path
export PATH=$PREFIX/bin:$PATH
display node and npm versions
node --version
v0.10.20
npm --version
1.3.11
install express.js
npm install -g express
display express version
express --version
3.4.0
install yeoman
npm install -g yo
install yeoman angular generator
npm install -g generator-angular
create angular app
yo angular app-name
serve angular app
grunt server
http://nodejs.org/dist/v0.10.20/node-v0.10.20-linux-x64.tar.gz
download and build from source
cd /tmp
wget http://nodejs.org/dist/v0.10.20/node-v0.10.20.tar.gz
tar -xf node-v0.10.20-linux-x64.tar.gz
cd node-v0.10.20-linux-x64/
configure, build and install
export PREFIX=/usr/local # or whatever your prefix is
./configure --prefix=$PREFIX
export LINK=g++ # only required if you're building on NFS
make
make install
clean up temporary files
rm -rf /tmp/node-v0.10.20-linux-x64*
add node to your path
export PATH=$PREFIX/bin:$PATH
display node and npm versions
node --version
v0.10.20
npm --version
1.3.11
install express.js
npm install -g express
display express version
express --version
3.4.0
install yeoman
npm install -g yo
install yeoman angular generator
npm install -g generator-angular
create angular app
yo angular app-name
serve angular app
grunt server
Subscribe to:
Posts (Atom)