Основным преимуществом использования Apache Cordova для создания приложений является то, что он предоставляет решение «напиши один раз, запусти много» для повторного использования логики и дизайна приложения на поддерживаемых мобильных платформах.

Это замечательно, если мы хотим создать приложение с примерно одинаковым макетом, внешним видом, ощущениями и функциональностью на всех целевых платформах. Однако это не всегда то, что мы хотим делать, поскольку каждая платформа имеет свои собственные идиомы и нормы, которым пользователи ожидают, что наше приложение будет соответствовать, или мы можем пожелать использовать специфические для платформы цветовые схемы, текст или графику по другим причинам.

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

Интерфейс командной строки Cordova предлагает здесь часто упускаемый из виду механизм, называемый слияниями. Эта функция работает независимо от внешней среды JavaScript, которую мы выбираем для нашего проекта, поскольку она встроена в сам инструмент Cordova. Он работает путем объединения набора ресурсов для конкретной платформы (который может быть любой комбинацией CSS, JavaScript, изображений, файлов JSON и т. Д.) С содержимым папки www нашего проекта при сборке для каждой платформы.

Давайте посмотрим, как это работает, изменив шаблон Cordova / приложение Hello World, чтобы приспособить его для разных платформ.

В этом примере мы будем использовать Cordova 6 на Mac с установленными последними версиями Xcode и Android SDK. Если вы хотите следовать инструкциям и вам необходимо настроить их на своем компьютере, в документации Cordova есть отличные инструкции для этого.

Создание приложения Boilerplate Cordova

Для начала нам нужно создать стандартное приложение Cordova для iOS и Android. Это очень просто сделать с помощью терминала и Cordova CLI:

cordova create testapp com.moduscreate.testapp TestApp
cd testapp
cordova platform add ios android --save

По завершении мы должны увидеть структуру каталогов приложения верхнего уровня и файл config.xml:

ls -lF

Должен вывести что-то похожее на:

total 8
-rw-r--r-- 1 simon staff 1071 Mar 17 21:47 config.xml
drwxr-xr-x 3 simon staff  102 Mar 17 21:47 hooks/
drwxr-xr-x 5 simon staff  170 Mar 17 21:47 platforms/
drwxr-xr-x 6 simon staff  204 Mar 17 21:47 plugins/
drwxr-xr-x 6 simon staff  204 Mar 17 21:47 www/

Объем нашего демонстрационного приложения

Если бы мы немедленно создали шаблонное приложение, созданное для нас Cordova CLI, оно бы выглядело так как на iOS, так и на Android:

Чтобы продемонстрировать, как использовать слияния в Кордове, мы изменим шаблонное приложение, внося следующие изменения:

  • Измените цвет фона области «УСТРОЙСТВО ГОТОВО» с помощью CSS для конкретной платформы.
  • Измените сообщение «APACHE CORDOVA», используя JavaScript для конкретной платформы.
  • Измените изображение логотипа Cordova, добавив файлы изображений для конкретной платформы

Мы могли бы достичь всего этого, используя плагин Cordova Device, некоторые дополнительные классы CSS в существующем стандартном файле CSS и добавив немного кода, подобного следующему:

if (device.platform === 'Android') {
  // Android specific code
} else {
  // iOS specific, assuming we are only supporting iOS
}

В этом нет необходимости и не будет хорошо масштабироваться, если мы добавим больше платформ: нам нужно будет использовать операторы switch с одним регистром для каждой поддерживаемой платформы, возможно, в нескольких местах в коде приложения. Здесь в игру вступает концепция слияний.

Работа с слияниями

Слияние обеспечивает более элегантный способ специализации внешнего вида, поведения и поведения нашего приложения для каждой платформы, не загрязняя код JavaScript приложения.

Концепция проста - CLI Кордовы знает, что нужно искать каталог проекта верхнего уровня, называемый «слияниями» (в том же каталоге, что и «config.xml»). Внутри «слияния» интерфейс командной строки будет искать каталог с тем же именем, что и создаваемая платформа («android», «ios» и т. Д.). Структура каталогов внутри «merges / ‹platformname›» должна затем отражать структуру папки «www» нашего приложения для файлов, которые мы хотим заменить эквивалентами для конкретной платформы во время сборки. Мы также можем добавлять новые файлы для конкретной платформы, создавая новые пути и / или файлы в «merges / ‹platformname›», которых нет в «www».

Интерфейс командной строки поместит результат слияния деревьев каталогов «www» и «merges / ‹platformname›» нашего приложения в папку «www» платформы, которую мы создаем. Для Android это:

platforms/android/assets/www/…

А для iOS это:

platforms/ios/www/…

Лучше всего это изучить на примере, поэтому давайте изменим наше стандартное приложение, как описано ранее, заменив некоторые стандартные CSS, JavaScript и изображения версиями для конкретной платформы.

