HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Кроссплатформенность - способность программы запускаться на разных платформах, например, разных операционных системах. Это довольно важное качество для программ, которые нужно запускать и в Windows, и в Linux. Причем как со стороны пользователей (все хотят кроссплатформенный фотошоп), так и со стороны разработчиков. Последнее часто встречается в веб-разработке, где часть команды может использовать одну операционную систему, а часть - другую.</p>
1 <p>Кроссплатформенность - способность программы запускаться на разных платформах, например, разных операционных системах. Это довольно важное качество для программ, которые нужно запускать и в Windows, и в Linux. Причем как со стороны пользователей (все хотят кроссплатформенный фотошоп), так и со стороны разработчиков. Последнее часто встречается в веб-разработке, где часть команды может использовать одну операционную систему, а часть - другую.</p>
2 <p>Кроссплатформенность программы зависит от разработчиков. В статье мы разберем несколько типичных ошибок программистов, которые ухудшают кроссплатформенность или вообще убирают ее.</p>
2 <p>Кроссплатформенность программы зависит от разработчиков. В статье мы разберем несколько типичных ошибок программистов, которые ухудшают кроссплатформенность или вообще убирают ее.</p>
3 <blockquote><p>Подписывайтесь на<a>канал Кирилла Мокевнина в Telegram</a>- чтобы узнать больше о программировании и профессиональном пути разработчика</p>
3 <blockquote><p>Подписывайтесь на<a>канал Кирилла Мокевнина в Telegram</a>- чтобы узнать больше о программировании и профессиональном пути разработчика</p>
4 </blockquote><p>Современные высокоуровневые языки изначально кроссплатформенны. Они прячут различия в операционных системах за готовыми абстракциями. Например, чтение и запись файлов внутри этих языков не зависит от того, где запускается код:</p>
4 </blockquote><p>Современные высокоуровневые языки изначально кроссплатформенны. Они прячут различия в операционных системах за готовыми абстракциями. Например, чтение и запись файлов внутри этих языков не зависит от того, где запускается код:</p>
5 <p>Но есть определенные вещи, которые спрятать нельзя, и программисту приходится работать с ними напрямую. Возьмем для примера разделитель директорий. В Windows это \ обратный слеш (backslash), в Linux - / прямой слеш или просто слеш. Какой использовать? Попробуем разобраться.</p>
5 <p>Но есть определенные вещи, которые спрятать нельзя, и программисту приходится работать с ними напрямую. Возьмем для примера разделитель директорий. В Windows это \ обратный слеш (backslash), в Linux - / прямой слеш или просто слеш. Какой использовать? Попробуем разобраться.</p>
6 <h2>Содержание</h2>
6 <h2>Содержание</h2>
7 <ul><li><a>Разделитель директорий</a></li>
7 <ul><li><a>Разделитель директорий</a></li>
8 <li><a>Перевод строки</a></li>
8 <li><a>Перевод строки</a></li>
9 <li><a>Дополнительные материалы:</a></li>
9 <li><a>Дополнительные материалы:</a></li>
10 </ul><h2>Разделитель директорий</h2>
10 </ul><h2>Разделитель директорий</h2>
11 <p>Во многих языках пытаются упростить эту задачу, добавляя специальные идентификаторы (переменные, константы), содержащие символы, специфичные для конкретной операционной системы. В зависимости от того, где запускается программа, значение этих идентификаторов может отличаться. В JavaScript это работает так:</p>
11 <p>Во многих языках пытаются упростить эту задачу, добавляя специальные идентификаторы (переменные, константы), содержащие символы, специфичные для конкретной операционной системы. В зависимости от того, где запускается программа, значение этих идентификаторов может отличаться. В JavaScript это работает так:</p>
12 <p>Решение кажется очевидным: достаточно начать использовать path.sep в тех местах, где идет работа с путями, и вопрос исчерпан. Да, для подавляющего большинства ситуаций такой ход сработает, но не для всех. Представьте, что наша программа должна формировать конфигурационный json-файл, внутри которого есть пути:</p>
12 <p>Решение кажется очевидным: достаточно начать использовать path.sep в тех местах, где идет работа с путями, и вопрос исчерпан. Да, для подавляющего большинства ситуаций такой ход сработает, но не для всех. Представьте, что наша программа должна формировать конфигурационный json-файл, внутри которого есть пути:</p>
13 <p>Затем этот файл будет использоваться на самом сайте (в продакшене). В подавляющем большинстве случаев продакшен (место, где запускается сайт) работает на Linux. Это значит, что если файл был сформирован в Windows-среде, то он не заработает в Linux-среде, так как Linux не понимает обратные слеши (как и MacOS). Что делать в этой ситуации?</p>
13 <p>Затем этот файл будет использоваться на самом сайте (в продакшене). В подавляющем большинстве случаев продакшен (место, где запускается сайт) работает на Linux. Это значит, что если файл был сформирован в Windows-среде, то он не заработает в Linux-среде, так как Linux не понимает обратные слеши (как и MacOS). Что делать в этой ситуации?</p>
14 <p>Секрет в том, что Windows понимает и обратный, и прямой слеш, а это значит, что кроссплатформенность в данном случае обеспечивается только при использовании прямых слешей. Поэтому лучше отказаться от использования path.sep, и в тех местах, где формируются пути, использовать прямой слеш. С другой стороны, не нужно сражаться с функциями типа path.join, как в примере выше. Пусть они используют path.sep внутри себя, зато мы получаем удобный способ работы с путями.</p>
14 <p>Секрет в том, что Windows понимает и обратный, и прямой слеш, а это значит, что кроссплатформенность в данном случае обеспечивается только при использовании прямых слешей. Поэтому лучше отказаться от использования path.sep, и в тех местах, где формируются пути, использовать прямой слеш. С другой стороны, не нужно сражаться с функциями типа path.join, как в примере выше. Пусть они используют path.sep внутри себя, зато мы получаем удобный способ работы с путями.</p>
15 <h2>Перевод строки</h2>
15 <h2>Перевод строки</h2>
16 <p>Другой пример - перевод строки. В большинстве операционных систем для перевода строк используется \n, но только не в Windows. Там по историческим причинам перевод строки - это \r\n. И это уже действительно проблема, потому что касается не только того, как работает код, но и в принципе самого исходного кода. Каждый файл, который сохраняется в Windows, будет сохраняться с \r\n в конце каждой строки. Это приводит к куче разных проблем:</p>
16 <p>Другой пример - перевод строки. В большинстве операционных систем для перевода строк используется \n, но только не в Windows. Там по историческим причинам перевод строки - это \r\n. И это уже действительно проблема, потому что касается не только того, как работает код, но и в принципе самого исходного кода. Каждый файл, который сохраняется в Windows, будет сохраняться с \r\n в конце каждой строки. Это приводит к куче разных проблем:</p>
17 <ul><li>появляются различные артефакты при выводе данных;</li>
17 <ul><li>появляются различные артефакты при выводе данных;</li>
18 <li>сходит с ума гит и редактор;</li>
18 <li>сходит с ума гит и редактор;</li>
19 <li>усложняется отладка тестов, так как данные визуально выглядят одинаково, но не совпадают при сравнении.</li>
19 <li>усложняется отладка тестов, так как данные визуально выглядят одинаково, но не совпадают при сравнении.</li>
20 </ul><p>С этими и другими проблемами сталкиваются все разработчики без исключения, которые работают в командах, разрабатывающих код на разных платформах. Для решения этих проблем есть два подхода. Первый - использовать перевод строки конкретной операционной системы:</p>
20 </ul><p>С этими и другими проблемами сталкиваются все разработчики без исключения, которые работают в командах, разрабатывающих код на разных платформах. Для решения этих проблем есть два подхода. Первый - использовать перевод строки конкретной операционной системы:</p>
21 <p>Как раз этот подход приводит к проблемам, указанным выше.</p>
21 <p>Как раз этот подход приводит к проблемам, указанным выше.</p>
22 <p>Второй подход - всегда использовать \n. Ситуация здесь аналогична разделителю директорий. \n - универсальный символ, одинаково хорошо работает и в Windows, и в остальных операционных системах:</p>
22 <p>Второй подход - всегда использовать \n. Ситуация здесь аналогична разделителю директорий. \n - универсальный символ, одинаково хорошо работает и в Windows, и в остальных операционных системах:</p>
23 <p>Но это еще не все. В обязательном порядке нужно правильно настроить и редакторы, и гит. Только после этого можно начинать говорить о кроссплатформенности.</p>
23 <p>Но это еще не все. В обязательном порядке нужно правильно настроить и редакторы, и гит. Только после этого можно начинать говорить о кроссплатформенности.</p>
24 <h2>Дополнительные материалы:</h2>
24 <h2>Дополнительные материалы:</h2>
25 <ul><li><a>Библиотека или своё решение</a></li>
25 <ul><li><a>Библиотека или своё решение</a></li>
26 </ul>
26 </ul>