File Coverage

blib/lib/Mojolicious/Command/Author/webpack.pm
Criterion Covered Total %
statement 34 41 82.9
branch 13 20 65.0
condition 8 15 53.3
subroutine 7 9 77.7
pod 1 1 100.0
total 63 86 73.2


line stmt bran cond sub pod time code
1             package Mojolicious::Command::Author::webpack;
2 1     1   226257 use Mojo::Base 'Mojolicious::Command';
  1         14  
  1         6  
3              
4 1     1   63622 use Mojo::File 'path';
  1         3  
  1         154  
5 1     1   10 use Mojo::Util 'getopt';
  1         3  
  1         71  
6              
7             # Less noisy test runs
8 1   33 1   7 use constant SILENT => $ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_IS_VERBOSE};
  1         3  
  1         995  
9              
10             # Ugly hack to prevent Mojo::Server::Morbo from exiting
11             our $WORKER_PID = -1;
12 0 0 0 0   0 *CORE::GLOBAL::exit = sub { $WORKER_PID == $$ ? $_[0] : CORE::exit($_[0] // $!) };
13              
14             has description => 'Start application with HTTP, WebSocket and Webpack development server';
15             has usage => sub { shift->extract_usage };
16             has _morbo => sub { require Mojo::Server::Morbo; Mojo::Server::Morbo->new };
17              
18             sub run {
19 15     15 1 32194 my ($self, @argv) = @_;
20              
21             # Need to run "mojo webpack" and not "./myapp.pl webpack" to have a clean environment
22 15 100       53 return $self->_exec_mojo_webpack($0, @argv) unless path($0)->basename eq 'mojo';
23              
24             # Parse command line options
25             getopt \@argv,
26             'B|build' => \my $build,
27             'b|backend=s' => \$ENV{MOJO_MORBO_BACKEND},
28             'h|help' => \my $help,
29             'l|listen=s' => \my @listen,
30             'm|mode=s' => \$ENV{MOJO_MODE},
31             'v|verbose' => \$ENV{MORBO_VERBOSE},
32 14         722 'w|watch=s' => \my @watch;
33              
34 14 100 100     9726 die join "\n\n", $self->description, $self->usage if $help or !(my $app = shift @argv);
35 11 50       29 return $self->_build($app) if $build;
36              
37             # Start rollup/webpack
38 11         30 my $builder_pid = $self->_start_builder($app);
39 11 50 100     1493 say "Bundler started with pid $builder_pid." if +($ENV{MORBO_VERBOSE} // 1) == 1;
40              
41             # Set up and start morbo - Mojo::Server::Morbo::run() will block until the the app is killed
42 11         127 local $ENV{MOJO_WEBPACK_BUILD} = ''; # Silence initial "Sure ... has been run ..." warning
43 11         54 local $WORKER_PID = $$;
44 11 100       50 $self->_morbo->backend->watch(\@watch) if @watch;
45 11 100       2409 $self->_morbo->daemon->listen(\@listen) if @listen;
46 11         127 $self->_morbo->run($app);
47              
48             # Stop rollup/webpack after the app is killed
49 11 50 100     109 warn "[Webpack] [$$] Reaping builder with pid $builder_pid...\n" if $ENV{MORBO_VERBOSE} and !SILENT;
50 11         34 1 while kill $builder_pid;
51             }
52              
53             sub _build {
54 0     0   0 my ($self, $app) = @_;
55 0   0     0 $ENV{MOJO_WEBPACK_BUILD} ||= 'build';
56 0         0 Mojo::Server->new->load_app($app);
57             }
58              
59             sub _exec_mojo_webpack {
60 1     1   117 my ($self, @argv) = @_;
61 1         3 warn "Switching to `mojo webpack @argv` ...\n" unless SILENT;
62 1         2 { exec qw(mojo webpack), @argv };
  1         6  
63 1         54 die "exec mojo @argv: $!";
64             }
65              
66             sub _start_builder {
67 11     11   24 my ($self, $app) = @_;
68 11 50       35 die "Can't fork: $!" unless defined(my $pid = fork);
69 11 50       466 return $pid if $pid;
70 0           local $ENV{MOJO_WEBPACK_BUILD} = 'watch';
71 0           Mojo::Server->new->load_app($app);
72 0           exit $!;
73             }
74              
75             1;
76              
77             =encoding utf8
78              
79             =head1 NAME
80              
81             Mojolicious::Command::Author::webpack - Mojolicious HTTP, WebSocket and Webpack development server
82              
83             =head1 SYNOPSIS
84              
85             Usage: mojo webpack [OPTIONS] [APPLICATION]
86              
87             mojo webpack ./script/my_app
88             mojo webpack ./myapp.pl
89             mojo webpack -m production -l https://*:443 -l http://[::]:3000 ./myapp.pl
90             mojo webpack -l 'https://*:443?cert=./server.crt&key=./server.key' ./myapp.pl
91             mojo webpack -w /usr/local/lib -w public -w myapp.conf ./myapp.pl
92             mojo webpack --build --mode production
93             MOJO_NPM_BINARY=pnpm mojo webpack --build
94              
95             Options:
96             -B, --build Build the assets and exit
97             -b, --backend Morbo backend to use for reloading, defaults
98             to "Poll"
99             -h, --help Show this message
100             -l, --listen One or more locations you want to listen on,
101             defaults to the value of MOJO_LISTEN or
102             "http://*:3000"
103             -m, --mode Operating mode for your application,
104             defaults to the value of
105             MOJO_MODE/PLACK_ENV or "development"
106             -v, --verbose Print details about what files changed to
107             STDOUT
108             -w, --watch One or more directories and files to watch
109             for changes, defaults to the application
110             script as well as the "lib" and "templates"
111             directories in the current working
112             directory
113              
114             =head1 DESCRIPTION
115              
116             Start L and L applications with the
117             L web server.
118              
119             =head1 ATTRIBUTES
120              
121             =head2 description
122              
123             my $description = $daemon->description;
124             $daemon = $daemon->description('Foo');
125              
126             Short description of this command, used for the command list.
127              
128             =head2 usage
129              
130             my $usage = $daemon->usage;
131             $daemon = $daemon->usage('Foo');
132              
133             Usage information for this command, used for the help screen.
134              
135             =head1 METHODS
136              
137             =head2 run
138              
139             $daemon->run(@ARGV);
140              
141             Run this command.
142              
143             =head1 SEE ALSO
144              
145             L, L
146              
147             =cut