По умолчанию интерфейс командной строки Cordova больше не создает каталог верхнего уровня «слияния» при создании нового проекта. Давайте создадим один подкаталог для каждой платформы, поддерживаемой нашим приложением, и отразим структуру каталогов стандартного приложения в каждом:

mkdir -p merges/{android,ios}/{css,js,img}

Теперь убедитесь, что у нас есть ожидаемая структура:

find merges

который должен выводить:

merges
merges/android
merges/android/css
merges/android/img
merges/android/js
merges/ios
merges/ios/css
merges/ios/img
merges/ios/js

Теперь нам нужно добавить контент для конкретной платформы в каждый из «листьев» этой новой структуры каталогов.

Слияния для платформы Android

Чтобы сделать наше приложение более специализированным при запуске на Android, давайте продолжим и добавим CSS для Android.

Чтобы это отображалось только на Android, нам нужно создать новый файл «platform.css» по адресу:

merges/android/css/platform.css

В котором мы переопределим некоторые стили для приложения Cordova по умолчанию:

/* This is Android platform.css */
.event.received {
  background-color: #FF0000;
}

Вышеупомянутое изменит цвет фона области «УСТРОЙСТВО ГОТОВО» на красный после запуска события «устройство готово».

Мы установим текст «APACHE CORDOVA» на определенную платформу, заставив JavaScript приложения извлекать из общего объекта, который каждая платформа будет реализовывать по-разному. Для этого создадим «merges / android / js / platform.js», содержащий следующее:

/* This is Android platform.js */
var platformConstants = {
  appFullName: 'Modus Create for Android'
}

Затем, наконец, мы представим новое изображение, которое заменит шаблонный «logo.png», сохранив следующее в «merges / android / img / logo.png».

Слияния для платформы iOS

Теперь нам нужно повторить процесс, который мы только что завершили для «merges / android» в «merges / ios». Для iOS мы сделаем фон «УСТРОЙСТВО ГОТОВО» синим, добавив «merges / ios / css / platform.css», содержащий:

/* This is iOS platform.css */
.event.received {
  background-color: #0000FF;
}

И мы реализуем тот же объект JavaScript с тем же именем ключа, что и для Android, только с другим значением, добавив «merges / ios / js / platform.js», который содержит:

/* This is iOS platform.js */
var platformConstants = {
  appFullName: 'iOS App by Modus Create'
}

Наконец, мы добавим изображение логотипа для iOS как «merges / ios / img / logo.png»:

На этом настройка дерева каталогов «слияния» завершена. Наша структура каталогов теперь должна выглядеть так:

find merges

Вывод:

merges
merges/android
merges/android/css
merges/android/css/platform.css
merges/android/img
merges/android/img/logo.png
merges/android/js
merges/android/js/platform.js
merges/ios
merges/ios/css
merges/ios/css/platform.css
merges/ios/img
merges/ios/img/logo.png
merges/ios/js
merges/ios/js/platform.js

Затем нам нужно обновить наше приложение, чтобы оно ссылалось на новые файлы, и предоставить реализации по умолчанию на тот случай, если мы хотим запустить приложение в браузере за пределами Кордовы. В настоящее время мы получим ошибку загрузки файла в консоли браузера, потому что в папке «www» нет «platform.css» или «platform.js», поэтому открываем «www / index.html» в браузере. вызовет некоторые проблемы.

Адаптация приложения Cordova Boilerplate

Прежде чем мы сможем создать и протестировать наши новые специфичные для платформы CSS, JavaScript и изображения, нам нужно внести несколько изменений в шаблонное приложение, которое Cordova сгенерировала для использования наших недавно созданных файлов слияния.

Поскольку мы представляем новый файл CSS, нам нужно отредактировать www / index.html и добавить ссылку на эту таблицу стилей в ‹head› документа HTML:

<head>
  …
  <link rel="stylesheet" type="text/css" href="css/index.css">
  <!-- Added to demonstrate merges -->
  <link rel="stylesheet" type="text/css" href="css/platform.css">
  …
</head>

Также в «www / index.html» нам нужно будет добавить атрибут id к элементу h1, который отображает текст «APACHE CORDOVA», чтобы мы могли настроить таргетинг на него с помощью JavaScript, чтобы изменить его на что-то специфичное для платформы. Нам нужно изменить:

<h1>Apache Cordova</h1>

to be:

<!-- Added id, deleted content to demonstrate merges -->
<h1 id="appFullName"></h1>

Затем в конце файла нам нужно включить тег «‹script›», чтобы загрузить наш новый файл JavaScript:

…
<script type="text/javascript" src="cordova.js"></script>
<!-- Following line added to demonstrate merges -->
<script type="text/javascript" src="js/platform.js"></script>
<script type="text/javascript" src="js/index.js"></script>
…

На этом мы закончили с изменениями в index.html, поэтому давайте сохраним их и перейдем к редактированию стандартного файла JavaScript «js / index.js». Здесь нам просто нужно изменить функцию «инициализировать», чтобы извлечь конкретную для платформы строку из нашего файла «platform.js» и отобразить ее:

