Interdependent NPM packages: peerDependency not resolving against "host" package - npm

I disovered the hard way today that I need to split a library into two packages; lets call them CoreLib and TestCoreLib. The CoreLib package is a library, the TestCoreLib library is the bundle of utilities and actors needs to setup the test environment required to test the CoreLib library. The added benefit of splitting this into two packages is that apps built with CoreLib can also beneift from use of TestCoreLib as it also suffices as a mocking library.
As TestCoreLib uses some actors from CoreLib, I defined CoreLib as a peerDependency of TestCoreLib.
{
"name": "TestCoreLib",
"version": "1.0.0-rc.1",
"type": "module",
"peerDependencies": {
"CoreLib": "^1.0.0-rc.0"
}
}
Conversely, I defined TestCoreLib as a devDependency of CoreLib as CoreLib of course has the need of passing its tests before publish.
{
"name": "CoreLib",
"version": "1.0.0-rc.1",
"type": "module",
"devDependencies": {
"TestCoreLib": "^1.0.0-rc.0"
}
}
Both release candidate packages have been published to NPM successfully and I have setup a third project DemoApp that uses both CoreLib and TestCoreLib successfully.
{
"name": "DemoApp",
"version": "1.0.0-rc.1",
"type": "module",
"devDependencies": {
"CoreLib": "^1.0.0-rc.0",
"TestCoreLib": "^1.0.0-rc.0"
}
}
The problem is now in the development branch of the CoreLib project. Tests don't complete complete as the following error is thrown:
Uncaught Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'CoreLib' imported from /path/to/CoreLib/node_modules/CoreTestLib/lib/index.js
That tells me that CoreLib is not being picked up by TestCoreLib, even though TestCoreLib is in the node_modules directory of the CoreLib project. The first statement in TestCoreLib is an import from CoreLib, so I assume the error is being thrown as that import is not being resolved even though it should... right?
I always want the development version of CoreLib to be used by TestCoreLib, so I am concerned about adding CoreLib as a devDependency (instead of a peerDependency) of TestCoreLib as I worry that doing such will lock CoreLib into version conflict with its own prior release, but I am honestly confused about what would happen in that context.
The lazy boy moon shot of linking TestCoreLib to CoreLib does not solve the problem either, so I am obviously missing something fundamental that I would really appreciate your help with.
Do you know of any projects that successfully split their packages off into peerDependencies in such a way that you could refer me to?
Is there an elephant in the room sitting top of me and if so could you tell it to get off so that I can resolve this maddening issue and move on? LMAO
Be safe, well, calm, clear, happy fellow humans. Thanks for considerations.

The elephant in the room was... the lazy boy moonshot and my misuse of it. My automatic typing fingers told me five minutes ago by adding the scoped package name to it
$ npm link #emmington/CoreLib
npm link by itself is insufficient for a symlinking a scoped package folder.
Symlinking a package folder
Scoped Packaged

Related

How to determine the dependencies of older npm package versions

