Скидки до 28% + 2-ая профессия бесплатно и подарки на 50 000₽

Главная | Все статьи | Код

Совершенный код: поддержка кроссплатформенности

Время чтения статьи ~4 минуты 60
Совершенный код: поддержка кроссплатформенности главное изображение

Кроссплатформенность — способность программы запускаться на разных платформах, например, разных операционных системах. Это довольно важное качество для программ, которые нужно запускать и в Windows, и в Linux. Причем как со стороны пользователей (все хотят кроссплатформенный фотошоп), так и со стороны разработчиков. Последнее часто встречается в веб-разработке, где часть команды может использовать одну операционную систему, а часть — другую.

Кроссплатформенность программы зависит от разработчиков. В статье мы разберем несколько типичных ошибок программистов, которые ухудшают кроссплатформенность или вообще убирают ее.

Подписывайтесь на канал Кирилла Мокевнина в Telegram — чтобы узнать больше о программировании и профессиональном пути разработчика

Современные высокоуровневые языки изначально кроссплатформенны. Они прячут различия в операционных системах за готовыми абстракциями. Например, чтение и запись файлов внутри этих языков не зависит от того, где запускается код:

import fs from 'fs';

// Не забывайте что абстракции текут, в определенных моментах различия все же есть
fs.readFileSync('filename');

Но есть определенные вещи, которые спрятать нельзя, и программисту приходится работать с ними напрямую. Возьмем для примера разделитель директорий. В Windows это \ обратный слеш (backslash), в Linux – / прямой слеш или просто слеш. Какой использовать? Попробуем разобраться.

Разделитель директорий

Во многих языках пытаются упростить эту задачу, добавляя специальные идентификаторы (переменные, константы), содержащие символы, специфичные для конкретной операционной системы. В зависимости от того, где запускается программа, значение этих идентификаторов может отличаться. В JavaScript это работает так:

import path from 'path';

console.log(path.sep);
// В Linux: /
// В Macos: /
// В Windows: \

path.join('one', 'two', 'three');
// Внутри делает ['one', 'two', 'three'].join(path.sep);
// В Linux: one/two/three
// В Macos: one/two/three
// В Windows: one\two\three

Решение кажется очевидным: достаточно начать использовать path.sep в тех местах, где идет работа с путями, и вопрос исчерпан. Да, для подавляющего большинства ситуаций такой ход сработает, но не для всех. Представьте, что наша программа должна формировать конфигурационный json-файл, внутри которого есть пути:

{
    "manifest": "public/assets/manifest.json"
}

Затем этот файл будет использоваться на самом сайте (в продакшене). В подавляющем большинстве случаев продакшен (место, где запускается сайт) работает на Linux. Это значит, что если файл был сформирован в Windows-среде, то он не заработает в Linux-среде, так как Linux не понимает обратные слеши (как и MacOS). Что делать в этой ситуации?

Секрет в том, что Windows понимает и обратный, и прямой слеш, а это значит, что кроссплатформенность в данном случае обеспечивается только при использовании прямых слешей. Поэтому лучше отказаться от использования path.sep, и в тех местах, где формируются пути, использовать прямой слеш. С другой стороны, не нужно сражаться с функциями типа path.join, как в примере выше. Пусть они используют path.sep внутри себя, зато мы получаем удобный способ работы с путями.

Перевод строки

Другой пример — перевод строки. В большинстве операционных систем для перевода строк используется \n, но только не в Windows. Там по историческим причинам перевод строки — это \r\n. И это уже действительно проблема, потому что касается не только того, как работает код, но и в принципе самого исходного кода. Каждый файл, который сохраняется в Windows, будет сохраняться с \r\n в конце каждой строки. Это приводит к куче разных проблем:

  • появляются различные артефакты при выводе данных;
  • сходит с ума гит и редактор;
  • усложняется отладка тестов, так как данные визуально выглядят одинаково, но не совпадают при сравнении.

С этими и другими проблемами сталкиваются все разработчики без исключения, которые работают в командах, разрабатывающих код на разных платформах. Для решения этих проблем есть два подхода. Первый — использовать перевод строки конкретной операционной системы:

import os from 'os';

console.log(os.EOL);
// В Linux: \n
// В Macos: \n
// В Windows: \r\n

Как раз этот подход приводит к проблемам, указанным выше.

Второй подход — всегда использовать \n. Ситуация здесь аналогична разделителю директорий. \n — универсальный символ, одинаково хорошо работает и в Windows, и в остальных операционных системах:

lines = ['one', 'two', 'three'];
const text = lines.join('\n');
// one
// two
// three

Но это еще не все. В обязательном порядке нужно правильно настроить и редакторы, и гит. Только после этого можно начинать говорить о кроссплатформенности.

Дополнительные материалы:

Аватар пользователя Kirill Mokevnin
Kirill Mokevnin 06 марта 2020
60
Похожие статьи
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Тестирование веб-приложений, чек-листы и тест-кейсы, этапы тестирования, DevTools, Postman, SQL, Git, HTTP/HTTPS, API
4 месяца
с нуля
Старт 26 декабря
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Google таблицы, SQL, Python, Superset, Tableau, Pandas, визуализация данных, Anaconda, Jupyter Notebook, A/B-тесты, ROI
9 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на PHP, Разработка веб-приложений и сервисов используя Laravel, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Ruby, Разработка веб-приложений и сервисов используя Rails, проектирование и реализация REST API
5 месяцев
c опытом
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript, разработка веб-приложений, bff и сервисов используя Fastify, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Git, JavaScript, Playwright, бэкенд-тесты, юнит-тесты, API-тесты, UI-тесты, Github Actions, HTTP/HTTPS, API, Docker, SQL
8 месяцев
c опытом
Старт 26 декабря