initialize: function() {
  /* Added following line to demonstrate merges. */
  document
    .getElementById('appFullName')
    .innerHTML = platformConstants.appFullName;
  this.bindEvents();
}

Для полноты картины давайте также сделаем эту работу в среде браузера ... для этого мы оставим исходное изображение робота Cordova на месте, сохраним исходный цвет фона «УСТРОЙСТВО ГОТОВНО» и установим в заголовке сообщение «MODUS CREATE WEB APP» .

Нам нужно будет добавить в проект новый файл www / css / platform.css, чтобы браузеру было что загружать, когда он не работает на iOS и Android. Мы можем оставить это поле пустым или просто написать в нем такой комментарий:

/* 
 www/css/platform.css will be replaced with:
 merges/<platform>/css/platform.css when built on iOS or Android
*/

Нам также нужно добавить «www / js / platform.js», который должен будет объявить наш объект, содержащий ключ, на который мы ссылаемся в «www / js / app.js» при запуске. Итак, «www / js / platform.js» должен содержать:

/* This is the default platform.js */
var platformConstants = {
  appFullName: 'Modus Create Web App'
}

Внеся эти изменения, мы можем использовать Cordova CLI в терминале, чтобы добавить платформу браузера в наше тестовое приложение:

cordova platform add browser --save

Теперь наше приложение готово к тестированию на iOS, Android и в браузере!

Сборка и тестирование приложения

Мы можем создать наше приложение для всех платформ с помощью одной команды:

cordova build

Когда это будет завершено, давайте проверим, что наши файлы из каталога merges были правильно скопированы на каждую платформу:

find . -name "platform.*" -o -name "logo.png"

Чей вывод должен быть:

./merges/android/css/platform.css
./merges/android/img/logo.png
./merges/android/js/platform.js
./merges/ios/css/platform.css
./merges/ios/img/logo.png
./merges/ios/js/platform.js
./platforms/android/assets/www/cordova-js-src/platform.js
./platforms/android/assets/www/css/platform.css
./platforms/android/assets/www/img/logo.png
./platforms/android/assets/www/js/platform.js
./platforms/android/platform_www/cordova-js-src/platform.js
./platforms/browser/cordova/node_modules/cordova-serve/src/platform.js
./platforms/browser/platform_www/cordova-js-src/platform.js
./platforms/browser/www/cordova-js-src/platform.js
./platforms/browser/www/css/platform.css
./platforms/browser/www/img/logo.png
./platforms/browser/www/js/platform.js
./platforms/ios/platform_www/cordova-js-src/platform.js
./platforms/ios/www/cordova-js-src/platform.js
./platforms/ios/www/css/platform.css
./platforms/ios/www/img/logo.png
./platforms/ios/www/js/platform.js
./www/css/platform.css
./www/img/logo.png
./www/js/platform.js

Как мы видим, файлы из каталога верхнего уровня «слияния» были скопированы по соответствующим путям в «платформах / браузере / www», «платформах / android / assets / www» и «платформах / ios / www».

Последний шаг - запустить собственное приложение в эмуляторах:

cordova emulate ios
cordova emulate android

Если все работает правильно, мы должны увидеть настроенную окраску «УСТРОЙСТВО ГОТОВНО», текстовую строку и изображение для каждой платформы, как показано ниже.

Чтобы протестировать реализацию браузера, мы используем команду:

cordova run browser

Это должно открыть реализацию браузера по адресу localhost: 8000 / index.html и отобразить:

Вывод

Используя функцию слияния, мы смогли продемонстрировать простое приложение Cordova, которое повторно использует как можно больше кода на двух платформах, функционирует в браузере без ошибок и не имеет специфических для платформы «if / else» или «switch». заявления в нем.

Слияния отлично подходят для работы с изображениями и CSS, зависящими от платформы, и в меньшей степени для некоторых потребностей JavaScript (значения конфигурации для конкретной платформы могут быть хорошим примером того, где слияние имеет смысл для файлов JavaScript / JSON). Для более сложного JavaScript, который должен различаться для каждой платформы или который вы хотите использовать в нескольких приложениях, мы рекомендуем вам рассмотреть вариант использования плагина.

Если вы хотите опробовать наше готовое тестовое приложение на себе, оно доступно на Github, и вы можете запустить его локально с помощью нескольких простых команд:

git clone https://github.com/ModusCreateOrg/cordova-merge-example.git
cd cordova-merge-example
cordova prepare
cordova build
cordova emulate ios
cordova emulate android
cordova run browser

Надеюсь, вы сочли это исследование удобной функции Cordova полезным, и мы будем рады узнать, планируете ли вы использовать ее в своих собственных приложениях. Если вы знаете кого-то, кому эта статья покажется информативной, поделитесь, пожалуйста! И подписывайтесь на меня в Twitter или Modus Create: Front End Development.