Role of the src and dist folders in NPM packages - javascript

Im using Restangular for HTTP requests. I want to use the method customPATCH. I can see it in the Restangular src/ directory here.
However when I ran 'npm install restangular' and pointed to the dist/ folder, I was getting the error "customPATCH is not a function". I noticed the source code in the dist/ folder isnt the same as what's in the src/ folder (it doesnt define the customPATCH method).
Why would there be a difference between what's in src/ and what's in dist/ for an NPM package? Are these normally kept in sync? In this case, the dist/ directory hasn't been updated in 8 months. Should I just use the source in the src/ folder? Maybe I'm misunderstanding how to use NPM packages (I always use the source in the dist/ folder)...

src/ and dist/ is a common naming convention for most packages. In most instances a developer has the code that they are working on src/ and the distribution version of the code they want others to use dist/. Most developers, my self included will either compile, minify or concatenate their code in to production facing version of the code. They usually include the src/ file in their public repositories so that people can see the source code and modify it as they see fit.
tdlr;
src/is the code the developer is working in.
dist/ is the distribution version that has been modified to perform better for users not looking to modify how the code works.

Typically src contains source code and dist code after minification and other changes (anyway, derived code - what would be target in Java world).
Sometimes when main repo is written in EcmaScript6 or newer, then dist folder contains code transpiled down to EcmaScript5 to support older versions of nodejs / older browsers.
You can use code from src if it works for you - however typically code in dist is minified and hence faster.
But sometimes authors forget to update dist folder and then you might have discrepancies. You might ping the author to rebuild the dist folder.

Related

How to publish ignored by git distribution files to Bower?

I am building a package for NPM and Bower.
I follow this pattern to keep the working files (ES6) in the src/ directory of my package and build my distribution files (ES5, compiled with Babel) in the lib/ directory.
In my .gitignore I ignore lib/.
On the one hand side (NPM), I have a .npmignore which ignores src/, instead of lib/. This is how I publish the lib/ folder contents on NPM.
On the other hand side (Bower), the lib/ folder is missing in the repository, therefore, the Bower package doesn't include it. How can I publish the ignored by git lib/ folder contents on Bower?
I think that's not possible.
The workaround I found is to commit the distribution files in the repository.
If they really piss you off - you could do this dirty trick: commit them right before you release a tag. Release a tag. Remove them.
Or simply drop the Bower support. But that's not a real solution to the problem, isn't it? :-)

Writing npm modules in TypeScript

