Skip to content

App Installation using Module Build

Aaron W. Swenson edited this page May 17, 2016 · 6 revisions

App Installation using Module::Build

There is an official recipe inside the Mojolicious documentation how to deploy your application using ExtUtils::MakeMaker.

http://mojolicio.us/perldoc/Mojolicious/Guides/Cookbook#Making-your-application-installable

If you are more familiar with Module::Build the following recipe will be useful. Additionally, I have now generalized this procedure into the module Mojolicious::Plugin::InstallablePaths which is useful both for Module::Build and EUMM deployments.

Much as with the EUMM example, first we move the templates and public directories into the lib directory. This time, though, we move them a little deeper.

mojo generate app
$ cd my_mojolicious_app
$ mv public lib/MyMojoliciousApp/files/
$ mv templates lib/MyMojoliciousApp/files/

From there we setup the paths. We do so in a way that if the app is run from the uninstalled directory, the files are used from here, but once the distribution is installed, these extra files are stored by File::ShareDir.

package MyMojoliciousApp;
use Mojo::Base 'Mojolicious';

use File::Basename 'dirname';
use File::Spec::Functions 'catdir';
use File::ShareDir 'dist_dir';

# Every CPAN module needs a version
our $VERSION = '1.0';

sub startup {
  my $self = shift;

  # Switch to installable home directory
  $self->home->parse(catdir(dirname(__FILE__), 'MyMojoliciousApp'));

  {
    # Switch to installable "public" directory
    my $public = $app->home->rel_dir('files/public');
    $app->static->paths->[0] = -d $public ? $public : catdir(dist_dir('MyMojoliciousApp'), 'public');

    # Switch to installable "templates" directory
    my $templates = $app->home->rel_dir('files/templates');
    $app->renderer->paths->[0] = -d $templates ? $templates : catdir(dist_dir('MyMojoliciousApp'), 'templates');
  }

  $self->plugin('PODRenderer');

  my $r = $self->routes;
  $r->get('/welcome')->to('example#welcome');
}

1;

Note that if your app has a name like My::Mojolicious::App you should call dist_dir('My-Mojolicious-App').

Finally, Be sure to add the shared directory lib/MyMojoliciousApp/files to the Build.PL file

use Module::Build;
my $builder = Module::Build->new(
  ...
  share_dir => 'lib/MyMojoliciousApp/files',
  ...
);
$builder->create_build_script;