NAME

slimpack - build a fatpacked, minified standalone Perl script

SYNOPSIS

slimpack [options] script
slimpack [options] -e/-E 'code' [-m/-M module ...]
slimpack trace   [--to=FILE|--to-stderr] [--use=MODULE] script
slimpack packlists-for MODULE...
slimpack tree    [PACKLIST ...]
slimpack bundle  [options] script
slimpack minify  [options] script...     # minify only, no bundling
slimpack --minify script...              # same, as a flag

DESCRIPTION

By default (pack) slimpack drives the whole fatpack pipeline internally by calling App::FatPacker's methods: it traces the boot script, drops core modules with Module::CoreList, resolves their packlists, copies the module sources into a temporary fatlib, then minifies and inlines plugins and emits a single standalone #!/usr/bin/perl script.

Each pipeline step is also exposed as its own subcommand with the same arguments as fatpack, so the individual steps can be run by hand.

minify (or the --minify switch) runs only the minification pass: each file is read, PPI-minified, and printed to STDOUT (or written with -o). Nothing is traced or bundled. The standalone minify script installed alongside slimpack offers the same mode.

OPTIONS

-o, --output FILE

Write the bundled script to FILE (default a.out; use - for stdout). minify prints to STDOUT unless -o is given.

--lib DIR

Project .pm sources (default lib).

--fatlib DIR

Fatpacked module tree (default fatlib; pack uses a temporary one).

--no-minify

Bundle modules and boot program verbatim, skipping the PPI minification pass.

--rename-vars, --no-rename-vars

Minify and rename my variables (default), or with --no-rename-vars leave variable names untouched (perl process(..., rename_vars = 0)>). Applies to bundling and to the minify mode. The legacy spelling --rename/--no-rename is still accepted as an alias.

--rename-subs, --no-rename-subs

Also rename sub and method names to short names (default): definitions, plain calls, ->method chains, &name/\&name code-references and fully-qualified Pkg::name(...) calls are all shortened in step, so the bundle shrinks further than variable renaming alone reaches. Names are kept verbatim when Perl dispatches or reads them by name: keywords and builtins, magic methods (new, DESTROY, AUTOLOAD, import, can, isa, tie methods, serialization hooks), string arguments to ->can(...) and friends, hashed-deref keys and label/goto targets. Variable-method dispatch $obj->$name is unchanged, but a method that is only invoked through $obj-can('method')> plus a string would stop matching after the rename; such modules should be packed with --no-rename-subs.

When bundleing, the whole dependency graph is renamed consistently with one shared name map (the minify mode renames each file independently).

--rename-modules, --no-rename-modules

On by default when bundling: rename the namespace components of every bundled package to short names, keeping each package's leaf (final) component verbatim. A bundle controls its own dependency graph, so package App::Thing, use App::Thing, App::Thing->new, qualified App::Thing::sub and module/namespace strings ("App/Thing.pm") can all agree on one short name, shrinking the file further than sub renaming alone. The leaf is kept so that filename-based plugin discovery (Module::Pluggable search paths built from a namespace string plus a .pm leaf) and loader keys App/Thing.pm stay coherent. Only names that are statically visible are rewritten; a module name assembled at runtime (from user config, directory globbing or string-eval) cannot be followed and must be handled by the app author, so bundles that do that should be packed with --no-rename-modules.

--rename-exports, --no-rename-exports

On by default. With --rename-subs, names in the export/import protocol are renamed in step with the sub they refer to: use ... qw(foo), @EXPORT_OK = qw(foo), $o->can('foo'), $o->import('foo') and the corresponding bareword forms. Pragma import arguments (use lib 'path', use parent, use constant) and any string that is not a single word are left alone. A program that builds method names from other strings at runtime should be packed with --no-rename-exports.

--rewrite, --no-rewrite

Additionally shorten keywords and operators into equivalent forms (foreach -> for, m/.../ -> /.../ after =~/!~, trailing ; before }, $x += 1 -> $x++, $x = $x OP $y -> $x OP= $y, print($x) -> print $x). Opt-in and experimental; --rewrite enables it, --no-rewrite restores the default (off).

