What is a Makefile? And how is it different from a Gruntfile or npm run? - makefile

Recently, while getting acquainted with the Mocha javascript testing framework, I came across this section that I didn't understand:
Makefiles
Be kind and don't make developers hunt around in your docs to figure
out how to run the tests, add a make test target to your Makefile:
test:
./node_modules/.bin/mocha --reporter list
.PHONY: test
Which is hardly descriptive, and not very helpful if you don't know what a makefile is.
So, What is a Makefile? And how is it different from a Gruntfile or using npm run?

Makefile
A Makefile (usually with no file extension) is a configuration file used by the Unix make tool.
Quoted from one of the best introductions I have found on Make that I highly recommend you read if you are interested in knowing more about make specifically, and task-runners in general.
Make is the original UNIX build tool. It existed a long time before
gulp, or grunt. Loved by some, loathed by others it is at least worth
being aware of how make works, what the strengths are and where it
falls short.
Make is available on UNIX-like systems. That means OSX, BSD and Linux.
It exposes any system command meaning that you can run system commands
and execute arbitrary scripts. There is no doubt that tools like gulp
and grunt are inpsired by or at least a reaction to make.
To use make you create a Makefile and then run make [what to run] from
the terminal.
Gruntfile.js
A Gruntfile.js is a javascript configuration file used by the Grunt.js tool.
The newer node.js version of make, if you will, is Grunt.js which is cross-platform (works on Windows) and written in Javascript. Both can do similar things like concatenate files, minify css, run tests, etc. and there is a lot of information on the web about Grunt.
'npm run'
Another option that some developers prefer to use is npm itself, using the npm run command as described in this informative post on how to use npm run for running tasks:
There are some fancy tools [Grunt] for doing build automation on javascript
projects that I've never felt the appeal of because the lesser-known
npm run command has been perfectly adequate for everything I've needed
to do while maintaining a very tiny configuration footprint.
If you haven't seen it before, npm looks at a field called scripts in
the package.json of a project in order to make things like npm test
from the scripts.test field and npm start from the scripts.start field
work.
npm test and npm start are just shortcuts for npm run test and npm run
start and you can use npm run to run whichever entries in the scripts
field you want!
Other good introductory resources:
Introduction to grunt.js and npm scripts, and choosing between the
two.
Cross platform JavaScript.
Package Managers: An Introductory Guide For The Uninitiated Front-End
Developer.

Related

How to use jest in clojurescript?

After I installing jest using npm install jest and adding "test":"jest" in package.json, I expect keywords like "expect" to work automatically in my cljs test files:
(.toBeInTheDocument (expect (.getByText screen "Some Component")))
But I get that "expect" is undefined. js/expect gives undefined as well. How to get jest to work with clojurescript?
-- EDIT --
I installed lint a this library, but still can't get jest functions to work in my test file.
This is not what you asked, but I think most ClojureScript projects use tests written with clojure.test and mocking facilities of the language (eg. with-redefs), so I think it will be much easier to follow that path instead.
Check these links depending on the build tool that you use for your project:
figwheel: https://figwheel.org/docs/testing.html
shadow-cljs: https://shadow-cljs.github.io/docs/UsersGuide.html#_testing

why compiler is used for sass files while they can be run through terminal

