I was wondering if I could create a package that extends NPM and adds a new subcommand. I would like to create something like npm pretty what would order my package.json keys in a specific order.
I know it's kind of possible with npm scripts but I want to have it as a subcommand to use it globally.
I know there is https://github.com/keithamus/sort-package-json but I want to extend this project to my needs.
As far as I'm able to discover, you have two options.
The first is to add to the scripts key of your project's package.json file:
"scripts" : {
"pretty": "some-command-to-run [args]"
}
To run that, you'll use npm run pretty. Which isn't exactly like you want, but it's what's offered.
I had thought there's some form of global package.json file, but I'm not able to find any documentation around that so I'm taking absence of documentation as documentation of absence.
This means your only other option would be to contribute back to the npm source as a pull request, and hopefully they bring it into the baseline.
Related
My goal is to read in graphml files and retreive information about the fields that are contained within the nodes.
I have found a node module that seems to do just that so I decided I'd give it a try before writing my own code.
Unfortunately I the documentation is pretty poor and I have only been using node.js for about three months so I cannot figure out what the few clues given mean.
Global Install
npm install -g graphml-schema-generator
To have the wizard assist you with questions, type: gschema And answer the questions until finished.
Alternatively, you can use the following syntax: gschema path/to/graphml/file path/to/out/directory The paths can be either relative or absolute. The tool should pick on it either way.
Local Install
npm install --save graphm-schema-generator
You can either type the whole path to the file each time, such as: ./node_modules/gml-to-typescript/build/index Or you can create an npm script that references the path
However you choose to go about it, the usage is exactly the same as stated in the Global Install section. Please refer to that.
If you don't want to pollute your development environment this might be a better way to install this. Then you can use npm scripts to alias it to a more manageable command.
There's no GitHub repository or what-so-ever. I have read through the code and basically there are three files of which two seem to be sourcefiles (exporting some modules that are used in the last one) and one that's called "app.ts".
I somehow expected that I could use this module like
import {<ModuleName>} from 'graphml-schema-generator';
or
require('./node_modules/graphml-schema-generator";
but this isn't the case. I do not understand what
gschema path/to/graphml/file path/to/out/directory
would mean or how it would be used. I guess there's some basic misunderstanding about packages on my side.
here's an Image of the modules hierarchy
So I want to understand how to use this module and if so, what I did wrong
Thanks in advance
I'm setting up a build system using node modules and npm scripts - no gulp, etc.
I need to determine if two files are equal, before copying unnecessarily. When I used to use gulp I used the gulp-changed plugin. I need something like that.
How could I do this in plain node?
I couldn't find an existing npm module that does this. I also checked the fs module but didn't find anything I could use.
I need something like this: function hasChanged(file1, file2) { /* ... */ } but I'm not sure how to compare the files.
UPDATE
Using the advice given so far, this problem seems simple enough to code myself, so I'm doing that. But if you know of a node module that does this already, I'd appreciate it.
You might use fs.stat function to get file info, and compare mtime to see if they differ. I also recommend you to lookup the sourcecode of gulp-change, its actully just a few lines of code.
https://github.com/sindresorhus/gulp-changed?files=1
Do you try use fs.watch.
It is still possible to use fs.watchFile(), which uses stat polling, but this method is slower and less reliable.
If you want check 2 file, try using hash code of them with md5.
Will somebody please help me understand how to update typings via the typings.json?
When I update certain libraries, their typings become deprecated. This is all well and good, but running typings install --save or any combination of typings install with any of my given libraries throws errors a-la "unable to find angular-protractor", etc.
The problem is that I can't understand how you're supposed to derive the version number. I understand that it is derived from the timestamp of the commit or whatever, but that seems like a terrible way to try to update something as simple as a typing. Particularly since, the only way I've found to be able to upgrade them, is find them and update typings.json manually.
For example:
{
"globalDependencies": {
"angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
}
}
So, version 1.5.0+20160425143459 is deprecated, but I have no idea what the new one is since it won't tell me, and the angular-protractor definition on github in the definitely typed repo doesn't seem to provide any info past the major/minor/patch.
I'm sure I'm missing something simple. Thanks for any help.
I have been working with TypeScript off and on for two years now. I am not an expert by any means, but I've spent some time in the eco-system: with VS2015 and node tools, with VSCode, and at the command line with tsc and typings (also used by VSCode).
And I have struggled with the correct way to get static typing and auto-complete etc in the code I've been writing.
I have a repo I maintain (EasyNodeQ) which was the start of my TypeScript experience and I sort of got that to a manageable place with ///reference and DefinitelyTyped. But any time I tried to use that within another project I had issues.
Things got a little better when I started using typings (rather than downloading the *.d.ts files myself) and especially with the ambient flag.
But I still have lots of issues trying to use that package within other projects. Depending on the approach I take, I get lots of Duplicate Identifier's, or module not found's or...
And this can range from Node definitions, to packages I use in both places (like node-uuid).
All I want to understand is this: how to I structure EasyNodeQ so that as I'm working on it, I get the static typings benefits of TypeScript but also have it be seamlessly included in other projects which can then also get these benefits?
Does that make sense?
The basic use cases are: npm install a package and get its typings, use my EasyNodeQ package and get its typings, work in a new project that uses EasyNodeQ and other packages and easily manage those typings.
Preferably in a VSCode or command line way...
This is with ES6 and the latest version of TypeScript (though an answer that works with ES5 would be nice - just not required).
I hope this makes sense. I've looked all over and I can't cobble together an answer that works.
UPDATE
I'm not convinced I've done this the "right" way, but it's working now so I thought I'd post the various things I've done (generally in the order I think they mattered and not inclusive because I may have forgotten some).
I hadn't npm'd the dependency package (easynodeq) and was just using a git url in the package.json - so I created a proper npm package and now install that package from npm
Instead of trying to use Bus.ts as both code and definition, I made Bus.js the "meat" of the npm, and built a Bus.d.ts file (also in the npm)
Embraced typings, using non-ambient definitions where possible and a mix of ambient definitions downloaded (via git) from DefinitelyTyped and "--ambient" definitions for the rest (because I'm still confused about the difference). The ambient definitions ended-up being the majority: node, express, serve-static, express-serve-static-core, mime, amqplib, when vs just bluebird and node-uuid, even though most of them were found by "typings search ..." Am I doing something wrong?
Modified package.json to also do "typings install"
Cleaned-up the git repo
There are several ways to make this work today. As you mentioned, using Typings works for definitions that aren't natively included in their NPM packages. For ones that do, you can using the typings field in package.json and it'll work with node module resolution. When you combine this together, you can publish packages that use both typings.json and relies on packaged typings - though this now forces your consumers to be using Typings to install the definitions. None of this, however, works with "ambient" definitions as they can not be namespaced properly.
This may be useful: https://github.com/typings/typings/blob/master/docs/faq.md#should-i-use-the-typings-field-in-packagejson. There's also dozens of examples I have using both workflows: https://github.com/blakeembrey/change-case/blob/master/package.json#L6 which uses node module resolution all the way down and https://github.com/blakeembrey/popsicle/blob/master/typings.json which uses Typings instead. Using Typings is only possible because it works to create namespaced ambient modules for you, but they won't conflict.
Is there a way to specify OS specific dependencies in a npm package.json file?
For example, I would only want to install 'dbus' (https://npmjs.org/package/dbus) as a dependency for my module if the user is running Linux. I would have a different dependency for Mac and Windows.
There's a possible good way of doing this, depending on your setup.
npm package.json supports an os key,
and also optionalDependencies
os can be used to specify which OS a module can be installed on.
optionalDependencies are module dependencies that if they cannot be installed, npm skips them and continues installing.
In this way you can have your module have an optional dependency for each OS, and only the one which works will be loaded/installed ^.^
EDIT: As #Sebastien mentions below, this approach is dangerous.
For any given OS, at least one of your dependencies is "required" and the rest "optional". Making all versions of the dependency optional means that if your installation fails for a legitimate reason, it will silently skip installation and you will be missing a dependency you really need.
I think the short answer is no. I can think of a couple of workarounds though - the simplest is to just add everything to package.json regardless of OS, and then require() the correct one at runtime.
If that doesn't work for you, you might be able to use an install script to get the result you're going for - https://docs.npmjs.com/misc/scripts
I haven't tested this but I think it would work:
Add something like this to your package.json:
,"scripts": {
"install": "node install_dependencies.js"
}
And then add a install_dependencies.js file that checks the OS and runs the appropriate npm install ... commands.
There's also the bindings-shyp module:
https://www.npmjs.com/package/bindings-shyp
Helper module for loading your native module's .node file
This is a helper module for authors of Node.js native addon modules. It is basically the "swiss army knife" of require()ing your native module's .node file.
Throughout the course of Node's native addon history, addons have ended up being compiled in a variety of different places, depending on which build tool and which version of node was used. To make matters worse, now the gyp build tool can produce either a Release or Debug build, each being built into different locations.
This module checks all the possible locations that a native addon would be built at, and returns the first one that loads successfully.
Quoting #npm_support at:
https://twitter.com/npm_support/status/968195526989512705
2/2 If you'd like to avoid installation problems related to dependencies, one route is for you to write a wrapper that's required as a regular dependency, and to make sure that it has optionalDeps (and also ensure that the wrapper verifies you have everything needed to work).
But IMHO it looks more like a workaround than solving the problem for real.
I can understand that npm wants to preserve portability and avoid to deal with platform specifics, but it has to be done anyway and IMHO doing this at runtime is not optimal (specialty if one wants do optimize code size).
So today I have no optimal solution to share but an open discussion for proposal.
Can't "conditional dependencies" be supported in npm ?
The 1st thing that came to my mind was to to add a "override" section that will change (+add, -remove, =replace) current parsed sections.
For example:
dependencies: { "common-stuff": "*" }
overrides: {
"os: { linux: { dependencies: { "+best-linux-module" } } }
}
And other option suggested by a developer I know, would be to introduce a provides keyword, then several modules could provide a same semantic than would be satisfied by resolver (a la debian), but it's generating similar overhead.
I am looking for a generic approach not only focused on OS support but also on other flavors of package (depending on engines for instance).
Do you know any related issue in NPM tracker ? if not I am considering to file a bug to be tracked at:
https://github.com/npm/npm/issues?q=dependencies+conditional
Feedback welcome on this idea.