Why does mocha need to be in devDependencies? - javascript

On the face of it, mocha being in devDependencies like the tutorials say, is logical enough, it is after all a dev dependency.
But in practice you install it -g so you can run mocha as a command. And as far as I can tell, given that, it makes no difference at all whether it's mentioned in your package.json.
So is there any need to explicitly list it?

If you're working on an open-source project, one of your goals could be to allow other developers to be able to start contributing quickly.
One of the things that will help a lot is the possibility for a new developer to quickly be able to build and run your project, as well as run the tests. In order to do that, you can provide an easy way of installation of all the tools that a developer should have in order to contribute to your project.
This includes:
Build tools
Testing tools
Code quality tools (linter)
On the other hand, a user of your project is likely not going to need any of that, which is a good reason to split dependencies and devDependencies.
On top of that, it's useful to edit your package.json to provide useful scripts so that you can, for example, run npm test. It's common to specify something like:
{
...
"scripts": {
...
"test": "mocha -opts mocha.opts ...tests..."
}
}
Then npm test is going to run the specific mocha from your node_modules.

If you install it globally, that's a single version across all your projects.
If it's a dev dependency, each project can be using a version specific to that project, and the project can migrate to newer versions in a controlled way.
Pretty much the same argument as for having other modules loaded project-specific rather than globally.

Because you don't need to run mocha as a command. You can run it from node_modules like so: ./node_modules/.bin/mocha.
Npm has special support for this. If you have the following in package.json:
"scripts": {
"test": "mocha"
},
"devDependencies": {
"mocha": "*"
}
Then you can execute npm test even if you don't have mocha globally installed.
So, what's the use of this? First of all it's a nice thing to do if you collaborate with other developers - they don't need to do anything more than npm install to set up the development environment.
Second, and I think more useful, is this makes it easy to integrate your project with other tools like Travis etc.

Related

Workflow to use a sub-module typescript written module into a non-typescript module?

I'm having a private typescript module that is a dependency of another major project. This dependency is achieved by having the typescript repository as sub-module and installed using npm to the local sub-folder. The typescript module can compile into JavaScript on its dist folder and by doing so the major module that consumes it can make use of it without issues. But here is my problem, the dist folder isn't committed to the typescript repository.
What should be the workflow to follow in order to consume this typescript module from a JavaScript-only major project? The best I can think at this moment is to instruct someone, or something, to run the $ tsc command before using the major project but it's "annoying" since it isn't a transparent step. If this is a weird approach, what would be a more ideal approach? Thanks everyone.
You have a couple of options.
Assuming you're not planning to have a private npm registry using e.g. Verdaccio you can simply commit the dist folder. This is definitely the simplest option and it's not completely unheard of, I'd probably go with that option.
This solution is actually quite unusual, but it's pretty clever and it works. You could add a postinstall script in package.json of your TypeScript package that would run tsc after installing the package. The downside is that you'd have to add typescript as your dependency, which is not ideal (it should generally be a dev dependency, in which case it wouldn't be installed in the project using the package), but for some it might not be a big deal at all.
Instead of installing the package, you could use npm link and then have a script in your main project that would compile it. You'd have to run it every time something changes in that package, though. You could also append it to your npm start script, so it runs before it, e.g. "start": "npm compile-package && webpack" (assuming your current start script is "start": "webpack"). It doesn't scale very well though.
If your Javascript project uses Babel (and I'd assume so considering you said it's a "major" project) you could change its config so it transpiles Typescript for you using #babel/plugin-transform-typescript, however it can be a bit complicated, IIRC e.g. projects created with create-react-app by default don't recompile the code from node_modules.
There are probably more solutions, but I'd probably go with 1 or 2.

Why does Yarn sometimes ping pong between how it represents versions?

We have a React project that is using Yarn for package management. I notice that Yarn sometimes tweaks versions in the yarn.lock file even though nothing is changing. For example, when I run yarn install, it wants to make the change from:
yarn#^1.21.1:
to:
yarn#1.21.1, yarn#^1.21.1:
I don't quite understand why since the versions are the same. It flip-flops on this change quite often and it just depends on what packages we're installing. This example is for the yarn package itself, but it does this with a few different things.
Does anyone have any insight into why this is happening? Is it an issue with one developer's setup vs. another developer's setup? It's incredibly annoying because every time I sync my branch, run a yarn install, it wants to make changes to our lock file when I don't think it should be doing this.
Edit:
We also have this in our package.json file:
"resolutions": {
"yarn": "1.21.1"
}

Running npm-scripts on node

I am trying to get away from using Grunt or Gulp in my projects. I thought that a good way to replace them is by using npm-scripts.
I know that npm-scripts leverages package.json, but I noticed that to run more advanced build processes, you need to include command line functions. However, this is not a cross-platform solution since Windows doesn't support the wide variety of commands that an OS like Linux supports.
So, I was wondering if you could just run npm-scripts on Node, and just reference any npm package you want to with a require statement.
Is this possible? If not, are there any good cross-platform solutions that exist for npm-scripts excluding Grunt and Gulp?
Yes you could run "npm-scripts on node". For instance I have this in my package.json (irrelevant parts are removed for clarity), and both rimraf and webpack are implemented in pure JS and interpreted by node.js. In fact rimraf is a good example of cross platform rm -Rf. This solution runs fine on windows, mac or linux boxes by just issuing npm run-script build.
{
"scripts": {
"build": "rimraf dist && webpack --config ./blah.js"
},
"devDependencies": {
"rimraf": "^2.5.0",
"webpack": "^1.12.10"
}
}
Or you could do something like:
"scripts": {
"hello": "node hello"
}
And implement everything you want in hello.js in the same dir as your package.json, and include whatever you need in that script like:
const hello = require("debug")("hello"); // require whatever module you need
console.log("hello world");
It would run just fine with npm run-script hello
> your-module#1.0.0 hello D:\dev\tmp
> node hello
hello world
I would stick with webpack and npm only. Using webpack is much simpler than writing custom grunt or gulp tasks, dev server will give a stable local enviornment to work, and it is just a config setup and you are golden. I would also move away from using global installs especially if you work team environment or are running continuous delivery. As you won't be able to control the global installation or installed version on any of these environments.

When it comes to using react with yeoman

There are a ton of packages out there that have this all bundled up but I dont like the way they set up the projects and such so I was reading the Reactjs docs on installing with npm and my confusion is:
After installing it using npm install react or adding react to
package.json
Do I add this to the "devDependencies": {} or ...
for the require statement to work, do I need to include requirejs?
Can I just do grunt serv to start everything and auto compile the jsx or do I need to do this? (it seems like that might be answered for me ..... but how can I get it to auto compile the jsx when I run grunt serv)
I ask these questions and state I don't like the existing yo ... commands for this because they don't play nicely with bacbone.js So I was going to set this up my self. if there are any repos out there for yeoman that do this for me please point me to them.
dependencies vs devDependencies: for npm package.json, devDependencies are mainly used for the tooling around working on the project itself: testing tool chain and project building modules, for example. Things you'd often see in there: Mocha, Grunt, etc. So mostly for repo contributors and alike. As a consumer of React, you'd put it in dependencies, which are for modules that your code actually needs in order to work.
require isn't for requirejs. The naming clash is unfortunate. require() is part of CommonJS. Node uses CommonJS. Browserify too. Here, it's assuming that you're using Browserify, or maybe doing server-side React with Node.
I'm not sure what you've set up to use with grunt serve. There's nothing magical that makes it work by default. You do need to do what the link said. The --watch option will look for changes to your files and auto compile the jsx to js.
Hope that helps!

package.json generation / npm unused packages

I'm introducing unit testing in my project and for this, I need to make myself a package.json file.
First question is, which unit testing suite are you using? I'm looking forward mocha which seem to be pretty much standard for Node.js projects.
Second question is: Is there any magical way of generating a package.json file? (for dependencies and versions)
Third question is: I've been testing a lot of npm packages while developing my project and now I'm stuck with a lot of probably unused packages. Is there any way to tell which one are useless? (I saw npm list installed which is useful though)
I am using Mocha.
npm init
npm ls will list "extraneous" next to ones that are not in your package.json. But, it sounds like you don't have a package.json yet.
Basically, your workflow is very backward. Here is how it is intended to work:
Start a new project with npm init. It has no dependencies.
Oh, I want to start using a package, say express? Add it to package.json under dependencies, then run npm install.
Oh, I want to start using a package for development, say mocha? Add it to package.json under devDependencies, then run npm install.
You seem to have some existing code with manually-installed packages (via npm install <packageName>), which is a mess. I suggest starting over and following the above workflow.
To answer the third question:
npm prune
will remove all installed modules that are no longer mentioned in your package.json.
And you should really have asked 3 separate questions.
I am also using Mocha. It has code coverage, BDD, TDD, runs in browser. It is pretty complete and also heavily maintained by I think one of the most brilliant javascript/node.js programmers named TJ.
It is almost impossible to guess which version(s) to use. Because npm does not know which version breaks which dependencies. You could probably install all dependencies using something like node-detective. Then you can just install them using npm.js from within javascript. Maybe I would like to tackle this in the future.
I would also probably delete all dependencies , next install needed dependencies back using step(2). But also disc-space is not such a big case anymore with the current HDs.
P.S: I think I also agree with Domenic
I am using vows. It's pretty good, but not perfect. I have found unit testing in node to often be challenging because of async callbacks to dbs & such, and have mostly been testing top level functionality.
Here's your magic: Managing Node.js Dependencies with Shrinkwrap.
The only way to know what packages you are using is to know. You can't generate this programmatically. My advice would be to remove packages aggressively, then retest all functionality - if it breaks, you'll know you need to reinstall one of your packages.
Answering your third question, you can use Sweeper to list unused dependencies, and them remove them from your package.json. Just npm install -g sweeper then on your project directory call sweeper on the command line.

Categories