The second of a 12 part series on how to use Twelve-Factor App in practice. This entry is written in collaboration with my good friend and (twice/double) former coworker Mycha de Vrees.
We will be implementing https://12factor.net/dependencies based on my/our combined experience on how to deal with dependencies.
The takeaway of this post is defined your dependencies as specify as strict as possible. Yes, in most cases pinning major and minor version should be enough but pinning the patch version should make sure of this.
Language | Package manager |
---|---|
Go | dep |
NodeJS | npm / yarn |
PHP | Composer |
Python | PIP |
Ruby | Bundler |
Python
Python uses a requirements.txt
file which is managed by PIP
Installing PIP
curl --silent --show-error https://bootstrap.pypa.io/get-pip.py | sudo python
# Specific version of python
curl --silent --show-error https://bootstrap.pypa.io/get-pip.py | sudo python2
curl --silent --show-error https://bootstrap.pypa.io/get-pip.py | sudo python3
curl --silent --show-error https://bootstrap.pypa.io/get-pip.py | sudo python3.6
More on install options can be found at https://pip.pypa.io/en/stable/installing/
Listing installed
Listing all installed versions is done with pip freeze
Please note that this is not advised outside of a virtual environment. For example; you’ll have
docker-compose
installed (via pip) globally, handy tool, but not specific to a project and not a dependency of your working project. Running pip globally, i.e. outside of a specific environment will include such tools in your requirements.
pip freeze > requirements.txt
Requirements.txt
Below is a short example external links are based on Git, a full list can be found at https://pip.readthedocs.io/en/1.1/requirements.html#requirements-file-format
# default
MyPackage
# pinned version options
MyPackage==3.0
MyPackage>=3.0
MyPackage<=4.0
MyPackage>=3.0<=4.0
#
MyPackage==3.0 [PDF]
# GIT
-e git://git.myproject.org/MyProject.git#egg=MyProject
-e git+http://git.myproject.org/MyProject/#egg=MyProject
-e git+ssh://git@myproject.org/MyProject/#egg=MyProject
# GIT - Specific branch/tag/commit
-e git://git.myproject.org/MyProject.git@master#egg=MyProject
-e git://git.myproject.org/MyProject.git@v1.0#egg=MyProject
-e git://git.myproject.org/MyProject.git@da39a3ee5e6b4b0d3255bfef95601890afd80709#egg=MyProject
NodeJS
NodeJS uses NPM (or Yarn) to manage dependencies, this is done via package.json
to define it and package-lock.json
to pin it.
package.json vs package-lock.json
The major difference, in short, is that package.json
allows version ranges, ^, >=, <=, and package-lock.json
pins it to a specific version.
Lets say I have a requirement with version ^5.1.0 and next week 5.1.1 is released package.json
allows us to both multiple version
while package-lock.json
will make sure person A this week will install the same version as person B next week.
The lock file will be generated by npm install
if it is not present.
npm
npm is a package manager for the JavaScript programming language. It is the default package manager for the JavaScript runtime environment Node.js.
yarn
Yarn is an alternative to the default npm manager. Yarn is created by Facebook due to issues with consistency, security and speed.
package.json example
Within the file, amongst a lot of other things, you’ll find the following; dependencies and devDependencies the difference should be fairly simple.
Dependencies for stuff you need in the final product / in production, devDependencies for the rest of the stuff you need while developing (and/or testing).
{
"dependencies": {
"vue": "^2.5.2"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1"
}
}