[TOC]
Данный проект предназначен для разработки React проекта с использованием H5 для мобильных устройств. Проект включает в себя следующие функции:
Использование VW для автоматического подбора шрифтов, что позволяет адаптировать дизайн под различные размеры экрана мобильных устройств.
Автоматическое создание спрайтов и соответствующих файлов sprite.less без необходимости ручного создания спрайтов или написания less кода.
Современная сборка с использованием webpack 4, которая обеспечивает разделение кода на модули, удаление повторяющихся CSS-кодов, оптимизацию ресурсов страницы и создание gz-пакетов.
Использование Fetch для создания сервиса dataService, который обеспечивает унифицированный формат запросов GET и POST к API.
Создание промежуточного компонента FetchData.jsx для предварительной загрузки данных и внедрения состояния в компоненты.
Реализация ленивой загрузки (lazy load) с помощью компонентов React router, которые включают в себя загрузку компонентов и отображение ошибок при неудачной загрузке. Это улучшает производительность и дружелюбие интерфейса.
Конфигурация bebel7.
Проверка предварительно запущенного кода с использованием liveServer для PROD среды.
Оптимизация CSS изображений и автоматическое разделение CSS файлов в производственной среде.
Использование browserHistory для маршрутизации, с автоматической конфигурацией для локальной среды (требуется настройка nginx на сервере при развертывании).
Автоматическое создание папки для сохранения текущего пакета tar, что предотвращает проблемы при развёртывании на сервере.
Возможность использования проекта как PC-проект, если отказаться от настроек H5, обеспечивая совместимость с IE9+.
Добавление панели для мобильной отладки, аналогичной консоли на ПК, для просмотра информации о console, network, cookie и localStorage.
Включение библиотеки жестов, таких как Pan, Pinch, Rotate и Swipe.
Интеграция Sentry для мониторинга и оповещения об ошибках в коде.
Получение уведомлений о завершении сборки Bundle и генерация отчета Bundle анализа.
Запуск локального сервера:
yarn dev
#или
npm run dev
Сборка bundle:
yarn build
#или
npm run build
Генерация tar-пакета:
# По умолчанию создается cdn.tar.gz
yarn tar
#или
npm run tar
# Можно указать собственное имя tar-пакета
yarn tar react
#или
npm run tar react
Тестирование перед развертыванием:
yarn start
#или
npm run start
webpack.config.js
{
test: /\.less$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'less-loader',
// Конфигурация для мобильного VW макета
{
loader: 'postcss-less-loader',
options: {
ident: 'postcss',
plugins: () => [
postcssPxToViewport({
viewportWidth: 750, // (Number) Ширина окна просмотра.
viewportHeight: 1334, // (Number) Высота окна просмотра.
unitPrecision: 3, // (Number) Количество знаков после запятой для единиц REM.
viewportUnit: 'vw', // (String) Ожидаемые единицы измерения.
selectorBlackList: ['.ignore', '.hairlines'], // (Array) Селекторы, которые следует игнорировать и оставить в пикселях.
minPixelValue: 1, // (Number) Установить минимальное значение пикселя для замены.
mediaQuery: false // (Boolean) Разрешить преобразование пикселей в медиа-запросах.
})
]
}
}
]
}
webpack.config.js
// Объединение изображений в спрайт
const SpritesmithPlugin = require('webpack-spritesmith');
// Пользовательский шаблон
const templateFunction = function(data) {
// console.log('---', data)
const shared = `.sprite_ico { background-image: url(I);display:inline-block;background-size: Wpx Hpx;}`
.replace('I', data.sprites[0].image)
.replace('W', data.spritesheet.width)
.replace('H', data.spritesheet.height);
const perSprite = data.sprites
.map(function(sprite) {
return `.sprite_ico_N { width: Wpx; height: Hpx; background-position: Xpx Ypx;}`
.replace('N', sprite.name)
.replace('W', sprite.width)
.replace('H', sprite.height)
.replace('X', sprite.offset_x)
.replace('Y', sprite.offset_y);
})
.join('\n');
return "//out:false" + '\n'+shared + '\n' + perSprite;
};
// Спрайты
plugins.push(
new SpritesmithPlugin({
src: {
//Путь, настраивается в соответствии с реальным путем
cwd: path.resolve(__dirname, './src/assets/icons'),
glob: '*.png'
},
// Цель: создание файла спрайта и файла стиля
target: {
// Путь, настраивается в соответствии с реальным путем
image: path.resolve(__dirname,
``` Текст запроса написан на языке JavaScript.
Ниже представлен перевод текста запроса на русский язык:
> Формат иконок должен быть `png`. Необходимые для создания спрайтов маленькие иконки помещаются в каталог `src/assets/icons`, после чего выполняется команда `yarn build`, и можно будет найти собственные значки ICON в файле `src\less\sprite.less`; например:

При использовании просто импортируйте `sprite_ico sprite_ico_guzhi`. Нет необходимости настраивать импорт файла `sprite.less`.
```html
<span className="sprite_ico sprite_ico_guzhi"></span>
Все компоненты React должны начинаться с заглавной буквы, остальное см. на официальном сайте.
cdn -------------- построенные ресурсы
public -------------- статические ресурсы
src -------------- все ресурсы React
actions --------------- связанные действия
assets --------------- все статические изображения
components ------------ общие компоненты
dataService----------- сервис запросов
less ------------------ файлы less
pages ----------------- все файлы входа и дочерние файлы
reducers -------------- reducer
router ---------------- настройка маршрутизатора
store ----------------- хранилище состояний
utils ----------------- общие методы
..... остальные — это App.jsx login.jsx и другие файлы входа
tar -------------- резервная копия tar
....
index.html
<script src="https://cdn.ravenjs.com/3.26.4/raven.min.js" crossorigin="anonymous"></script>
// Мониторинг ошибок кода Raven.config('https://f5fe3d6e599849bfa1d1f0c26d1c3213@sentry.io/1729437').install();
Добавьте компонент React ErrorBoundary, подробнее см. официальную документацию:
import React from 'react';
import oops from "@assets/oops.png";
// перехватывает ошибки JavaScript в любом месте их дочернего дерева компонентов, регистрирует эти ошибки и отображает резервный пользовательский интерфейс
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
}
componentDidCatch(error, errorInfo) {
this.setState({ error });
Raven.captureException(error, { extra: errorInfo });
}
render() {
if (this.state.error) {
//отображение резервного пользовательского интерфейса
return (
<div className="snap" onClick={() => Raven.lastEventId() && Raven.showReportDialog()}>
<img src={oops} />
<p>Мы сожалеем — что-то пошло не так.</p>
<p>Наша команда была уведомлена, но нажмите здесь, чтобы заполнить отчёт.</p>
</div>
);
} else {
//если нет ошибки, отобразить детей без изменений
return this.props.children;
}
}
}
export default ErrorBoundary;
Теперь, если мы намеренно внесём некоторые ошибки, появится сообщение «fallback UI»:
Пользователь может инициировать отправку проблемы нам, нажав на текст:
В настоящее время информация об ошибках отправляется на https://sentry.io, также можно создать собственный «частный сервер»;
index.html
//Просмотр ресурсов, связанных с консолью, на мобильном устройстве
(function () {
//Рекомендуется использовать CDN для загрузки
const src = 'https://cdn.jsdelivr.net/npm/eruda@1.5.8/eruda.min.js';
// var src = 'node_modules/eruda/eruda.min.js';
if (!/debug=true/.test(window.location) && localStorage.getItem('debug') != 'true') return;
document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>');
document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>');
})();
После запуска проекта перейдите по адресу http://192.168.1.100:3002/?debug=true, и на вашем мобильном устройстве вы увидите следующее:
<script
*Примечание: В тексте перевода могут быть неточности или ошибки.* **Пример использования Hammer.js**
Пример:
import React from 'react';
class HammerPan extends React.Component {
render() {
return <div className="myElement">888</div>;
}
componentDidMount() {
const myElement = document.querySelector('.myElement');
// создать простой экземпляр
// по умолчанию он добавляет только горизонтальные распознаватели
const mc = new Hammer(myElement);
// позволить жесту панорамирования поддерживать все направления.
// это заблокирует вертикальную прокрутку на сенсорном устройстве, пока элемент находится в фокусе
mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });
// слушать события...
mc.on('panleft panright panup pandown tap press', ev => {
myElement.textContent = ev.type + ' жест обнаружен.';
});
}
}
export default HammerPan;
После запуска проекта посетите http://192.168.1.100:3002/pan, чтобы увидеть результат.
# NPM
npm install --save-dev webpack-bundle-analyzer
# Yarn
yarn add -D webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
package.json
"scripts": {
"dev": "webpack-dev-server --mode development",
"build": "bash ./rm.sh && webpack --mode production --profile --json > stats.json && yarn tar",
"start": "node ./server.js",
"tar": "bash ./tar.sh"
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )