Обновление App
С некоторых пор я плотно переехал на Webpack, так что решил обновить и свою заготовку для создания сайтов App.
Точкой входа во frontend приложение служит _build/assets/js/index.js, там вот такой код:
В чём прикол, по сравнению с Gulp? Ну в том, что нам нужна только эта точка входа для работы, в которой импортируются и скрипты и стили. А дальше Webpack уже сам всё разбирает:
— берёт указанные скрипты, проходит по ним, находит зависимости и тащит с собой
— затем проходит по стилям, обрабатывает пути к файлам и тащит импорты
— копирует и минифицирует изображения
— скрипты, стили, шрифты и картинки раскладываются в соответствующие директории
— а конечные директории перед этим очищаются от старых файлов
— имена файлов называются с припиской их хэша из 8 символов, для грамотного кэширования
— за всё это отвечает единый конфиг и при добавлении новых библиотек в нём ничего менять не нужно, просто импортировать их в index.js
В итоге получается вот такая картина в assets:
Так как имена файлов меняются, генерируется еще и специальный манифест с их именами:
Дальше дело техники получить его в плагине на OnBeforeRegisterClientScripts и подключить скрипты со стилями на страницу:
Больше про версии ассетов думать не нужно. Просто вызывайте npm run build перед сборкой и установкой App. Понятное дело, есть и npm run watch для разработки.
Как видите, автоматически грузится и шрифт FontAwesome который обработан через импорт в scss и скопирован в директорию fonts.
Помимо автоматизации вы можете использовать и все прелести ECMAScript 6, конечно. Можно подключать хоть Vue, хоть React, хоть чёрта лысого.
Всем приятной разработки!
Точкой входа во frontend приложение служит _build/assets/js/index.js, там вот такой код:
import 'jquery'
import 'bootstrap'
import '../scss/index.scss'
console.log('App is loaded!');
В чём прикол, по сравнению с Gulp? Ну в том, что нам нужна только эта точка входа для работы, в которой импортируются и скрипты и стили. А дальше Webpack уже сам всё разбирает:
— берёт указанные скрипты, проходит по ним, находит зависимости и тащит с собой
— затем проходит по стилям, обрабатывает пути к файлам и тащит импорты
— копирует и минифицирует изображения
— скрипты, стили, шрифты и картинки раскладываются в соответствующие директории
— а конечные директории перед этим очищаются от старых файлов
— имена файлов называются с припиской их хэша из 8 символов, для грамотного кэширования
— за всё это отвечает единый конфиг и при добавлении новых библиотек в нём ничего менять не нужно, просто импортировать их в index.js
В итоге получается вот такая картина в assets:
Так как имена файлов меняются, генерируется еще и специальный манифест с их именами:
{
"bootstrap.js": "/assets/components/app/js/bootstrap.7ee522b0.min.js",
...
"fonts/fa-solid-900.woff": "/assets/components/app/fonts/fa-solid-900.0be94a07.woff",
"fonts/fa-solid-900.woff2": "/assets/components/app/fonts/fa-solid-900.64b3e814.woff2",
"jquery.js": "/assets/components/app/js/jquery.a93a223a.min.js",
"main.css": "/assets/components/app/css/main.628a6812.min.css",
"main.js": "/assets/components/app/js/main.41054e11.min.js",
"popper.js.js": "/assets/components/app/js/popper.js.103f3354.min.js"
}
Дальше дело техники получить его в плагине на OnBeforeRegisterClientScripts и подключить скрипты со стилями на страницу:
$manifest = MODX_ASSETS_PATH . 'components/app/manifest.json';
if (file_exists($manifest)) {
$files = json_decode(file_get_contents($manifest), true);
foreach ($files as $file) {
if (strpos($file, '.css')) {
$modx->regClientCSS($file);
} elseif (strpos($file, '.js')) {
$modx->regClientScript($file);
}
}
}
Больше про версии ассетов думать не нужно. Просто вызывайте npm run build перед сборкой и установкой App. Понятное дело, есть и npm run watch для разработки.
Как видите, автоматически грузится и шрифт FontAwesome который обработан через импорт в scss и скопирован в директорию fonts.
Помимо автоматизации вы можете использовать и все прелести ECMAScript 6, конечно. Можно подключать хоть Vue, хоть React, хоть чёрта лысого.
Всем приятной разработки!
Комментарии: 38
Спасибо!
За модуль webpack-assets-manifest спасибо, прикручу к своему конфигу и теперь нормально свяжу с modx.
Отличненько, попробуем вебпак =)
А из админки MODX можно как-то вызывать «npm run build» кнопкой созданной? Через shell_exec или есть способы получше?
App придуман именно для того, чтобы в админку вообще не заходить.
Это, конечно, здорово, но вопрос никак не отменяет :)
Пример. Создал я в удобном для меня окружении сайт, всё без админки, по фен-шую! Но, пришёл после меня менеджер, которую эти webpack / gulp совсем ни о чём не говорят, ему надо только шрифт в нескольких местах изменить, да скриптов пару поправить. И для этого ему надо подключаться по ssh, чтобы в терминалы выполнить npm run build? Это неудобно)
Пример. Создал я в удобном для меня окружении сайт, всё без админки, по фен-шую! Но, пришёл после меня менеджер, которую эти webpack / gulp совсем ни о чём не говорят, ему надо только шрифт в нескольких местах изменить, да скриптов пару поправить. И для этого ему надо подключаться по ssh, чтобы в терминалы выполнить npm run build? Это неудобно)
которую эти webpack / gulp совсем ни о чём не говорят, ему надо только шрифт в нескольких местах изменить, да скриптов пару поправить.Менеджер не должен этого делать, это не его работа. А если он берётся за работу, в которой ничего не понимает, то это уже его проблемы.
Скрипт сборки по умолчанию и так запускает npm run build, но процесс это небыстрый и, как правило, build.php прибивается по таймауту, если запускать его из браузера. А вот при работе в консоли такой проблемы не будет.
Каждый раз вызывать программиста, верстальщика, разработчика для того, чтобы изменить какую-нибудь мелочь — тоже дело довольно странное. Речь ведь не о функциональных возможностях, не о программировании, а о контенте, о том, как ог отображается. И, если надо убрать несколько строк CSS из тех файлов, что есть, то это вызывает слишком много лишних телодвижений, занимающих время, которое продуктивнее направить в другое русло.
Ваш метод хорош, а желание совместить приятное с полезным, чтобы всем было удобно, остаётся.
Самый логичный способ — добавить 1 кнопку для ребилда скриптов, стилей и т.д. Идеально же!
Ваш метод хорош, а желание совместить приятное с полезным, чтобы всем было удобно, остаётся.
Самый логичный способ — добавить 1 кнопку для ребилда скриптов, стилей и т.д. Идеально же!
Мой метод хорош для серьёзных проектов и разработчиков. И для серьёзных заказчиков, которые платят за техобслуживание сайта. А для проектов «на коленке» он, безусловно, совсем не хорош.
Прямо сейчас представил, как я сдал modstore.pro Витале с Лёней, а они там стили со скриптами в админке правят, чтобы меня не вызывать лишний раз. До слёз!
Прямо сейчас представил, как я сдал modstore.pro Витале с Лёней, а они там стили со скриптами в админке правят, чтобы меня не вызывать лишний раз. До слёз!
Бесспорно, это так. Вы очень выборочный в заказчиках, это здорово, что у вас грамотные заказчики.
Рад, что развеселил вас! Не плачьте
Рад, что развеселил вас! Не плачьте
Александр, РУ сообщество MODX разъяснения то начинает если ты, как минимум, с PHPна 4? 4+?, если нет — «метод хорош для серьёзных проектов и разработчиков. И для серьёзных заказчиков, которые платят». Это не место для таких вопросов ) А если, не дой Бог, вы начали изучать, то точно не сюда за помощью ). Поэтому MODX сообщество самое малочисленное ).
А так Василий создал хорошую вещь и она только для программеров и не более.
А так Василий создал хорошую вещь и она только для программеров и не более.
эт ты еще на всяких форумах и чатиках по линуксу не спрашивал начальные вопросы)))) вот там джентльмены знают толк в покрывании хренами)
честно говоря твой посыл в этом сообщении я понял только после 4-5 раза перечитывания :D
честно говоря твой посыл в этом сообщении я понял только после 4-5 раза перечитывания :D
Можно еще в один файлик все компоновать быстрее будет.
- gulp-iconfont и gulp-iconfont-css
- gulp-rev
- gulp-uglify
- gulp-clean-css
- gulp.spritesmith и gulp-imagemin
- gulp-svgmin, gulp-svg-sprite, gulp-cheerio
Если я одну библиотеку обновил, то именно она и загрузится у юзера заново, а остальные останутся в кэше.
Лично меня не радует перекачивать какой-нибудь бандл на много мегабайт при каждой обновке. Именно поэтому всё разбито на файлы с хэшем в имени.
Лично меня не радует перекачивать какой-нибудь бандл на много мегабайт при каждой обновке. Именно поэтому всё разбито на файлы с хэшем в имени.
На вкус и цвет конечно, мне больше нравиться вендоры отдельно компоновать (они достаточно редко обновляются, за исключением если это делается автоматом конечно со всякими тестами), а динамичные куски js держать в html. В итоге получаем 1-н css 1-н js 1-н спрайт, шрифты и отдельные файлы подгружаемых картинок контента.
Доброго времени суток, Степан. Чем генерируете спрайты, используете иконочные шрифты?
Доброго, делаю через gulp, есть определенная структура и от местоположения файликов, скрипт сам решает что куда распихивать, просто напишу частично что используется:
Советую вместо gulp-uglify использовать gulp-uglify-es, так как gulp-uglify не поддерживает ES6 и при компиляции такого кода будут возникать ошибки
Где же вы раньше были, спасибо! :)
Спасибо за информацию!
Спасибо за подсказку.
@Василий Наумкин Отличное решение, но одну противоречивость так и не удается победить:
Файл main.XXX.min.css — каждый раз новый, что удобно для кеширования, но не удобно для «истории».
Не успел опробовать, пожалуйста, подскажи:
Реально ли писать имя файла в формате main.min.css?v=XXX, где XXX — contenthash
Файл main.XXX.min.css — каждый раз новый, что удобно для кеширования, но не удобно для «истории».
Не успел опробовать, пожалуйста, подскажи:
Реально ли писать имя файла в формате main.min.css?v=XXX, где XXX — contenthash
filename: options.mode == 'production'
? 'css/[name].[contenthash:8].min.css'
: 'css/[name].css',
Для истории нужно использовать Git.
Я про эту историю:
archive.org/web/ и «Сохраненная копия» поисковиков
Такая же проблема с использованием Minify — каждый раз новые файлы (css и js)
archive.org/web/ и «Сохраненная копия» поисковиков
Такая же проблема с использованием Minify — каждый раз новые файлы (css и js)
Меня проблемы этих сервисов как-то совсем не заботят.
Если есть огромное желание — убери вообще [contenthash:8]. и добавляй версию при подключении файла в плагине.
Если есть огромное желание — убери вообще [contenthash:8]. и добавляй версию при подключении файла в плагине.
Спасибо за webpack, да и вообще отличную заготовку! Правда один момент неоднозначный получается: ресурсы генерируются со статическими id из массива, но что, если менеджер создал несколько новых ресурсов в админке? Получится так, что если мы вдруг надумаем добавить еще один ресурс в массив, то при следующей сборке ранее созданные ресурсы менеджером перезапишутся ввиду того, что наш пакет не знает о них. Такая же история получается при какой-нибудь выгрузке из 1C, например.
Спасибо за отличную заготовку! Все супер. Правда есть пара вопросов, буду рад ответам:
1) как поставить пакеты из modstore (подгружаю файл providers.php в resolvers и поставщик ставится без проблем), пробую указать такую конструкцию в setup.php, но пакет не ставится:
2) почему то при установке в папке core/components создается папка 0, которая полностью дублирует папку assets/components/app, это так и должно быть?
1) как поставить пакеты из modstore (подгружаю файл providers.php в resolvers и поставщик ставится без проблем), пробую указать такую конструкцию в setup.php, но пакет не ставится:
'pdoTools' => [
'version' => '2.12.3-pl',
'service_url' => 'modstore.pro',
],
Что делаю не так?2) почему то при установке в папке core/components создается папка 0, которая полностью дублирует папку assets/components/app, это так и должно быть?
1) неправильный service_url, правильный: modstore.pro/extras/
2) есть такая проблема
2) есть такая проблема
1) оказалось была ошибка в API-ключе, после исправления все заработало. modstore.pro/extras/ не обязательно указывать, modstore.pro досточно как оказалось.
2) эту папку можно удалять без каких-либо последствий?
2) эту папку можно удалять без каких-либо последствий?
можно ли как-то при помощи webpack-а чистить папку cache при каждом редактировании элементов, в частности сниппетов?
Я так понимаю, что нужно копать в файле webpack.config.js в блоке CleanWebpackPlugin, параметр cleanaftereverybuildpatters? Или ничего не получится и необходимо дополнительно ставить gulp?
Я так понимаю, что нужно копать в файле webpack.config.js в блоке CleanWebpackPlugin, параметр cleanaftereverybuildpatters? Или ничего не получится и необходимо дополнительно ставить gulp?
Как вариант предложу вот такую штуку, сам пользуюсь. Правда там немного по-другому
грузить страницу каждые 0.5 секунд выполнением скрипта, это сильно конечно :))
«Страница» это всего-лишь малюсенький скрипт на чистом PHP) Он запускает маленький процесс на сервере, который не напрягает ни процессор ни оперативку. А процессов этих в любой операционной системе тьма) Некоторые жрут сотни мегабайт оперативки каждую секунду, и грузят процессор. Gulp тоже запускает всякие процессы иначе как он узнает о том, что файлы изменились? У меня этот скрипт работает на локалке, и как-то я не чувствую тормозов в системе)) Он вообще для разработки, потом можно удалить ;) Кстати, та страница отдаётся за 20-30 мс.
В общем, проблем не было даже на хостинге. Вообще не понимаю удивления. За запросы к страницам что деньги берут или наказывают как-то?)
решилось настройкой конфига:
new CleanWebpackPlugin({
verbose: false,
cleanStaleWebpackAssets: true,
cleanAfterEveryBuildPatterns: [base + '../../../core/cache/*'],
dangerouslyAllowCleanPatternsOutsideProject: true,
dry: false,
}),
Народ, никто не сталкивался с проблемой, когда указываешь в типах содержимого для HTML расширение "/", чтобы все страницы заканчивались слэшем, получается циклическая переадресация?
Разобрался сам, мб кому пригодится:
в папке /Extras/App/core/components/app/model/ в файле app.class.php нужно найти код (101 строка):
в папке /Extras/App/core/components/app/model/ в файле app.class.php нужно найти код (101 строка):
if ($uri != '/' && in_array(substr($uri, -1), ['/', '?'])) {
$this->modx->sendRedirect(rtrim($uri, '/?'), ['responseCode' => 'HTTP/1.1 301 Moved Permanently']);
}
на if ($uri != '/' && in_array(substr($uri, -1), ['?'])) {
$this->modx->sendRedirect(rtrim($uri, '?'), ['responseCode' => 'HTTP/1.1 301 Moved Permanently']);
}
Всем привет. Понимаю, что вероятность крайне мала, но вдруг кто-то может помочь: почему-то не добавляются на страницу ни стили, ни скрипты. Такое чувство, что событие OnBeforeRegisterClientScripts просто не срабатывает. Что я делаю не так? Как заставить стили и скрипты грузиться из манифеста?
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.