Can anyone please help explain this? I am new at using Sass. But I cant understand why people use compiler for sass files when they can be run through terminal.
I actually had the same question some time ago when I was learning SASS.
I kept wondering why most tutorials involved using GRUNT / GULP or some kind of task runner when there where sass proprietary commands even for live-watching your files with a command such as:
sass --watch app/sass:public/stylesheets
I will quote myself here in the question (that no one answered) just to share my experience with SASS compiling:
Grunt: using grunt-contrib-sass - Everything has worked smoothly; I chose this one over grunt-sass for no particular reason, but I've read that the latter uses libsass(c++) which is faster than the traditional ruby Sass.
Gulp: using gulp:sass - I often encounter an error when watching
files, it doesn´t find some partials, but if you save again,
everything is fine (this is addressed in their common issues -this
solution hasn't worked for me though), also it doesn't generate sass
maps as a default you have to use gulp-sourcemaps on top.
Straight from Console: no task runners - Works fine so far, generates
sourcemaps, and lets you know where there's an error, just like with
Grunt and Gulp.
So after working on different projects using SASS I'd say the reasons are:
Tutorials popularized the use of task runners when using SASS in its early times
In a project, you rarely use SASS just by itself, you most likely want to run other tasks, so it makes sense to add your SASS task to the flow, which saves time and makes sense.
It's easier to run a simple command such as gulp sass or just gulp to run the default gulp task (that should include the sass task) than to remember a long command in which you have to put the paths over and over again.
After a while I realized that you can use NPM scripts in your package.json to run the SASS command line tools like so:
"scripts": {
"sass": "sass --watch app/sass:public/stylesheets --style compressed"
},
And then run it from the command line: npm run sass
the above requires no configuration and you don't have to remember the whole command by heart.
To conclude, there is nothing wrong in using the CMD SASS without other compilers/task runners, just use whatever you feel most comfortable with.

Merits of using npm over shell program(Bash)

I have recently started using npm (https://www.npmjs.com) and it's wonderful that we can use npm as build tool. But after digging much, I got question in my mind.
As a building tool, npm is almost like shell program(sh or bash), because we just execute shell commands in npm package.json file. And even sometimes we execute shell program from it.
EDIT: here is an example how I use it.
package.json
{
"name": "myproject",
"devDependencies": {
"jshint": "latest",
"minify": "latest",
"mocha": "latest"
},
"scripts": {
"lint": "jshint **.js",
"test": "mocha test/",
"minify":"minify *.js",
"build":"npm run lint && npm run test && npm run minify"
}
}
So, everything we're doing with npm bundling facility, we can achieve by writing normal shell program(sh or bash). I want to know what are special advantages of npm over nprmal shell program. What we can't do with shell script, which we can achieve with npm as build tool.
There must be some special vision behind developing tool. Otherwise everything we can do with shell program (Makefile).
Your answer will be appreciated.
Thanking in advance!
Npm as a build tool: do you mean the npm scripts feature? Or something like Grunt or Gulp?
Npm itself is just a package ecosystem for JavaScript (Node) packages. Shell is, well, shell. You can create shell programs with anything which can be run using a shell (Bash, C, Python, PHP, and so on). I presume you mean shell languages like sh or bash in your question.
If you develop Node or browser applications, or use a tool such as Gulp, Grunt, Fly, npm scripts and so on then npm is a good (mandatory) pick.
If you need to create build procedures for something really custom or lower level than regular applications, then custom shell builders or maybe Makefiles could be a better fit. Though some people seem to use Makefiles in places where npm and a build tool like Gulp would be a simpler choice.
What are you building with npm right now which got you questioning the usage of it?

Karma and Jasmine installation without npm

I want to use Karma and Jasmine to test my AngularJS application. All of the documentation I've found to install Karma and Jasmine involve using npm. I can't use npm because I am restricted, the reason doesn't matter. So far I have pulled Jasmine and Karma from Github using zip files. I want to add Karma and Jasmine to my project, but I don't think unzipping the entire contents of the respective GitHub repos is the way to go.
I'd like to know what I need to make Karma and Jasmine usable within my AngularJS project without using npm.
I guess it is possible, but will take a huuuuuge amount of work because of the dependencies. If you take a look at karma's repository, you can find a file package.json (here). In this file there is a property dependencies (link), which lists the modules karma depends on. So you'll have to find their sources, manually download all of them with respective version number and put in the folder called node_modules created in the karma module folder. But each of these modules karma depends on also has dependencies listed in their own package.json - you'll have to download them too keeping in mind version numbers and putting them in module's node_modules folder. And this dependency nesting can be really really deep.
Some modules may have extra scripts to be executed after they have been installed (scripts), which are called by NPM by default on installation. Maybe there are some other things which I am not aware of. Generally speaking it was designed to be installed via NPM and it's rarely the case when someone has no access to use it.
I would advise to ask somebody who has access to NPM to do an install of required packages and share the result of installation with you. Everything will be installed in the node_modules folder of the directory you run NPM commands from, it would be easy to do.
Here you can download version I've created, it has karma v0.13.1, karma-jasmine v0.3.6 and karma-chrome-launcher v0.2.0. I hope it will work for you, because we might have different OS (mine is Ubuntu 14.04 x64), I'm not sure if NPM does something OS-specific while installation of any package.
You should place the content of the archive to your project directory, to execute tests from your project folder use a terminal command:
./node_modules/karma/bin/karma start
I would still advise to solve the problem of accessing the NPM if you want to closely work with modules it stores.

Configure node npm package.json so that "npm test" works on both unix and windows

I have developed a node.js npm module, developing under Windows. Today I wrote some Mocha tests. After many struggles, it seemed that for npm test to work, package.json had to look like this: (there may be other options???)
"scripts": { "test": "node node_modules/mocha/bin/mocha" }
instead of what's in all the Unix based books,
"scripts": { "test": "./node_modules/.bin/mocha" }
How can I set package.json up to work on both Windows and Unix? I'm assuming that Travis-CI runs Unix, so, should I link the build to that, it will blow up with the Windows version.
I found a two year old thread where somebody requested a feature for exactly this. That thread seemed to die out. This SO question seems to be close, but it isn't exactly what I want and, frankly, I can't understand the answer. :-( Can anybody clarify?
For the time being, I am going
"scripts": {
"test": "node node_modules/mocha/bin/mocha",
"testOnUnixUseThis" : "./node_modules/.bin/mocha (I think)",
"testOnWindowsUseThis" : "node node_modules/mocha/bin/mocha"
},
Unfortunately, you cant go npm test testOnWindowsUseThis or npm testOnWindowsUseThis. And it doesn't fix the Travis-CI issue. But at least a person who downloads the module can (hopefully) see what is going on.
Any better ideas? Am I the only person still developing under Windows??? :-)
I've always been able to npm install -g mocha or npm install mocha and then just add
"scripts": {
"test": "mocha spec"
}
to package.json. That may or may not work in EVERY environment. I know, for instance, with lineman, you have to use bin/mocha. Also, if you don't find a way around this, set your test script up for Unix and then add a second script called "wintest" or something that does whatever you need it to do in Windows. You can name your scripts whatever you want. The default ones (test, start, etc.) can be used with npm [command]; any non-standard ones (like wintest) can be used with npm run-script [command], and they will still work.
A little back story on how/why this works:
When you install a module globally, it's available on PATH (or whatever the windows equivalent is). When you install a project dependency, if that module has any binaries, those are symlinked to node_modules/.bin and when you run npm run [some-command], npm helpfully adds node_modules/.bin to PATH for that command. So when mocha is installed globally "test": "mocha spec" uses your globally installed mocha to run tests. When it's a project dependency, it uses the one in node_modules/.bin. The one gotcha I've found with this is that npm adds node_modules/.bin to the front of PATH, so local binaries will always take precedence over global ones. Almost all of the time, this is what you want, but it's worth knowing that that's how it works (I recently had a bug related to this).
EDIT:
Not sure at what point in npm history this changed, but npm run <script-name> now works (don't need to do npm run-script <script-name> anymore). Possibly run-script still works as well. I'd expect it to, but I haven't tried it.
How can I set package.json up to work on both Windows and Unix?
If you
use Windows
dislike -g global install
...this is a working solution
"scripts": {
"test": "node node_modules/mocha/bin/mocha.js"
},
Notes:
putting node in front shouldn't harm, and can help on Windows (.js extension is not necessarily registered to the nodejus executable, unless you set it so. Could open a text editor, an IDE or (worse) windows scripting host, Internet Explorer…)
Adressing the script directly saves you from needing a global install. (Not judging if this is a good practice)
forward slashes help running under linux (obviously) and do work under windows (in this scenario. Also avoids a windows pitfall: backslashes if used, would need to be doubled – since they are interpreted as escaping the following letter if used solitary).
Don't use global solution, I suggest you follow what the Mocha guys say:
"scripts": {
"test": "node_modules/.bin/mocha -w"
},
Use npm i mocha --save-dev
This will save the module as a development dependency and npm will automatically set up the executables to be used within the scripts object. If you want to use the executables outside of the scripts defined in package.json, you can install it globally as well, although note that you may end up with different versions of the package.
If you only install it globally, other people won't be happy if they try to run your tests (with the standard npm test)
The new way with latest npm versions after 6.x, you needn't install mocha with global mode any more.
"scripts": { "test": "npx mocha" }
npx is installed automatically with new npm installation. It will search
mocha from node_modules/.bin or $PATH
reference: https://www.npmjs.com/package/npx

Resources