{"id":1055,"date":"2021-03-29T17:19:49","date_gmt":"2021-03-29T15:19:49","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1055"},"modified":"2021-03-29T17:21:24","modified_gmt":"2021-03-29T15:21:24","slug":"why-package-lock-json","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2021\/03\/29\/why-package-lock-json\/","title":{"rendered":"package-lock.json  VS package.json"},"content":{"rendered":"\n<p>When writing JavaScript applications, you describe its dependencies using a\u00a0<code>package.json<\/code>\u00a0file. This file contains all of your applications direct dependencies and their versions.<\/p>\n\n\n\n<p><code>package-lock.json<\/code>\u00a0is automatically generated for any operations where npm modifies either the\u00a0<code>node_modules<\/code>\u00a0tree, or\u00a0<code>package.json<\/code>.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-cyan-blue-color\">Managing Packages<\/span><\/h5>\n\n\n\n<p>npm exists to make managing packages easy. Your projects might have hundreds of dependencies, each of those with a hundred others. To keep your mind away from dependency hell, npm was created so that with some simple commands, you could install and manage these dependencies and hardly ever have to think about them.<\/p>\n\n\n\n<p>let\u00b4s say for example,  you\u2019re building a RESTful API using Express, .Your<strong>\u00a0<code>package.json<\/code><\/strong>\u00a0file will probably list\u00a0<code>express<\/code>\u00a0as a dependency.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n  \"name\": \"my-app\",\r\n  \"version\": \"1.0.0\",\r\n  \"main\": \"index.js\",\r\n  \"dependencies\": {\r\n    \"express\": \"4.0.0\"\r\n  }\r\n}<\/code><\/pre>\n\n\n\n<p>Whenever you ask others to clone and run your application, they need to install its dependencies using\u00a0<code>npm install<\/code>. Doing so will cause them to download the version\u00a0<code>4.0.0<\/code>\u00a0of Express.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/lucasfcosta.com\/assets\/package-lock1.png\" alt=\"An image showing that your application points to the Express pacakge, meaning it depends on it.\"\/><figcaption><em>Your application&#8217;s direct dependency on Express.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>When installing Express, a package upon which your application depends, you will also download all of the packages upon which Express itself depends. Among the packages upon which Express depends, you can find, for example,\u00a0<a href=\"https:\/\/github.com\/pillarjs\/send\"><code>send<\/code><\/a>, a package which provides a\u00a0<a href=\"https:\/\/stackoverflow.com\/questions\/28918845\/what-exactly-does-serving-static-files-mean\">static file server<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/lucasfcosta.com\/assets\/package-lock2.png\" alt=\"Your application points to the Express package, which in turn points to the send package.\"\/><figcaption><em>Express depends on `send`, which causes it to be downloaded when installing your application&#8217;s dependencies<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>Additionally, when installing Express and, consequently,\u00a0<code>send<\/code>, you will have to install the dependencies of\u00a0<code>send<\/code>. Because\u00a0<code>send<\/code>\u00a0depends on\u00a0<a href=\"https:\/\/github.com\/jshttp\/mime-types\"><code>mime-types<\/code><\/a>, , a utility package to handle\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Media_type\">mime-types<\/a>, NPM will install also install\u00a0<code>mime-types<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/lucasfcosta.com\/assets\/package-lock3.png\" alt=\"Your application points to the Express package, which points to the send package, which then points to the mime-types package.\"\/><figcaption><em>The `send` package depends upon `mime-types`<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>The process of recursively downloads all of your packages\u2019 dependencies and the dependencies of those dependencies is what causes your\u00a0<code><strong>node_modules<\/strong><\/code>\u00a0folder to get heavy so quickly.<\/p>\n\n\n\n<p>Even though you only listed<strong>\u00a0<code>express<\/code><\/strong>\u00a0as a dependency, if you check your<strong>\u00a0<code>node_modules<\/code><\/strong>\u00a0folder \u2014 the folder in which NPM stores dependencies \u2014 you will see that there are many more packages there. These packages are not only Express\u2019 dependencies, but also the dependencies of\u00a0<em>all<\/em>\u00a0dependencies.<\/p>\n\n\n\n<p>This dependency download process would be beautiful if it weren\u2019t for the fact that&nbsp;<strong><code>npm install<\/code>&nbsp;doesn\u2019t necessarily install the same dependencies given the same&nbsp;<code>package.json<\/code>&nbsp;file<\/strong>.<\/p>\n\n\n\n<p>Running\u00a0<code>npm install<\/code>\u00a0in the afternoon can cause you to get different dependencies when compared to the\u00a0<code>npm install<\/code>\u00a0your colleague ran in the morning, even though none of you changed the version of Express upon which the application depends, for example.<\/p>\n\n\n\n<pre id=\"tw-target-text\" class=\"wp-block-preformatted\">say it in other words<\/pre>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Let us say it in other words<\/span><\/h5>\n\n\n\n<p>Let\u2019s say we create a new project that is going to use\u00a0<a href=\"https:\/\/expressjs.com\/\">express<\/a>. After running `npm init`, we install express: `npm install express \u2014 save`. with the   version 4.15.4. So \u201cexpress\u201d: \u201c^4.15.4\u201d is added as a dependency within the package.json and that exact version is installed on your machine. Now maybe tomorrow, the maintainers of express release a bug fix, and so the latest version becomes 4.15.5. Then if someone were to want to contribute to your project, they would clone it, and run `npm install.\u2019 Since 4.15.5 is a higher version with the same major version, that is installed for them. We both have express, but we have two different versions. Theoretically, they should still be compatible, but maybe that bugfix affected functionality that we are using, and our application would produce different results when run with express version 4.15.4 compared to 4.15.5.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-cyan-blue-color\">The Goal<\/span><\/h5>\n\n\n\n<p>The purpose of the package-lock is to avoid the situation described above, where installing modules from the same package.json results in two different installs<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-cyan-blue-color\">How\u00a0<code>package-lock.json<\/code>\u00a0solves the unstable dependency problem<\/span><\/h5>\n\n\n\n<p>The\u00a0<code>package-lock.json<\/code>\u00a0file lists your application\u2019s dependencies and the dependencies of all its dependencies. In other words, it describes which version of every single package you have installed. That\u2019s why it\u2019s so much longer than\u00a0<code>package.json<\/code>. Whenever you use\u00a0<code>package-lock.json<\/code>\u00a0to install dependencies, you will get the exact same packages, it doesn\u2019t matter whether you\u2019re installing them now or in a thousand years when we\u2019ll hopefully not be using keyboards anymore.<\/p>\n\n\n\n<p>To install dependencies based on your\u00a0<code><strong>package-lock.json<\/strong><\/code>\u00a0file, you should use<strong>\u00a0<code>npm ci<\/code><\/strong>\u00a0instead of<strong>\u00a0<code>npm install<\/code><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm ci<\/code><\/pre>\n\n\n\n<p>By using&nbsp;<code>npm ci<\/code>&nbsp;you will be able to avoid problems which happen when an application works in your machine, but doesn\u2019t work in someone else\u2019s because they ended up downloading different dependencies due to using&nbsp;<code>npm install<\/code>.<\/p>\n\n\n\n<p>That\u2019s why, whenever running your builds in a\u00a0Continuous integration server, you should install dependencies using<strong>\u00a0<code>npm ci<\/code><\/strong>\u00a0instead of\u00a0<code>npm install<\/code>. Doing so will cause the CI server\u2019s build to run just like it had run in your machine.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h5>Reference:<\/h5>\n\n\n\n<p><a href=\"https:\/\/medium.com\/coinmonks\/everything-you-wanted-to-know-about-package-lock-json-b81911aa8ab8\">https:\/\/medium.com\/coinmonks\/everything-you-wanted-to-know-about-package-lock-json-b81911aa8ab8<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/lucasfcosta.com\/2020\/10\/17\/lockfile-guide.html\">https:\/\/lucasfcosta.com\/2020\/10\/17\/lockfile-guide.html<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/blog.coodoo.io\/fragen-rund-um-die-package-lock-json-e7ff95fe4d6f\">https:\/\/blog.coodoo.io\/fragen-rund-um-die-package-lock-json-e7ff95fe4d6f<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When writing JavaScript applications, you describe its dependencies using a\u00a0package.json\u00a0file. This file contains all of your applications direct dependencies and their versions. package-lock.json\u00a0is automatically generated for any operations where npm modifies either the\u00a0node_modules\u00a0tree, or\u00a0package.json. Managing Packages npm exists to make managing packages easy. Your projects might have hundreds of dependencies, each of those with a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1057,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,5],"tags":[274,273],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1055"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1055"}],"version-history":[{"count":6,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1055\/revisions"}],"predecessor-version":[{"id":1062,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1055\/revisions\/1062"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1057"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}