I am working on my first npm module. I briefly worked with TypeScript before and a big problem was that for many modules there were no definition files available. So I thought it would be a good idea to write my module in TypeScript.
However, I can't find any information on the best way to do that. I found this related question "Can I write npm package in CoffeeScript?" where people suggest only publishing the JavaScript files. But in contrast to the CoffeeScript files, the TypeScript files might actually be useful if they are used within a TypeScript application.
Should I include TypeScript files when publishing an npm module, or should I only publish the JavaScript files and provide the generated .d.ts files to DefinitelyTyped?
Here is a sample Node module written in TypeScript : https://github.com/basarat/ts-npm-module
Here is a sample TypeScript project that uses this sample module https://github.com/basarat/ts-npm-module-consume
Basically you need to :
compile with commonjs and declaration:true
generate a .d.ts file
And then
Have your ide read the generated .d.ts.
Atom-TypeScript just provides a nice workflow around this : https://github.com/TypeStrong/atom-typescript#packagejson-support
With TypeScript 4.x, TypeScript 3.x or TypeScript 2.x, the following steps describe what you have to do to create a library (npm package) with TypeScript:
Create your project as you normally would (with tests and everything)
Add declaration: true to tsconfig.json to generate typings.
Export the API through an index.ts
In the package.json, point to your generated typings. For example if your outDir is dist, then add "types": "dist/index.d.ts" to your package json.
In the package.json, point to your main entry file. For example if your outDir is dist and the main entry file is index.js, then add "main": "dist/index.js" to your package.json.
In the package.json, whitelist the files you'd like to ship to npm: files: ["/dist"]. An alternative approach is blacklisting with .npmignore, but it's harder to keep up to date.
Publish to npm with npm publish. Use semver specifications for updates (patch / bug fix npm version patch, non-breaking additions npm version minor, breaking api changes npm version major)
Since it got me a while to sift through all the outdated resources on this topic on the internet (like the one on this page...) I decided to wrap it up in how-to-write-a-typescript-library with an up-to-date working minimal example.
This is a more recent answer using TypeScript 1.8.10:
My project structure is:
|
|--- src
|--- test
|--- dist <= My gulp file compiles and places the js, sourcemaps and .d.ts files here
| |--- src
| |--- test
|--- typings
.gitignore
.npmignore
gulpfile.js
package.json
README.md
tsconfig.json
tslint.json
typings.json
I added the following in .npmignore to avoid including extraneous files and keep the bare minimum to have the package imported and working:
node_modules/
*.log
*.tgz
src/
test/
gulpfile.js
tsconfig.json
tslint.json
typings.json
typings
dist/test
My .gitignore has:
typings
# ignore .js.map files
*.js.map
*.js
dist
My package.json has:
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
Now I run:
npm pack
The resultant file (when unzipped) has the following structure:
|
|--- dist
| |--- src
| |
| index.js
| index.js.map
| index.d.ts
|
package.json
README.md
Now I go to the project where I want to use this as a library and type:
npm install ./project-1.0.0.tgz
It successfully installs.
Now I create a file index.ts in my project where I just installed the npm
import Project = require("project");
Typing Project. gives me the Intellisense options which was the point of this whole exercise.
Hope this helps someone else in using their TypeScript npm projects as internal libraries in their bigger projects.
PS: I believe that this approach of compiling projects to npm modules which can be used in other projects is reminiscent of the .dll in the .NET world. I could well imagine projects being organised in a Solution in VS Code where each project produces a an npm package which can then be used in another project in the solution as a dependency.
Since it took a fair amount of time for me to figure this out, I have posted it in case someone is stuck here.
I also posted it for a closed bug at:
https://github.com/npm/npm/issues/11546
This example has been uploaded to Github: vchatterji/tsc-seed
You should publish the original typescript sources instead of the type definition. In package.json let the 'types' property point to the *.ts file.
*.d.ts are good to annotate existing JS libs, but as a consumer I'd rather read the typescript code than switching between type definitions and down-leveled, generated JS code.
I mainly follow the suggestion by Varun Chatterji
But, I would like to show a complete example with unit testing and code coverage and publishing it into npm and importing them using javascript or typescript
This module is written using typescript 2.2 and it is important to configure the prepublish hook to compile the code using tsc before publish it to npm
https://github.com/sweetim/haversine-position
https://www.npmjs.com/package/haversine-position
You can use autodts to handle distributing and using .d.ts files from npm also without support from the Atom IDE.
autodts generate will bundle all your own .d.ts files together for publishing on npm, and autodts link handles references to other installed packages, which may not always be directly under node_modules in a larger project split into several subpackages.
Both commands read their settings from package.json and tsconfig.json in "convention over configuration" style.
There's another answer on stackoverflow and a blog post with more details.

How does jquery's bower.json file point to a folder not included in git?

I am trying to understand how bower works..
If you look at jquery's github repo https://github.com/jquery/jquery you will see that the bower.json file points to dist/jquery.js. However, the repo does not include this folder on github, because the /dist folder is a product of the build step that is not checked into git (it is included in .gitignore).
So I am at a loss for how bower finds the dist/jquery.js file when it is not included in the git repo??
A couple of other points that should lead you on your way:
Gruntfile.js has a build task that outputs the built file to dist/jquery.js (see also build/tasks/build.js).
package.json has a dependency on grunt-bowercopy.
Related: Managing Bower components with Grunt
As #cbuckley said, the trick is that Bower will checkout from Git a tagged version instead of the master head. If you have a look at Jquery, the 2.1.1 tagged version has a jquery.js in dist/

npm install on modules not in node_modules/

I'm building a project and I want to split it up into different modules. I know I should put modules into node_modules/ but I want to commit the modules to the main version control for the time being (I'm using .gitignore to ignore the node_modules/ directory at the moment).
My current project setup:
services/
services/service1/package.json
services/service1/index.js
services/service2/package.json
services/service2/index.js
node_modules/*
app.js
package.json
My problem is it works with relative requires but the dependences in the services/*/package.json aren't loaded. Only the main package.json are loaded.
Is this a good approach? Is there a better one? What command can I run to install all the dependences? This is more of a problem for my CI/CD setup.
Thanks.
i found similar feature request here https://github.com/npm/npm/issues/4017 and seems you can't do it
one approach i see is to create soft links from node_modules to services you want and maintain them somehow
maybe you can use https://www.npmjs.org/doc/misc/npm-scripts.html postinstall script for this?

NPM Pack / Nodejitsu ignores buried Node_modules folders