It appears to me that the dependency linkage on the npm site is only applicable to the current/latest version.
Is there some tidbit of information that I'm not aware of on how to determine what dependency version a package has other than by downloading it and inspecting the package.json file?
I feel like I'm wasting HOURS doing something I would expect to be much easier to do.
"It appears to me that the dependency linkage on the npm site is only applicable to the current/latest version."
Yes that's correct, www.npmjs.com will only show the dependencies for the latest version of a package.
Here are a couple of ways to discover what you want both programmatically and non-programmatically.
Programmatically:
Utilizing the npm view command with the following syntax;
npm view <pkg_name> versions --json
obtains a list of all versions available for a given package in the npm registry.
Note: The <pkg_name> part above should be substituted with the real package name.
For instance; running the following command for let's say the eslint package:
npm view eslint versions --json
prints the following to the console:
[
"0.0.4",
"0.0.5",
"0.0.6",
"0.0.7",
"0.1.0-dev",
"0.1.0",
"0.1.1",
"0.1.2",
...
]
Now we know what versions are available, let's say we want to list the dependencies for eslint version 0.1.2 we can run the following command:
npm show eslint#0.1.2 dependencies --json
This will print:
{
"optimist": "*",
"estraverse": "~1.3.0",
"esprima": "*",
"escope": "1.0.0"
}
Similarly, we can discover the devDependencies for eslint version 0.1.2 by running the following command instead:
npm show eslint#0.1.2 devDependencies --json
This will yield something like this:
{
"vows": "~0.7.0",
"sinon": "*",
"commonjs-everywhere": "~0.9.0",
"mocha": "~1.13.0",
"chai": "~1.8.1",
"grunt": "~0.4.1",
...
}
If you know that a package has a particular dependency in advance.
For instance; retrospectively after running the aforementioned command we now know that eslint version 0.1.2 has escope listed as a dependency.
So, if we wanted to know the version of escope that eslint version 0.1.2 needs, we can run the following command:
npm show eslint#0.1.2 dependencies.escope
^
Note: The package name follows the dot (.), i.e. .escope
This prints the following:
1.0.0
The non-programmatic way
I can't think of a reason why you would want to perform the following non-programmatic way instead of the aforementioned programmatic way when you have a CLI tool available to you. However, if you prefer manual tasks then here goes...
Note: YMMV using the following manual steps as it depends on how the package has been managed/maintained.
Typically, the source code of an npm package will be hosted on GitHub, so you can perform the following manual steps. This will avoid you having to download the package to inspect the package.json file.
For this we'll demonstrate for the eslint package:
Visit npmjs.com and type the name of the package in the "Search Packages" input field. We'll type eslint and hit the return key.
Next click eslint from the list of packages, which will take you to this page.
Click on the github link which typically appears on the right-hand side of the webpage and looks like this:
That will take you to the eslint repo, i.e. this one
On the Github page click the "Branch" button - which appears above the list of source code files, and looks like this:
In the pop-up panel that subsequently appears click the "Tags" button, then locate and click the version tag from the list that you want to discover it's dependencies. (Note: These tag names will typically correspond to the version released/published to npm)
This will then load the source code files in the browser for that particular release/version.
Locate the package.json file from the list of files and click it. This will load the contents of package.json in the browser, upon which you can read it and ascertain its dependencies.
Visualizing the dependency tree
I sometimes utilize this online tool https://npm.anvaka.com which can help you to visualize the complete dependency tree/graph for a given package - however it's for the latest version of a package only.
Here is the complete dependency tree/graph (many levels deep) for the latest version of eslint.

Yarn (or npm) swap nested dependency with a fork

