предисловие
Техника теневого клонирования, любой, кто видел Хокаге, знает, что у одного тела есть несколько клонов.
Все должны задаваться вопросом, может ли разработка небольших программ быть связана с техникой теневого аватара? Да, это естественно: набор кода, несколько небольших программ.
Не закатывайте глаза, все, и слушайте меня. . .
В настоящее время разработка небольших программ идет полным ходом. В сочетании с продвижением WeChat бизнес многих компаний постепенно переходит на небольшие программы. Это заставило меня, Android-разработчика, начать путь разработки небольших программ.
Однако с развитием компании клиентов становится все больше и больше.Небольшие программы с одинаковыми основными функциями необходимо положить на полки для использования разными клиентами, и между каждой небольшой программой есть небольшая часть настройки, например Различия в отображении интерфейса, различия в мелких функциях и т.д.
Это сводит меня, новичка в разработке апплетов, с ума Скопировать код для каждого апплета, а затем вносить индивидуальные изменения? Означает ли это, что если основной бизнес однажды изменится, мне придется менять каждый набор кода отдельно? Нет, даже новичок не выдержит создания нескольких наборов повторяющегося кода! !
Поэтому для этого сценария есть решение: разработать технику теневого клонирования апплета.
Адрес Github: https://github.com/BakerJQ/WeAppBunXin
Проект основан наTaroкадр, поЛаборатория ударовОткрытый исходный код, большое спасибо за их тяжелую работу.
Я выбрал Taro главным образом потому, что он принимает стандарт синтаксиса React, и у меня есть предыдущий опыт разработки ReactNative.
Так как я давно не контактировал с front-end разработкой, если есть ошибка в тексте или есть лучшее решение, то приветствую вашу терпимость и исправление, большое спасибо.
Базовая конфигурация теневого клона
Способность теневого клона в основном исходит из способности компиляции, предоставленной Таро, поэтому необходимоКонфигурация сборкиа такжеСведения о конфигурации сборкипонимать.
Давайте сначала посмотрим на соответствующие каталоги файлов конфигурации:
Каталог config является каталогом конфигурации по умолчанию после инициализации Taro.Три файла (dev, index, prod) в синей рамке на рисунке — это файлы конфигурации, сгенерированные по умолчанию, а остальные файлы — это конфигурации, необходимые для клона. На рисунке настроено три аватара, в качестве примера возьмем канал 1, config — некоторая конфигурация аватара, а project.config.json — базовая конфигурация апплета аватара, например:
{
"miniprogramRoot": "./",
"projectname": "channel1",
"description": "channel1",
"appid": "wx8888888888888",
...
}
Файл channel.js используется для указания того, какой апплет в данный момент необходимо скомпилировать, например:
module.exports = {
channel: 'channel1'
}
В файле записи конфигурации компиляции по умолчанию index.js нам нужно настроить выходной каталог апплета, конфигурация выглядит следующим образом:
const channelInfo = require('./channel')
const config = {
...
//输入目录为dist_channel1
outputRoot: 'dist_' + channelInfo.channel,
...
//讲config/channel1/project.config.json文件拷贝到dist_channel1下
copy: {
patterns: [
{
from: 'config/' + channelInfo.channel + '/project.config.json',
to: 'dist_' + channelInfo.channel + '/project.config.json'
}
],
...
}
...
}
Казнить Тарокоманда компиляции апплетаПосле этого будет создана папка кода апплета dist_channel1, соответствующая клону, и вы можете напрямую использовать инструмент разработчика апплета, чтобы открыть этот каталог для предварительного просмотра апплета channel1.
С помощью этих конфигураций мы можем сгенерировать несколько разных небольших программ с помощью одного и того же набора кода! Конечно, содержание этих небольших программ абсолютно одинаковое, самое большее, имя и appid, настроенные в project.config.json, отличаются.
Затем давайте начнем смотреть, как создавать несколько дифференцированных апплетов.
Перед конкретной реализацией нам необходимо знать две важные конфигурации Таро:Глобальная переменная «defineConstants»а такжепсевдоним "псевдоним".
Клон в стиле теневого клона
Во-первых, давайте взглянем на одно из наиболее распространенных требований, которое заключается в различии стиля между различными программами-апплетами. Давайте сначала посмотрим на две картинки.
апплет А | апплет Б |
---|---|
С точки зрения стиля, текущие различия между двумя апплетами:
- разные основные цвета
- Соответствующие ресурсы изображений отличаются
- другое расположение
Установить каталог аватаров
Первый шаг — создать каталог для каждого апплета аватара в src, желательно с тем же именем, что и конфигурация в channel.js, как показано ниже:
Различия стилей места
Возьмем в качестве примера предыдущую «Мини-программу А»:
Папка assets — это ресурсный файл апплета, то есть различные синие значки.
app.less — это файл глобального стиля со следующим содержимым:
@main_color: #1296db;
.main_color_txt {
color: @main_color
}
Файл ChannelStyle.ts — это стиль, который может понадобиться в коде:
const ChannelStyle = {
mainColor: '#1296db'
}
export default ChannelStyle
Настроить псевдонимы
После размещения всех видов различий в стилях вы можете настроить глобальные переменные и псевдонимы.Выполните следующую настройку в index.js в конфигурации проекта.
const config = {
...
alias: {
'@/channel': path.resolve(__dirname, '..', 'src/channel/' + channelInfo.channel),
'@/assets': path.resolve(__dirname, '..', 'src/channel/' + channelInfo.channel + '/assets'),
'@/app_style': path.resolve(__dirname, '..', 'src/channel/' + channelInfo.channel + '/app.less'),
}
...
}
Таким образом, на него можно ссылаться с помощью псевдонимов в коде.
//代码中需要用到ChannelStyle中的样式
import ChannelStyle from '@/channel/ChannelStyle'
//app.tsx入口文件引用全局样式
import '@/app_style'
//引用资源图片
<Image src={require('@/assets/icon.png')} />
Кроме того, обратите внимание, что, поскольку Taro не поддерживает псевдонимы в файлах стилей, таких как .less, на него нельзя ссылаться способом, аналогичным @import '@/app_style', поэтому в настоящее время необходимо разместить полное количество разностных стилей. под каждым пакетом аватарки.
Настроить глобальные переменные
Поскольку конфигурация TabBar представлена в виде чистых строк и не может быть настроена через псевдонимы, необходимо использовать другой метод настройки, то есть глобальные переменные Метод настройки в index.js выглядит следующим образом:
const config = {
defineConstants: {
ASSETS_PATH: 'channel/'+channelInfo.channel+'/assets'
}
}
Однако у каждого клона основной цвет разный, поэтому его нужно настраивать в конфигурационном файле клона, то есть в базовой конфигурации config.js под папкой клона, в которую добавлена конфигурация глобальных переменных :
module.exports = {
...
defineConstants: {
MAIN_COLOR: '#1296db'
},
...
}
Глобальные переменные можно использовать прямо в коде, например, конфигурацию TabBar в app.tsx:
config: Config = {
...
tabBar: {
...
selectedColor: MAIN_COLOR,
list: [
{
pagePath: 'pages/index/index',
text: '首页',
iconPath: ASSETS_PATH + '/home_u.png',
selectedIconPath: ASSETS_PATH + '/home_s.png'
},
...
]
}
}
слияние конфигураций
После завершения настройки в окончательный объединенный код файла index.js добавьте определенную нами конфигурацию аватара:
module.exports = function (merge) {
...
//默认的原始代码为return merge({}, config, envConfig)
return merge({}, config, envConfig, require('./' + channelInfo.channel + "/config"))
}
резюме стиля аватара
Таким образом, в соответствии с файлом ресурсов и цветовой конфигурацией темы «мини-программы B», эти две мини-программы могут быть сгенерированы путем изменения имени аватара компиляции в channel.js.
Мы также можем обнаружить, что разница в стиле между «Мини-программой A» и «Мини-программой B», помимо изображений ресурсов и цветов темы, макет страницы «Разработка» также отличается, как с этим бороться? Правильно, указать соответствующий файл стиля для каждой страницы, указав файл less по псевдониму.
Если в реальном бизнесе существуют очевидные различия в стилях тем и стилей между разными апплетами, рекомендуется создать пакеты тем, а затем настроить разные пакеты тем для разных апплетов, например:
//分身配置
module.exports = {
...
alias: {
'@/theme': path.resolve(__dirname, '..', '../src/theme/theme1'),
...
}
...
}
//文件引用
import '@/theme/dev.less'
Клон функции теневого клонирования
В дополнение к различиям в стиле мини-программы с настраиваемыми атрибутами также должны иметь определенные функциональные различия.
Внимательные друзья могли обнаружить, что количество записей на странице разработки «Мини-программы А» и «Мини-программы Б» разное.
«Апплет А» не имеет FireWall, и порядок первых двух элементов Java и JSX у этих двух апплетов разный. Мало того, если вы запустите апплет и нажмете на каждый элемент, вы обнаружите, что когда вы нажимаете на элемент C++, «Applet B» перейдет на страницу сведений об элементе, а «Applet A» перейдет на « Вкладка «Управление».
Как мы справляемся с такими функциональными различиями?
Определить конфигурацию страницы
Идея, которую я имею в виду, состоит в том, чтобы предоставить дифференцированные элементы конфигурации для страниц с различиями, а затем объединить конфигурации аватаров с различиями путем слияния.
Давайте сначала посмотрим на каталог конфигурации после завершения определения, который находится в src:
Для «разработки» страницы, например, в DevConfig.ts я определил следующие конфигурации:
import Taro from "@tarojs/taro";
//页面配置
export default {
dev: {
items: {//条目
item1: {//条目1
img: require('@/assets/jsx.png'),//图片
txt: 'JSX',//文字
onItemClick: () => {//点击跳转事件
toPage('JSX', require('@/assets/jsx.png'))
}
},
item2: {...},
...
}
}
}
//页面跳转
function toPage(title, img){
Taro.navigateTo({url: '/pages/dev/DevInfo?title='+title+'&img='+img})
}
определить слияние различий
При этом файл ChannelConfigDiff.ts в составе пакета diff, как файл разностной конфигурации, имеет следующее содержимое:
export default (config, merge)=>{
return merge([{}, config])
}
Видно, что это фактически возвращает входящий конфиг как есть, потому что для основной части проекта конфиг менять не нужно, конкретное использование будет объяснено ниже.
А MultiChannelConfig.ts — это окончательная конфигурация каждой страницы, содержание которой следующее:
import merge from 'deepmerge'
import ChannelConfigDiff from '@/diff/ChannelConfigDiff'
//开发页面配置
import DevConfig from './pages/DevConfig'
//合并基本页面配置
const baseConfig = Object.assign({}, DevConfig)
//合并差异页面配置
const config = ChannelConfigDiff(baseConfig, merge.all)
//开发页面最终配置
export const devConfig = config.dev
Определить конфигурацию различий
В приведенном выше определении мы обнаружили, что ChannelConfigDiff ссылается на псевдоним Теперь все должны понимать роль файла ChannelConfigDiff.ts, верно? Правильно, добавив этот файл в каждый клон и прописав конфигурацию.
Взяв в качестве примера «Мини-программу A», каталог diff выглядит следующим образом:
В ChannelConfigDiff.ts канала 2 вам нужно только настроить определенные элементы различий, а если они не настроены, используйте конфигурацию по умолчанию:
const dev = {
dev: {
items: {
item1: {//定义第一个item为java内容
img: require('@/assets/java.png'),
txt: 'Java',
onItemClick: () => {
toPage('Java', require('@/assets/java.png'))
}
},
item2: {...},//第二个item为jsx内容
item5: null,//第五个item(FireWall)为空
item8: {
onItemClick: () => {//最后一个item(C++)点击后跳转TAB
Taro.switchTab({url: '/pages/index/Manage'})
}
}
}
}
}
//将dev配置合并到原始整体配置
export default (config, merge) => {
return merge([{}, config, dev])
}
Видно, что в этой конфигурации содержимое item1 (оригинальный jsx) и item2 (оригинальный java) поменяно местами, item5 (оригинальный FireWall) оставлен пустым, а событие click для item8 (оригинальный C++) изменено. Благодаря этим конфигурациям могут быть достигнуты функциональные различия в «Мини-программе А».
Наконец, не забудьте определение псевдонима, в index.js псевдоним настроен как:
'@/diff': path.resolve(__dirname, '..', 'src/config/diff'),
В config.js канала 2 псевдоним настроен как:
'@/diff': path.resolve(__dirname, '..', '../src/channel/channel2/diff'),
Обзор функциональных аватаров
Если есть другие различия страниц, вы можете выполнить дифференциальную обработку, добавив аналогичную конфигурацию.Нет никаких требований к формату каталога файла.Вам нужно только убедиться, что имя файла конфигурации согласовано, а конфигурация псевдонима верна.
В это время, после компиляции, сгенерированная «мини-программа А» имеет страницу «разработки» с дифференцированными стилями и функциями.
Такая дифференцированная конфигурация требует хорошего понимания бизнеса, разумного разделения компонентов и определения разумных элементов конфигурации.
Большая разница теневых клонов
Даже если используются стильные и функциональные аватары, все равно могут быть огромные различия в требованиях к настройке. Эти огромные различия приводят к чрезмерным затратам на настройку стилевых и функциональных аватаров. Что в этом случае делать?
Если это произойдет, ей придется сломать руку, чтобы выжить — то есть подмену всей страницы.
Давайте взглянем на «Страницы администратора» «Мини-программы А» и «Мини-программы Б»:
апплет А | апплет Б |
---|---|
написать новую страницу
Мы предполагаем, что страницу «Администрирование» «Мини-программы B» трудно отличить с помощью конфигурации, поэтому в настоящее время нам нужно только написать новую страницу со следующим каталогом:
Среди них страница под страницами - это страница, посвященная каналу 3.
замена страницы
Способ замены страниц на самом деле через глобальные переменные.
index.js:
defineConstants: {
PAGE_MANAGE: 'pages/index/Manage',
}
config.js для канала 3:
defineConstants: {
PAGE_MANAGE: 'channel/channel3/pages/index/Manage'
},
Конфигурация страницы app.tsx:
config: Config = {
pages: [
...
PAGE_MANAGE
],
...
tabBar: {
...
list: [
...
{
pagePath: PAGE_MANAGE,
...
}
]
}
}
Таким образом, после компиляции, канал 3 генерирует страницу «Управление» «Апплета Б», которая является уникальной страницей канала 3.
Суммировать
То, что представлено в этой статье, - это просто метод, который я могу придумать для решения дилеммы «несколько небольших программ с похожими основными функциями должны поддерживать несколько наборов кодов». Если есть лучший метод, я надеюсь, что вы можете сказать мне, спасибо ты очень.
Так как я только новичок во фронтенд-разработке под Android, мне еще многому предстоит научиться, если в тексте есть ошибки, прошу меня поправить и покритиковать.
Конкретный код можно просмотреть на Github, и вы также можете пометить его звездочкой и поднять вопрос.
Наконец, снова опубликуйте адрес Github: https://github.com/BakerJQ/WeAppBunXin.