When bundleing, --rewrite also renames our-declared package globals across the whole bundle (declaration and all references, fully-qualified $PKG::name or not), since the bundle controls its entire dependency graph. Postfix declarations (return if our $flag) count too. $VERSION/ $AUTOLOAD/@ISA, ALL_CAPS, control-variable ($^...) and single-character names are never renamed, and a global is skipped if its name is a my/ state lexical anywhere in the bundle -- so an unqualified reference can never become ambiguous. Interpolating strings follow the rename while quoted: "$name", qq{_${name}}, <<"EOF" heredoc bodies, <$fh> readlines and backticks are written with the short name (escaped dollars and literal-only tokens stay as they are), so names quoted in templates shrink too.

--compress, --no-compress

Deflate the minified source of each bundled module -- and the boot program (default), or embed them verbatim with --no-compress. Compression happens at install time at the best level with the core Compress::Raw::Zlib module, and the embedded loader (also core-only) decompresses lazily exactly when a module is required (or just before the boot program is evald). How the compressed bytes are stored is picked with "--binary, --no-binary". Raw --no-compress bundles keep the sources and boot program visible and readable, at the cost of a larger file.

A boot-program __DATA__/__END__ section is compressed too: it is split off, bundled on its own, and served through an in-memory handle the loader installs as *main::DATA before the boot program runs (a main::DATA that something already opened is left alone, with a warning). Reading, seek, tell and eof work as usual; the differences are that fileno(DATA) is -1, as there is no OS file descriptor behind it, and that tell counts from the start of the data rather than of the script file.

--binary, --no-binary

Store the compressed sources as escaped binary (the default), or base64-encoded with --no-binary. In binary form only the bytes that could be mangled in transit or by the Perl parser are escaped (CR, LF, ctrl-Z, backslash, the quote), so the payload is about 2% larger than the raw deflate output instead of base64's 33%, making the bundle roughly 25% smaller; the loader also drops the MIME::Base64 dependency. The escaping keeps the payload free of CR, LF and ctrl-Z bytes, so running the bundle is safe on every platform, including Windows text-mode reads.

A binary bundle still contains NUL and high-bit bytes, so treat it as an opaque artifact and move it byte-for-byte: an editor that re-saves it as UTF-8, a copy-paste, or a transfer in text mode corrupts it silently. Use --no-binary when the bundle must stay a plain text file that survives those channels -- checked into a repository and diffed, sent by mail, pasted into a terminal. Neither form makes the sources readable; to inspect or debug what a bundle runs, use --no-compress (and --no-minify for the verbatim sources).

--shebang LINE

The shebang line for the bundle. The default is the boot script's own shebang; a boot script without one (or a -e/-E program) gets #!/usr/bin/env perl, which also works on systems without /usr/bin/perl, such as FreeBSD. The leading #! may be left out.

--no-inline-plugins

Keep Module::Pluggable as a runtime dependency instead of inlining plugins.

--bundle-lib-all

Include every .pm under --lib, even if not referenced. By default only statically-reachable lib modules are bundled; fatlib is always fully included.

--include MODULE

Also bundle MODULE and what it loads, for modules the script loads in a way slimpack can't see, such as a plugin chosen at runtime. Repeat it for more modules. * and ? work as wildcards, so --include 'DateTime::TimeZone::*' takes all of them.

--exclude MODULE

Never bundle MODULE, even when something loads it. Takes the same patterns as --include. Use it to leave out optional parts of a dependency the script never uses.

Moo's Moose support is left out without this: Moo::HandleMoose, which loads Moose, is only bundled when Moose is in the bundle anyway.

-m MODULE

Use MODULE with no imports (like perl -m).

-M MODULE[=list]

Use MODULE, optional import list or version (like perl -M).

-e CODE

Code to bundle; may be repeated (like perl -e).

-E CODE

Same as -e, but enables all features (like perl -E).

AUTHOR

Nicolas Mendoza <mendoza@pvv.ntnu.no>

LICENSE

Artistic License 2.0.

SEE ALSO

App::FatPacker, fatpack, App::SlimPacker