In my package.json I have a package:
{
"somepackage": "^6.5.1"
}
This package has a dependency (from somepackage's package.json):
{
"someotherpackage": "^9.4.2"
}
I want to swap someotherpackage to one of its fork.
I know of yarn's Selective dependency resolution feature, but I guess that is only for different versions of the same package.
I could as well fork somepackage and change its dependencies manually, swapping someotherpackage to someotherpackage-fork, but if there is another way I would take that.
Thanks!
The mentioned selective dependency resolution feature is the way to go. Under the hood it seems to be resolving packages the same way dependencies does which allows us to do the following:
"resolutions": {
"**/someotherpackage": "npm:someotherpackage-fork#*"
}
You can also specify which version of your fork you want:
"resolutions": {
"**/someotherpackage": "npm:someotherpackage-fork#3.0.2"
}
I haven't confirmed if this works for Yarn version 2 yet.
Showcase: https://github.com/dimitarnestorov/yarn-resolutions-showcase

Why is dependency in package.json prefixed with #polymer?

When looking at this package.json I see two versions for sinonjs:
"dependencies": {
"#polymer/sinonjs": "^1.14.1",
...
"sinon": "^2.3.5",
...
},
What is the difference between sinon and #polymer/sinonjs?
Node packages that start with #namespace are scoped packages. Typically this means an organization that wants a standardized naming convention for all of their packages that might have common names already taken in the global namespace.
In your example the organization is Polymer who has their own published version of sinon. As to why Polymer has their own published package of Sinon you'd have to ask them. The description suggests it's a workaround to access the Bower version of Sinon. That workaround probably wont be needed once Polymer makes the jump to NPM.
SinonJS proxy repository for the BowerJS package manager

How do I declare a development dependency in project.json?

In my project.json, I need to refer to a library that I'm using during development, but don't want included in the project output. This is common for things like static analyzers and other tools.
Before project.json, this was handled by a metadata tag in the package .nuspec file. But, this no longer works (as far as I know) for projects following the new JSON standard.
How do I declare a development-only dependency in the new standard?
As of 1.0.0-rc1, the correct syntax is:
"dependencies": {
"HelloShared": {
"version": "0.1-beta-*",
"type": "build"
}
},
This declares HelloShared as a build (development-only) dependency of the current project.
I found this example in dnx/samples/HelloWorld/project.json on Github.
Project.json has a publishOptions:exclude section.

How to use modules/packages like htmltojsx in ASP.Net or in any other web application

In order to convert some dynamic HTML to React's JSX, in my ASP.Net MVC based project I want to use htmltojsx, but can't figure out how to incorporate it in the project as it involves requireJS and probably some other JavaScript dependencies.
If someone can describe it in an easy/clear manner, would be of great help. Will salute you if some working example fiddle is also provided.
OK, posting answer to my own question after a long time. Here is a brief summary of what I found out during my research on this topic in past few weeks.
Actually it involved exploring various co-related topics before to getting onto the right point.
To understand how to incorporate packages (especially npm based) like htmltojsx into web apps, we need to understand first 'Modules'.
By 'Modules' we mean a composed set of highly decoupled, distinct pieces of functionality that we have also the ability to dynamically load, sort of something like 'Import' statements we have in C# and some other Server side Languages.
Most modules are either based on CommonJS or AMD formats. Here is a very nice Blog on these. Please do read it first for a through understanding.
Writing Modular JavaScript With AMD, CommonJS & ES Harmony
To make us enable to use these modules in any web application there are then Module bundlers like Webpack, Browserify etc.
In short, a Module bundler takes modules with dependencies and generates static assets (like .js/.css files etc.) representing those modules.
These static assets can then be used in any web page like we do with HTML script/link tags normally.
Also to mention here, for using Webpack/Browserify one must first understand node's npm package manager which has become heart and soul of all Javascript's module based applications. Basically npm is a package manager and makes it easy for JavaScript developers to share and reuse code. It has become the de-facto standard behind the creation of well managed module based applications.
For using this an understanding of package.json is primary and vital step.
A developer must have to define the dependencies in a file named as package.json that describes modules/packages that an application will depend upon.
There are mainly two kinds of dependencies. Normal dependencies, defined in "dependencies" option (which are packaged along with the output static asset(s)) and "devDependencies" (which take part in compilation of modules and/or their resources). A typical devDependency is Babel, which is used to compile ES6 aka ES2015, React etc. to ES5 syntax which all major Browsers can understand.
After defining these dependencies in package.json file, we can just use them using a simple require statement, example:
var webpack = require("webpack");
An example package.json file would look something like this:
{
"name": "my-sample-app",
"description": "My sample app",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "John",
"dependencies": {
"classnames": "^2.1.3",
"datejs": "0.0.2"
},
"devDependencies": {
"babel": "^6.3.26",
"babel-core": "^6.4.0",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.3.13",
"css-loader": "^0.23.1",
"style-loader": "^0.13.0",
"webpack": "^1.12.11"
}
}
Once we understand package.json and some npm commands, using webpack we can compile modules into static assets and then use them in any web page.
Here are also some links that can help us understand all this better:
Getting Started With React ES6 & Webpack
Setting up React for ES6 with Webpack and Babel