Node and npm version locking for frontend framework projects? - javascript

I have a frontend project in React and another in Vue where other developers will be making pushes to the repo. I am using a set version of node and npm but what is the best way to enforce these versions for other developers so that the js bundles they build will be using the same? We currently don't have a proper build process so the build of the bundles are just done through the command line (e.g. npm build production).

You can use a engines property in package.json and can use "engineStrict": true in order to enforce it.
{
"engineStrict": true,
"engines": {
"node" : ">=0.10.3 <0.12",
"npm" : "~1.0.20"
}
go one directory up and then install it like - npm install myproject that will trigger the checks for engines and engineStrict.
If the particular versions are not present then it will throw error.
However engineStrict was removed in npm 3.0.0 so you can use npm --engine-strict=true from command line.

Related

Use npm modules written in ES6 with react-scripts

In my project I need to use the npm module ipfs-api with create-react-app.
I can run npm start and run the proect.
But when I try to build the proect with react-scripts build, it throws the following error
Failed to compile.
Failed to minify the code from this file:
./node_modules/ipfs-api/src/utils/module-config.js:7
Read more here: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-build-fails-to-minify
According to the suggestions in the provided link in eorror log, I tried using,
"dependencies": {
...
"ipfs-api": "github:atfornes/js-ipfs-api#transpiled",
...
}
instead of "ipfs-api": "^22.0.0",. Although this solved error for ipfs-api, other dependent modules (probably installed with ipfsapi) kept giving same type of Failed to minify errors which I stopped transpiling them manually.
Is there a way to transile all the dependent node modules to es5 while before using the command react-scripts build ? Or any other way to overcome this issue?
Usually client-side or platform independent packages are compiled to ES5 on publishing. That you have this problem may suggest that the package isn't intended for client side.
As the documentation explains, the package contains a bundle for browsers that includes polyfilled Node features (streams, etc.) that are needed to run it on client side.
It's supposed to be used as a global:
import 'ipfs-api/dist';
ipfs(...)
Is there a way to transile all the dependent node modules to es5 while before using the command react-scripts build ?
This would require to eject create-react-app configuration and configure Webpack to transpile this package properly. This example from the documentation shows how Node-specific parts should be configured to bundled for browsers.

How to develop client side library and npm library ?

I would like to develop a JS test library for client & node.
I need to develop for two different repo's?
Lets take for example QUnit:
for client side I will use:
https://code.jquery.com/qunit/qunit-2.3.0.js
But for node develop, I will use :
npm install qunitjs
Those are 2 different code repo's, aren't?
For the example, lets puts aside the testrunner, etc..
Thanks!
Originally the "npm" used to stand for the "Node Package Manager".
Currently, the npm Registry is a public collection of packages of open-source code for Node.js, front-end web apps, mobile apps, robots, routers, and countless other needs of the JavaScript community.
And npm is the command line client that allows developers to install and publish those packages.
See: https://www.npmjs.com/about
So you can use npm to package front-end code just like you can use npm to package Node code. Sometimes it makes sense to publish two packages - one for frontend and one for backend - but sometimes you can have just one.
For packaging frontend code there are more options like Bower: https://bower.io/
For packaging Node code the most popular choice is npm but you can install code directly from GitHub or other git repos.
As an example you can see my module tco that is on npm:
https://www.npmjs.com/package/tco
But also on GitHub:
https://github.com/rsp/node-tco
So you could install it with npm either from the npm Registry or from GitHub:
npm install tco # <-- from npm registry
npm install rsp/node-tco # <-- from github
Additionaly you can use it on the frontend from the CDN available for all code on GitHub:
<script src="https://cdn.rawgit.com/rsp/node-tco/v0.0.12/tco.min.js"></script>
If you want your code available on that CDN as well, see RawGit:
https://rawgit.com/

What is the step-by-step procedure for installing any npm module with Aurelia CLI?

I wanted to install jquery and found instructions here:
http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/contact-manager-tutorial/4
I then wanted to install "moment.js" and found instructions here ( I am not using typescript) :
How to import Moment-Timezone with Aurelia/Typescript
To install both of these with the Aurelia CLI the procedure is to install the respective npm module and then to manually modify aurelia.json in some way so the app recognizes it.
In the case of moments the instructions then say to place an import at the top of app.js , but this is not the case for JQuery.
First off , is there any way the changes to aurelia.json can be automated ( like a regular node.js package.json) so I don't need to manually do it and second, how do I know what modifications I am expected to make to aurelia.json ( or app.js or any other file) for the module I want to install?
With a basic node.js app its pretty simple , just npm install. With Aurelia its much more confusing.
Edit: There is also JSPM which I've read is used for front end libraries like the ones I mentioned above. However, the links with instructions for installation that I posted are not using JSPM.
Edit
I found some of the answers here:
http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/the-aurelia-cli/6
The CLI is still under development. I think the automatic adding of a package might some day be included in the CLI itself, for example with an install command.
The extra registration is required to register the package correctly for usage with RequireJS (http://requirejs.org/). And if the plugin exists of more than just 1 file, this registration is a bit more complex then just adding the name of the plugin.
There is an experimental CLI task here https://github.com/martonsagi/aurelia-cli-pacman that will do the automation for you.
Which can be installed by running:
npm install aurelia-cli-pacman -D
The above will install the package manager and register/ include itself in the tasks in your current project (be sure to run it with install, because npm won't run the post install script if you run it the i shorthand). Next, you can run the following command to install an extension:
npm i aurelia-interactjs -S
au pacman i aurelia-interactjs
The only downside for many might be that currently there aren't that many registry entries, but I think the author of the package would be very happy if you help him out by creating a pull to extend the registry. Would take you some time to figure out what would be the correct install/ import settings, but you will help out someone else and make them happy when they hit the same problem you experience :-).
JSPM has a same sort of issue around this, only is more matured/ the registry is bigger and/ or authors added specific information for JSPM installations to their package.json. For example: To install the above plugin with JSPM it will use the following highlighted section https://github.com/eriklieben/aurelia-interactjs/blob/master/package.json#L72,L86. The same is currently not possible with aurelia-cli, because the installation is done by NPM instead of through JSPM that redirects it to NPM.
If the author of the plugin didn't specify the JSPM section in the package.json, you would most likely and up with the same sort of issues. JSPM has a similar registry (https://github.com/jspm/registry/tree/master/package-overrides/npm) as aurelia-cli-pacman.

Difference between Grunt, NPM, and Bower (package.json vs bower.json)

When I want to add a package (and check in the dependency into git), where does it belong - into package.json or into bower.json?
From what I gather,
running bower install will fetch the package and put it in /vendor directory,
running npm install it will fetch it and put it into /node_modules directory.
This SO answer says bower is for front-end and npm is for backend stuff.
Ember-app-kit seems to adhere to this distinction from the first glance... But instructions in gruntfile for enabling some functionality give two explicit commands, so I'm totally confused here.
Intuitively I would guess that
npm install --save-dev package-name would be equivalent to adding the package-name to my package.json
bower install --save package-name might be the same as adding the package to my bower.json and running bower install?
If that is the case, when should I ever install packages explicitly like that without adding them to the file that manages dependencies (apart from installing command line tools globally)?
Npm and Bower are both dependency management tools. But the main difference between both is npm is used for installing Node js modules but bower js is used for managing front end components like html, css, js etc.
A fact that makes this more confusing is that npm provides some packages which can be used in front-end development as well, like grunt and jshint.
These lines add more meaning
Bower, unlike npm, can have multiple files (e.g. .js, .css, .html, .png, .ttf) which are considered the main file(s). Bower semantically considers these main files, when packaged together, a component.
Edit: Grunt is quite different from Npm and Bower. Grunt is a javascript task runner tool. You can do a lot of things using grunt which you had to do manually otherwise. Highlighting some of the uses of Grunt:
Zipping some files (e.g. zipup plugin)
Linting on js files (jshint)
Compiling less files (grunt-contrib-less)
There are grunt plugins for sass compilation, uglifying your javascript, copy files/folders, minifying javascript etc.
Please Note that grunt plugin is also an npm package.
Question-1
When I want to add a package (and check in the dependency into git), where does it belong - into package.json or into bower.json
It really depends where does this package belong to. If it is a node module(like grunt,request) then it will go in package.json otherwise into bower json.
Question-2
When should I ever install packages explicitly like that without adding them to the file that manages dependencies
It does not matter whether you are installing packages explicitly or mentioning the dependency in .json file. Suppose you are in the middle of working on a node project and you need another project, say request, then you have two options:
Edit the package.json file and add a dependency on 'request'
npm install
OR
Use commandline: npm install --save request
--save options adds the dependency to package.json file as well. If you don't specify --save option, it will only download the package but the json file will be unaffected.
You can do this either way, there will not be a substantial difference.
Update for mid 2016:
The things are changing so fast that if it's late 2017 this answer might not be up to date anymore!
Beginners can quickly get lost in choice of build tools and workflows, but what's most up to date in 2016 is not using Bower, Grunt or Gulp at all! With help of Webpack you can do everything directly in NPM!
Google "npm as build tool" result:
https://medium.com/#dabit3/introduction-to-using-npm-as-a-build-tool-b41076f488b0#.c33e74tsa
Webpack: https://webpack.github.io/docs/installation.html
Don't get me wrong people use other workflows and I still use GULP in my legacy project(but slowly moving out of it), but this is how it's done in the best companies and developers working in this workflow make a LOT of money!
Look at this template it's a very up-to-date setup consisting of a mixture of the best and the latest technologies:
https://github.com/coryhouse/react-slingshot
Webpack
NPM as a build tool (no Gulp, Grunt or Bower)
React with Redux
ESLint
the list is long. Go and explore!
Your questions:
When I want to add a package (and check in the dependency into git),
where does it belong - into package.json or into bower.json
Everything belongs in package.json now
Dependencies required for build are in "devDependencies" i.e. npm install require-dir --save-dev (--save-dev updates your package.json by adding an entry to devDependencies)
Dependencies required for your application during runtime are in "dependencies" i.e. npm install lodash --save (--save updates your package.json by adding an entry to dependencies)
If that is the case, when should I ever install packages explicitly like that without adding them to the file that manages dependencies (apart from installing command line tools globally)?
Always. Just because of comfort. When you add a flag (--save-dev or --save) the file that manages deps (package.json) gets updated automatically. Don't waste time by editing dependencies in it manually. Shortcut for npm install --save-dev package-name is npm i -D package-name and shortcut for npm install --save package-name is npm i -S package-name

Using npm to install or update required packages just like bundler for rubygems

I love Bundler, it's great at dependency management. I love npm, installing node packages is easy! I have a nodejs app and would love to be able to specify my apps dependencies and easily install / update them wherever I deploy my app. This isn't a library I'm releasing, it's a full fledged web-app.
I'm aware of the npm bundle command, but that just seems to simply override the directory where packages are installed.
I'm used to using bundler in this fashion:
# Gemfile
gem "rails", "3.0.3"
Installs rails v3.0.3 and any other required gems on the host machine only if it doesn't already exist
> bundle install
How can I achieve something similar with npm?
As of npm 1.0 (which is now what you get by default if you follow the steps in the README file), "bundle" is no longer a segregated thing -- it's just "how it works".
So:
Put a package.json file in the root of your project
List your deps in that file
{ "name" : "my-project"
, "version" : "1.0.0"
, "dependencies" : { "express" : "1.0.0" } }
npm install Since you're calling this with no args, and not in global mode, it'll just install all your deps locally.
require("express") and be happy.
Edit: This only applies to npm versions < 1.0
It was quite difficult to figure this out, but NPM makes this possible.
You need three components
A subdirectory in your repository (i.e. deps/)
A package.json file in the above directory that lists dependencies
An index.js file in the above directory that requires your dependencies
Example
Imagine that express is your only dependency
deps/package.json
note: Increment the version # each time you modify the dependencies
{
"name": "myapp_dependencies",
"version": "0.0.1",
"engines": {
"node": "0.4.1"
},
"dependencies":{
"express": "2.0.0beta2"
}
}
deps/index.js
export.modules = {
express: require('express')
//add more
}
Now you should be able to install your dependencies using npm. You could even make this part of your deployment process
cd deps
npm install
Then within your app code you can get access to your specific version of express like this:
var express = require('myapp_dependencies').express;
You should read these two articles from Isaacs(author npm) blog. I think they are really good, and I believe tell you how to achieve your goal:
http://blog.izs.me/post/1675072029/10-cool-things-you-probably-didnt-realize-npm-could-do
http://foohack.com/2010/08/intro-to-npm/
I believe link #1(point #11) explains this:
11: Bundle all your dependencies into the package itself
When you use the
npm bundle command, npm will put all
your dependencies into the
node_modules folder in your package.
But it doesn’t stop there.
If you want to depend on something
that’s not on the registry, you can do
that. Just do this:
npm bundle install
http://github.com/whoever/whatever/tarball/master
This will install the contents of that
tarball into the bundle, and then you
can list it as a dependency, and it
won’t try to install it when your
package gets installed.
This also is handy if you have your
own fork of something, and would
prefer not to change the name.
In fact, you can run almost any npm
command at the bundle. To see what’s
inside, you can do npm bundle ls. To
remove something, do npm bundle rm
thing. And, of course, you can install
multiple versions and activate the one
you want.
As of Npm version 1.1.2 , there's a new command npm shrinkwrap which creates an npm-shrinkwrapped.json file, analogous to Gemfile.lock. It's important to make one, to prevent software rot (see Bundler's rationale). Particularly as Nodejs has such a fast moving community.
While bundle install creates a Gemfile.lock automatically, npm install won't create npm-shrinkwrapped.json (but will use it when it exists). Hence you need to remember to use npm shrinkwrap.
Read a full guide at http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/
It seems to me that the simplest solution is to use a package.json file with the private flag (added to npm just last month) set to true. That way, you can run npm install or npm bundle to grab your project's dependencies, but you prevent anyone from accidentally publishing your non-public project.
Here's an example package.json:
{
"name": "yourProject"
,"version": "1.0.0"
,"dependencies": { "express" : ">=2.1.0" }
,"private": true
}
Running npm install will install express on the local system if it doesn't already exist; running npm publish gives an error because of the "private": true.
You and your team can use the version tag internally to track dependency changes over time—each time you change a dependency, bump the version. To see which version you've installed, use npm ls installed.
Publish your app with npm as well, and list its dependencies in your package.json file.
When someone uses npm to install your package, npm will take care of resolving its dependencies.
Packages spec: http://wiki.commonjs.org/wiki/Packages/1.0

Categories