Laravel 용 package 만들기

Laravel 용 package 만들기 updated_at: 2024-07-22 16:30

[Laravel 용 package 제작] 1. 패키지 만들기

laravel Package Development

package 관련 참조

패키지 구조

- src
  - migrations
  - composer.json

composer.json

{
  "name": "wangta69/laravel_board",
  "description": "패키지 설명",
  "keywords": ["키워드1", "키워드2"],
  "homepage": "https://www.onstory.fun"
  "license": "MIT",
  "authors": [
    {
      "name": "제작자명",
      "email": "제작자 이메일",
      "homepage": "https://www.onstory.fun"
    }
  ],
  "minimum-stability": "안정화버전",
  "require": {
    "php": ">=7.0.0",
    "kyslik/column-sortable": "^6.0",
  },
  "autoload": {
    "psr-4": {
      "Pondol\\Bbs\\": "src/"
    }
  },
  "extra": {
    "laravel": {
      "providers": [
        "Pondol\\Bbs\\BbsServiceProvider"
      ],
      "aliases": {
        "CustomPackage": "Pondol\\Bbs\\Facades\\BbsFacade"
      }
    }
  }
}
  • name : 패키지의 이름입니다. 이것은 /로 나뉘는 벤더의 이름과 프로젝트의 이름으로 구성되어 있습니다.
    • monolog/monolog
    • wangta69/laravel_board
  • description : 패키지에 대한 짧은 설명입니다. 일반적으로 한줄 정도의 길이로 구성됩니다. 퍼블리시 된 패키지(라이브러리)의 경우 필수속성입니다.
  • version : 패키지의 버전을 의미합니다. 생략가능.
  • type : 패키지의 타입을 정의합니다. 기본타입은 library 입니다.
    • library
    • project
    • metapackage
    • metapackage
    • composer-plugin
  • keywords : 패키지와 관계가 있는 키워드가 배열 형태로 선언됩니다. 이것들은 검색과 필터링에 사용 됩니다.
  • homepage : 프로젝트의 웹사이트 URL
  • time : 해당 버젼의 릴리즈 날짜입니다. 반드시 YYYY-MM-DD 혹의 YYYY-MM-DD HH:MM:SS 의 형태로 사용해야 합니다.
  • license : SPDX Open Source License Registry 참조
  • authors : 제작자. 아래와 같은 속성을 가질 수 있습니다.
    • name : 제작자의 이름, 대게 실제 이름을 사용합니다.
    • email : 제작자의 이메일 주소.
    • homepage : 제작자 웹사이트의 주소.
    • role: 해당 프로젝트에서 제작자의 역할. (e.g. 개발자 혹은 번역가)
  • support : 지원정보. 아래와 같은 속성을 사용할 수 있습니다.
    • email: 지원을 위한 이메일 주소
    • issues: 이슈관리를 위한 URL
    • forum: 포럼 URL
    • wiki: 위키 URL
    • irc: 지원을 위한 IRC 채널(irc://server/channel)
    • source: 접근 혹은 다운로드 가능한 소스의 UR
  • Package links : 패키지 관련사항 으로 해당 내용에서는 패키지의 이름에 대응하는 버전 제약 객체를 갖습니다
{
  "require": {
    "monolog/monolog": "1.0.*"
  }
}
  • 세부내역

    • require : 당 패키지에서 필요한 패키지들입니다. 패키지는 요구사항에 작성되지 않는 것들 외에는 설치하지 않습니다.
    • require-dev (root-only) : 해당 패키지를 개발하거나 테스트를 수행하는 등에 필요한 패키지들입니다. 기본으로 최상위 패키지(root package)의 개발에 필요한 요구사항을 설치하게 됩니다. install과 update는 각각 --no-dev라는 옵션을 지원하는데, 이는 개발에 필요한 의존성 패키지들을 설치하지 않도록 합니다.
    • conflict : 현재 패키지 버전에서 충돌을 일으키는 패키지들입니다. 이들은 당신의 패키지안에 설치되지 않습니다.
    • replace : 재 패키지로 대체 가능한 패키지들의 리스트입니다. 이 replace 를 활용하는 경우는 패키지를 복사(fork)하고, 패키지의 고유한 버저닝과 다른 이름으로 배포할 수 있도록 합니다. 그리고 원본 패키지를 필요로하는 패키지들은 원본 패키지를 대체 할 수 있도록 복사한 패키지로도 동작이 가능하게 해줍니다.
    • provide : 현재 패키지에서 제공하는 다른 패키지들의 리스트입니다.
    • suggest : 해당 항목은 현재 패키지와 함께하면 더 좋거나 강화할 수 있는 패키지들을 제안합니다. 이는 현재 패키지를 사용하는 사용자에게 반드시 필요하진 않지만 추가하면 좋은 패키지들의 정보를 제공하기 위해 설치 이후에 보여지는 단순한 정보입니다.
  • autoload : PHP 오토로더를 위한 오토로더 매핑.

현재는 PSR-0 오토로딩, PSR-4 오토로딩, 클래스맵(classmap) 생성, 파일(files) 포함을 지원합니다. PSR-4를 사용하기를 권장하며 이는 사용하기에 매우 쉽습니다. (클래스를 추가할 때마다 매번 오토로드 파일을 재생성하는 번거로움을 피할 수 있습니다.).

"Pondol\\Bbs\\": "src/"
  • 세부내역

    • PSR-4 : psr-4에서는 어떤 네임스페이스가 파일경로(패키지 경로에 대한 상대경로)에 대응하는지를 정의할 수 있습니다. Foo\Bar\Baz와 같이 클래스를 오토로딩할 때 Foo\ 네임스페이스의 전두사가 src/ 디렉터리에 대응되어있다면, 오토로더는 src/Bar/Baz.php 파일을 찾을 것이고 그리고 해당 파일이 존재하면 이것을 불러올 것입니다. 예전 PSR-0에 완전히 대응되는 개념으로서 접두사(Foo\)는 현재의 파일경로가 아닙니다.
네임스페이스: 기본경로(src)

위처럼 처리되면 자동 로딩시 Pondol\Bbs 를 스페이스로 하고 이후 src의 모든 파일들을 참조한다.

  • "extra" > "laravel" >"providers"

여기에 정의된 provider를 install 시 읽어 들여 초기화 한다.

ServiceProvider

<?php
namespace Pondol\Bbs;
use Illuminate\Support\ServiceProvider;

class BbsServiceProvider extends ServiceProvider {
  /**
   * Where the route file lives, both inside the package and in the app (if overwritten).
   *
   * @var string
   */
   // public $routeFilePath = '/routes/bbs/base.php';

  /**
   * Register any application services.
   *
   * @return void
   */
  public function register()
  {
    $this->app->bind('bbs', function($app) {
      return new Bbs;
    });
  }

  /**
     * Bootstrap any application services.
     *
     * @return void
     */
    //public function boot(\Illuminate\Routing\Router $router)
  public function boot()
  {
    if (!$this->app->routesAreCached()) {
      require_once __DIR__ . '/Https/routes/web.php';
      require_once __DIR__ . '/Https/routes/api.php';
    }

    $this->loadMigrationsFrom(__DIR__.'/migrations/'); // migrations 디렉토리에 있는 모든 파일들을 마이그래이션 한다.
    \Artisan::call('migrate'); // midration 파일들로 부터 db create or update


    // set assets
    $this->publishes([
      __DIR__.'/Https/public/assets/' => public_path('assets/pondol/bbs'),
    ], 'public');

    // copy config
    $this->publishes([
      __DIR__.'/Https/config/bbs.php' => config_path('bbs.php'),
    ], 'public');


    // LOAD THE VIEWS
    // - first the published views (in case they have any changes)
    $this->publishes([
      __DIR__.'/resources/views/bbs' => resource_path('views/bbs'),
    ]);
    // - loadViews  : 상기와 다른 점음  resources/views/bbs 에 없을 경우 아래 것에서 처리한다. for user modify
    $this->loadViewsFrom(__DIR__.'/resources/views/bbs', 'bbs');

    $this->publishes([
      __DIR__.'/Https/Controllers/Bbs/' => app_path('Http/Controllers/Bbs'),
    ]);
  }
}

Resources

리소스 파일들은 boot() 안에 넣어 둔다.

config

아래는 config 파일을 활용하는 두가지 예 (publishes, mergeConfigFrom) 이다.
publishes 는 현재 배포하는 패키지의 config 파일을 laravel application에서 사용하는 config path에다가 copy 하는 것이다.
이렇게 함으로서 배포된 패키지를 사용하는 사용자들은 쉽게 config를 변경할 수 있다.

public function boot(): void
{
  $this->publishes([
    __DIR__.'/../config/courier.php' => config_path('courier.php'),
  ]);
}

그러면 mergeConfigFrom 은 왜 사용하는 것일까?
버전업등이나 사용자의 실수(?) 등으로 특정 변수등이 필요한 경우 현재 배포중인 패키지의 config에서 값을 가져오게 하는 것이다.
즉, 기존 config에 있는 변수에 없는 값을 추가로 넣어 안정적인 서비스를 운영할때 필요한 명령이다.

public function register(): void
{
  $this->mergeConfigFrom(
    __DIR__.'/../config/courier.php', 'courier'
  );
}

routes

패키지에 경로가 포함된 경우 loadRoutesFrom 메서드를 사용하여 경로를 로드할 수 있습니다. 이 메소드는 애플리케이션의 경로가 캐시되었는지 자동으로 확인하고 경로가 이미 캐시된 경우 경로 파일을 로드하지 않습니다.

public function boot(): void
{
  $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}

예전에는 아래와 같은 방법으로도 사용했지만 현재는 위의 방법을 추천드립니다.

public function boot()
{
  if (!$this->app->routesAreCached()) {
    require_once __DIR__ . '/Https/routes/web.php';
    require_once __DIR__ . '/Https/routes/api.php';
  }
}

Migrations

데이타베이스 마이그레이션이 필요한 경우 사용합니다.

public function boot(): void
{
  $this->publishesMigrations([
    __DIR__.'/../database/migrations' => database_path('migrations'),
  ]);
}

언어파일(Language Files)

public function boot(): void
{
  $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');
}

blade에서 호출시 아래와 같이 하시면 됩니다.

echo trans('courier::messages.welcome');

Views

뷰 가 있는 위치를 나타낸다.

/**
 * Bootstrap any package services.
 */
public function boot(): void
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}

컨트롤러에서 아래처럼 호출하면 된다.

Route::get('/dashboard', function () {
  return view('courier::dashboard');
});

View Components

use Illuminate\Support\Facades\Blade;
use VendorPackage\View\Components\AlertComponent;
 
/**
 * Bootstrap your package's services.
 */
public function boot(): void
{
  Blade::component('package-alert', AlertComponent::class);
}
  • blade에서는 아래와 같이 사용하시면 됩니다.
<x-package-alert/>
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1

질문 및 답글