For more than ten years I have been a PHP developer, but recently switched to JavaScript using its server and client capabilities. Before that, I was already familiar with JS. First I worked with jQuery, then I mastered Angular, and, finally, I started using React.
When I started writing in PHP, I embedded it in HTML files. It turned out not a code, but a complete mess. Therefore, in order to bring my development to a decent look, I began to use frameworks, in particular, ZF1 and ZF2. After a while, an approach that starts developing from an API when I use it, led to the fact that I had a server consisting of generated REST APIs and several hundred lines of my own code.

')
Since only a small and not the most important part of our projects was written in PHP, the question arose whether we could get rid of it. And, if we can, what it will cost us, and what we will get from it. In this article I will share the experience with those who, like me, want, understanding what and why he does, to leave the world of PHP and get under the banner of JavaScript in all its manifestations.
Today I will mainly tell about my journey from the server side of PHP to the server side of JS in the form of Node.js. Here I will not talk about Webpack, React and other JS client technologies.
Evolution of technology stack
Let's start with a general scheme that describes the evolution of the stack of technologies used by us during the transition from PHP to Node.js.
Major changes in the technology stack we useNode.js is the main component of our new set of technologies. It has high performance.
Node.js does its job so well that for a variety of tools previously written in low-level languages, there are now JavaScript equivalents. Installing the usual programs for the platforms we used was so time consuming that we had to use Ansible to deploy the working environment. Since the new tools now depend only on Node.js, the only thing we have to install on our own is
NVM (Node Version Manager) - a tool designed to install Node.js.
How to install Node.js correctly using NVM
When we installed Node.js manually, or using the operating system's package manager, this quickly created a lot of problems when trying to switch between Node versions. As a result, we came to the use of NVM.
This tool is very easy to install and use:
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash nvm install node nvm use v6.9.1
After its installation, the following features became available to us:
- Install different versions of Node.js on the same system using the same command.
- Conveniently switch between installed versions of Node.js.
Besides, which is especially nice, NVM runs on Linux, on Mac, and on
Windows .
JavaScript in 2017
Starting to learn JavaScript, I perceived it as a second-rate language, without which, “unfortunately, I can't do” when creating dynamic websites. As a result, I never tried to figure it out properly. I taught javascript mainly in blog posts and yes in response to Stack Owerflow. Now I regret it.
Teach materiel!I was not ready to start using modern frameworks and JavaScript tools. In 2017, JavaScript has become completely different due to new features. Among them are the following:
- Classes.
- Promises (now embedded in the language).
- Unstructured and expanded operators.
- Modules and module loaders.
- Map / Set structures and their variants with weak links.
- Async / Await.
In the end, I took the time to work out a lot of material and how to learn JavaScript. For example, the site
Babeljs.io gave me a wonderful overview of what modern JavaScript programming is.
Switch from Composer to Yarn
Composer is a great, but slow tool. NPM has the same flaw, so we chose
Yarn instead. It is the fastest alternative to NPM.
In the past, we had about a thousand dependencies. The development team consists of 10 people, the
node_modules
folder
node_modules
changed at least 2 times a day. Let us estimate how long it will take to install the packages in two months according to the following formula:
(10 developers + 3 environments) * 2 installations per day * 60 days * 3 minutes for installation = 78 hours.
It turns out that two weeks of working time was spent on monitoring the progress of loading packages and reading Reddit. Three minutes is a long enough period of time, which can result in large losses, but too short, so that, while the installation is in progress, it would be possible to switch to some other task.
Thanks to Yarn, we managed to reduce the installation time from 3 minutes to one minute. This saved 46 hours of work time. And, I will tell you, this is an excellent result.
Creating API in JavaScript
Perhaps, instead of telling about it myself, I will give the word to the code. Here is a minimal API example based on the following packages:
- Express is the lightweight JS equivalent of Zend Frameword 2 / Symfony.
- Sequelize is an alternative to Doctrine.
- Epilogue is an alternative to Apigility.
const Sequelize = require('sequelize'), epilogue = require('epilogue'), express = require('express'), bodyParser = require('body-parser'); // Sequelize // - Doctrine let database = new Sequelize('database', 'root', 'password'); let User = database.define('User', { username: Sequelize.STRING }); // Express let app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // Epilogue Express epilogue.initialize({ app: app, sequelize: database }); // , Epilogue, REST let userResource = epilogue.resource({ model: User, endpoints: ['/users', '/users/:id'] }); // , User GET/POST DELETE. app.listen(() => { console.log('Server started!'); });
A few lines of code - and we have a REST API that is configurable and extensible.
After we created more than 50 API endpoints with Apigility, we understood two things. Firstly - it is possible, secondly - effectively.
For example, Epilogue easily generates 10 endpoints. It is also possible to connect your own code to a standard framework to support complex conditions, such as user rights. What cannot be automatically generated is created as simple Express RPC endpoints using Sequelize.
I do not argue with the fact that Zend Framework 2 has much greater capabilities than Express. But Express turned out to be an economical and simple solution, which was enough for all our needs. In the transition to it, we did not have to give up anything.
Flow: a lifeline for those who drowned in a sea of ​​data types
In PHP, it was possible to add hints of data types only when it was needed. This is one of my favorite PHP features. There is a powerful but flexible type system.
<?php class UserService { public function createUser(string $name, User $parent = null, $isAdmin) : User { $user = new User($name); ... return $user } }
For many years I thought that something like this in JS is impossible, that the only way out is to switch to TypeScript. However, I was wrong.
I discovered the Flow library, also known as the
Flow-type , and was able to easily add type information to my JS texts.
Installing the Flow library is easy:
yarn add
It is also easy to connect it by adding one line of code to the top of the files that need to be controlled:
Then the
flow check
command allows you to get a report based on the derived types.
If your project uses a transpiler like Babel, you can add new rules to support Flow type prompts in JS. As a result, it will be possible to work with types as conveniently as in PHP.
Flow TipsServer downfall and monitoring with PM2
In the PHP world, a script failure means a raw request. In the case of Node.js, if the server crashes, the entire website ceases to function. Therefore, processes need to be monitored.
In search of a good monitoring system, we switched from
Supervisord to its rival written in JavaScript. Here he is:
→
PM2 (Process Manager 2)I like PM2 so much that I just can’t help myself from inserting a couple of hearts here.
PM2 can be installed using Yarn, which is very good in itself, but PM2 itself has a lot of strengths. So, in terms of features, it surpasses Supervisord. He is able to track the load that each process creates on the system, and the memory occupied by the process, it can be configured so that it restarts processes when their code changes.
The pm2 list command displays information about all PM2 managed processes.The
pm2 monit
provides a detailed report on what is happening with each process in real time. In addition, PM2 simplifies logging, since we can, without additional efforts, use standard
console.log()/.warn()/.error()
commands.
PM2 visualizes service output and can track user defined metrics.I will say more. While the scope of Supervisord features is limited to process management, PM2 can replace some of the scripts used for project deployment with simple configuration files:
Configuration file that allows you to conveniently describe and deploy processesPM2 for me is one of the most important advantages of switching to JavaScript. In addition, we can use it for projects written in any language, the only negative - in such cases, there is no integration as close as when working with projects based on JS.
Configuring projects with .env
In our projects,
Phing was used to solve three problems:
- Configuring the project.
- Scripting
- Storage of useful commands.
In the JavaScript world, configuration tasks can be solved using the excellent
DotEnv library and
.env
files. The library allows you to use environment variables to customize the application. This is one of the recommended tricks from
The Twelve-Factor App methodology that we use on an ongoing basis.
Those tasks that were solved thanks to Phing's scripting capabilities no longer require us to use special tools. Previously, all of our scripts were either tied to configuring software outside of the PHP world, such as Supervisord, or could be designed as independent command line scripts.
As a result, the only role Phing could play is to store commands and create abbreviations for them. This task is perfectly solved by Yarn (or NPM):
{ "name": "my project name", "...": "...", "scripts": { "release": "standard-version", "db-reset": "rm -rf data/main.db && sequelize db:migrate && sequelize db:seed:all", "db-migrate": "sequelize db:migrate", "dev": "pm2 delete all; pm2 startOrReload ecosystem.config.js && pm2 start react-scripts --name web -- start", "start": "pm2 startOrReload ecosystem.config.js", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "flow": "flow" } }
As a result, we were able to completely get rid of Phing and call our teams in the following way:
yarn run db-migrate
Find and use a good open source editor
Developing in PHP, I used PhpStorm, a paid IDE, as those that were distributed for free, either seemed slow or suffered from a lack of plug-ins.
In the JavaScript world, the choice of decent code editors is much richer. We stopped at
VS Code . This editor is written in JavaScript and is supported by a community of enthusiasts and Microsoft.
VS Code logoUntil now, everything in VS Code we like. It works fast, it has a wonderful code completion system, and there is an excellent community behind it.
Here I really like the opportunity to ask which plugins to use in the project, and share configurations. Thanks to it, you can prepare the workplace of the programmer in just a couple of clicks.
Getting rid of hand linting with Prettier
In PHP, we had one great thing. These are
PSR standards. These standards are really useful when preparing code design rules.
We set up our IDEs so that the code conforms to PSR 1 and 2 standards. Since there was no auto fix function, everyone was responsible for applying them independently. It was not so good.
When switching to JavaScript, Prettier has become an invaluable assistant in this area. Prettier is a rule-based code formatter. It, with each save the file, removes all amateur styling and leads the code to the form corresponding to a single style.
Prettier in actionAs a result, there are no more arguments about the style of the code, no training in this area, no time wasted for merging files in which only the formatting is modified.
Everyone on the team uses and loves Prettier. Programmers do their job, and Prettier is responsible for the formatting details.
Results
Consider the pros and cons that we encountered during the transition from PHP to JS:
Pros:- Our stack is easier to install and deploy.
- Client and server code is written in the same language.
- We no longer rely on complex installation scripts.
Minuses:- It took a lot of effort to create a set of technologies that meet our needs.
- I had to organize a lot of trainings in order to learn modern JavaScript programming.
It should be noted that after the transition, we were able to quickly generate server APIs. This is similar to what we did in PHP. I do not regret anything after the transition and I feel that I have not lost anything. All the tools we switched to are either equivalent to the ones we used earlier, or better than them.
If you are thinking about switching from PHP to JS, we wish you success and hope that our story will help you navigate the world of JS and choose exactly what you need.
Dear readers! If you use PHP, please tell us how you live, do you plan to switch to JavaScript?