Мои мысли и проекты
Создаем сайт на Lumen (Laravel) - изменяем структуру проекта
создание нетиповых решений 1с, fxo.

В предыдущей статьея указывал на проблему когда vue компоненты модуля находятся отдельно от php кода модуля. В данной статье я решу эту проблему изменив структуру проекта.

До сего момента при написании кода я пользовался Nodepad++. Это прекрасный легковесный редактор с подсветкой кода. Однако не подсвечивает компоненты Vue. Поэтому я решил перейти на Visual Studio Code. так как проекты у меня на переносном устройстве, то пользоваться буду портативной версией (partable) VSCode. Для этого скачаю файл zip. Распаковываем архив и создаем в распакованной папке директорию data. Все данные будут храниться в ней. После запуска VSCode устанавливаю плагин Vetur для работы с компонентами Vue. В принципе их много разных, может вы найдете что-то лучше.

Для форматирования PHP кода установил плагин phpfmt - PHP formatter. Для корректной работы его требуется натроить. Для этого в параметрах необходимо открыть файл настроек settings.json
В настройках указать в параметрах phpfmt.php_bin и php.validate.executablePath путь до php интерпретатора. Я ещё установил настройку editor.formatOnSave в true чтобы код форматировался при сохранении. Можно сделать это отдельно для php кода.

{
    "workbench.colorTheme": "Visual Studio Light",
    "editor.minimap.enabled": false,
    "explorer.confirmDelete": false,
    "breadcrumbs.enabled": true,
    // Местоположение php интерпретатора
    "phpfmt.php_bin": "s:/Cloud/Apps/OSPanel-5.2.9/modules/php/PHP-7.2-x64/php.exe",
    "php.validate.executablePath": "s:/Cloud/Apps/OSPanel-5.2.9/modules/php/PHP-7.2-x64/php.exe",
    // Set the default
    "editor.formatOnSave": true,
    // Enable per-language
    "[php]": {
        "editor.formatOnSave": true
    }
}

Также полезен будет плагин PHP IntelliSense для удобного перехода по коду.

Структура папок/файлов проекта теперь имеет следующий вид

Все файлы я уже описывал за исключением файла .excludes.txt. Он содержит в каждой строке маску файлов для исключения. К примеру вот для моего случая.

*/node_modules*
*/lumen/vendor*

Для упаковки проекта я использую 7-Zip и вот такую командную строку которую я нашел вот тут.

set inDir=<директория проекта>
7za.exe a -ssw -mx7 -r0 -x@%inDir%\.excludes.txt full_path_for_the_archive %inDir%

При этом в архив не попадут огромные папки node_modules и vendor, так как их содержимое можно восстановить и не стоит тратить время на их упаковку. Для восстановления в папке console создал файл s-install.bat. При выполнении в консоли команды s-install будут установлены все модули NodeJS и Composer

cls
rem Установить все пакеты NodeJS через npm
cd %~dp0..\
npm install
rem Установить все пакеты Lumen через Composer
cd %~dp0..\lumen\
composer install

Также в папку console добавил команду s-ui-build.bat для сборки исходного кода в библиотеки для подключения их на сайт.

@echo off
cls
rem Перейти в директорию с Vue UI для сайта
cd %~dp0..\
rem Запустить
npx vue-cli-service build %1 ./VueCLI/s-ui/main.js

Перенесем модули из папки lumen\app\Modules в папку lumen\modules. Изменим все namespace в классах модулей, убрав из них App. Добавим в настройки Composer путь до нового расположения modules

    "autoload": {
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "psr-4": {
            "App\\": "app/",
            "Modules\\": "modules/"
        }
    },

После этого обновим загрузчик, выполнив в папке lumen следующую команду

composer dump-autoload

И осталось последняя часть (из-за которой я и изменил структуру проекта) - автоматическая загрузка компонентов vue. Для этого я изменил файл точки входа VueCLI\s-ui\main.js

import Vue from "vue";
import kebabCase from 'lodash/kebabCase'
import "./plugins/vuetify";
//
Vue.config.productionTip = false

// Зарегистрировать Vue компоненты из контекста
function registerVueComponentsFromContext(requireComponent,cbTransformFilename) {
  // Зарегистрировать
  requireComponent.keys().forEach(fileName => {
    // Получение конфигурации компонента
    const componentConfig = requireComponent(fileName)
    //
    if(!cbTransformFilename) cbTransformFilename = function(fileName) { return fileName; }
    // Получение имени компонента в PascalCase
    const componentName = cbTransformFilename("s-"+kebabCase(
        // Удаление из начала `./` и расширения из имени файла
        fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    ) )
    /* eslint-disable no-console */
    console.log(fileName,' => ',componentName);
    /* eslint-enable no-console */
    // Глобальная регистрация компонента
    Vue.component(
      componentName,
      // Поиск опций компонента в `.default`, который будет существовать,
      // если компонент экспортирован с помощью `export default`,
      // иначе будет использован корневой уровень модуля.
      componentConfig.default || componentConfig
    )
  })  
}
//-- Подключить и зарегистрировать общие компоненты
registerVueComponentsFromContext( require.context(
    // Относительный путь до каталога модулей гду мы будем искать компоненты
    "./components",
    // Обрабатывать или нет подкаталоги
    true,
    // Регулярное выражение для определения файлов базовых компонентов
    /\w+\.(vue)$/
  )
);
//-- Подключить и зарегистрировать компоненты модулей
registerVueComponentsFromContext( require.context(
    // Относительный путь до каталога модулей гду мы будем искать компоненты
    "./../../lumen/modules/",
    // Обрабатывать или нет подкаталоги
    true,
    // Регулярное выражение для определения файлов базовых компонентов
    /\w+\/vue\/\w+\.(vue)$/
  ),
  // Трансформация имени компонента
  function(componentName){
    return componentName.replace("-vue","");
  }
);
// Сохранить ссылку на Vue глобально
window.Vue = Vue;

Теперь компоненты из папки VueCLI\s-ui\components и папко vue в модулях будут "подхватываться" автоматически. Это делается с помощью функции require.context которая позволяет искать файлы на диске при сборке приложения.

0

Комментарии

Чтобы оставлять комментарии войдите на сайт. Вы можете сделать это через социальную сеть