It seems that NPM pack, and by extension, nodejitsu, do not like my node_modules folders. :*(
I currently am building a web app.
My web app's project folder structure is as follows:
Root
Engine(folder) Server(folder) readme.md package.json
(Multiple Folders) (folder)(folder) node_modules(folder)
easyimage,mongodb,mysql(folders) socket.io (folder)
node_modules(folder, NPM Pack ignores this) node_modules(folder, NPM Pack ignores this)
Socket.io-client (folder, NPM Pack ignores this)
I hope everyone can see this structure alright!
The problem I am having is that when I run NPM Pack at the root directory, the entire directory structure is packed correctly, except for all of the node_modules folders below the first node_modules folder.
It is as if NPM pack completely ignores those node_modules folders. (The one below socket.io for instance).
Due to the fact NPM pack ignores these npm folders, jitsu is also ignoring them and I can't get my web app started.
How can I get NPM pack/nodejitsu to correctly package all of the node_modules folders correctly?
My current package.json file, at the root directory, looks like follows:
http://pastebin.com/SAU6rwb5
As you can see, I have attempted to use bundleDependencies to tell NPM Pack that I am trying to include some node_modules folders (modules?), but pack still ignores all of them... Also, if i include anything under "dependencies", NPM start creates a new (??) node_modules folder at the root directory... but at the root directory nothing needs node_modules... as you can see node_modules are used inside of the server folder.
How can I get NPM Pack to recognize the files and folders inside of all of the node_modules folders and pack them correctly?
(jump to last paragraph if you want a really easy solution)
I'm having a hard time understanding your app structure. I think I get what your trying to do though.
From https://npmjs.org/doc/folders.html , it actually goes into detail about when and why sub modules will or wont show up.
When installing locally, npm first tries to find an appropriate prefix folder. This is so that npm install foo#1.2.3 will install to the sensible root of your package, even if you happen to have cded into some other folder.
Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a package.json file, or a node_modules folder. If such a thing is found, then that is treated as the effective "current directory" for the purpose of running npm commands. (This behavior is inspired by and similar to git's .git-folder seeking logic when running git commands in a working dir.)
If no package root is found, then the current folder is used.
When you run npm install foo#1.2.3, then the package is loaded into the cache, and then unpacked into ./node_modules/foo. Then, any of foo's dependencies are similarly unpacked into ./node_modules/foo/node_modules/....
Bear With me for another quote...
Cycles are handled using the property of node's module system that it walks up the directories looking for node_modules folders. So, at every stage, if a package is already installed in an ancestor node_modules folder, then it is not installed at the current location.
Consider the case above, where foo -> bar -> baz. Imagine if, in addition to that, baz depended on bar, so you'd have: foo -> bar -> baz -> bar -> baz .... However, since the folder structure is: foo/node_modules/bar/node_modules/baz, there's no need to put another copy of bar into .../baz/node_modules, since when it calls require("bar"), it will get the copy that is installed in foo/node_modules/bar.
This shortcut is only used if the exact same version would be installed in multiple nested node_modules folders. It is still possible to have a/node_modules/b/node_modules/a if the two "a" packages are different versions. However, without repeating the exact same package multiple times, an infinite regress will always be prevented.
As far as the bundledDependencies:
Upon publishing [this also applies to packing], npm will look in the node_modules folder. If any of the items there are not in the bundledDependencies array, then they will not be included in the package tarball.
I take this to mean that it will only bundle the listed modules in ./node_modules/ and specific sub-modules for a ./package.json . Then of course as written above, it recursively walks down the directory tree again... so if it sees another package.json file in this directory npm will look and see if that has any bundled deps to include in the pack.
So as I understand it right now, since you have no packages in your base directory, your bundled dependencies in package.json doesn't do anything, and actually having items in your bundledDependencies field does more harm than good.
To fix you need to edit the package.json files to include these bundles at each level.
I have had this issue before when trying to get a packed then unpacked meteor app working on nodejitsu. I solved it in a different way. In the root folder of my app I included all of the top level node modules and explicitly set their version in my package.json file.
From what I understand your file structure is such:
app
+-- Engine
+-- Server
| +-- socket.io
| | `-- package.json
| | +-- node_modules
`-- readme.md
`-- package.json
If this is so then you need to be editing the package.json under socket.io to include the bundled deps you want. Generally though you can trust the package maintainers to keep valid versions.(but in this case you can't?)
As for Socket.io-client not being packed that's a result of it being a dependency of socket.io.
If I was to suggest a way for you to make this easier for yourself, i'd suggest you to, in your MAIN top level package.json file, to include the dependencies you need for your app # the specific version you need. If you need them bundled for some reason, add them into the bundled section, if you need sub modules at a different version than what the author intended. Consider making a folder called package or vendor and then placing the modules in there, in those you can edit the package.json and bundles their dependencies to your hearts content. Be sure though that you do not ignore any files or folders under you vendor or packages directory with .npmignore or .gitignore files.
Alternatively, if this is too difficult (editing all theses files and specifying certain versions can be a pain) I'd suggest hosting your vendor packages some where where you could download them with a script, and then execute this script in the postinstall part of your package.json (take a read at https://npmjs.org/doc/scripts.html ... you would add this in the same section you have your "start" script.
I hope that clarifies things.

Categories