Author image Nickolay Platonov
and 1 contributors


Module::JSAN::Tutorial - more detailed explanation on writing a JSAN module. Its really not that hard (tm).


Version 0.01


In Build.PL:

    use inc::Module::JSAN;
    name            'Digest.MD5';
    version         '0.01';
    author          'SamuraiJack <>';
    abstract        'JavaScript implementation of MD5 hashing algorithm';
    license         'perl';
    requires        'Cool.JS.Lib' => '1.1';
    requires        'Another.Cool.JS.Lib' => '1.2';
    docs_markup     'mmd';

or more relaxed DSL syntax:

    use inc::Module::JSAN::DSL;
    name            Digest.MD5
    version         0.01
    author          'SamuraiJack <>'
    abstract        'JavaScript implementation of MD5 hashing algorithm'
    license         perl
    requires        Cool.JS.Lib             1.1
    requires        Another.Cool.JS.Lib     1.2
    docs_markup     mmd

Standard process for building & installing JSAN modules:

      perl Build.PL
      ./Build test
      ./Build install

Or, if you're on a platform (like DOS or Windows) that doesn't require the "./" notation, you can do this:

      perl Build.PL
      Build test
      Build install


Module::JSAN is a system for building, testing, and installing JavaScript modules. Its based on the Module::Build packaging system, and Module::Build::Functions adapter, which provides more relaxed syntax for building scripts.

To install JavaScript modules, packaged with Module::JSAN, do the following:

  perl Build.PL       # 'Build.PL' script creates the 'Build' script
  ./Build             # Need ./ to ensure we're using this "Build" script
  ./Build test        # and not another one that happens to be in the PATH
  ./Build install

This illustrates initial configuration and the running of three 'actions'. In this case the actions run are 'build' (the default action), 'test', and 'install'. Other actions defined so far include:

  build                 clean                               
  code                  docs
  dist                  distcheck                      
  distclean             distdir                              
  distmeta              distsign                               

  help                  install
  manifest              realclean                                   

You can run the 'help' action for a complete list of actions.


There are some general principles at work here. First, each task when building a module is called an "action". These actions are listed above; they correspond to the building, testing, installing, packaging, etc., tasks.

Second, arguments are processed in a very systematic way. Arguments are always key=value pairs. They may be specified at perl Build.PL time (i.e. perl Build.PL destdir=/my/secret/place), in which case their values last for the lifetime of the Build script. They may also be specified when executing a particular action (i.e. Build test verbose=1), in which case their values last only for the lifetime of that command. Per-action command line parameters take precedence over parameters specified at perl Build.PL time.

The following build actions are provided by default.


If you run the Build script without any arguments, it runs the build action, which in turn runs the code and docs actions.


This action will clean up any files that the build process may have created, including the blib/ directory (but not including the _build/ directory and the Build script itself).


This action builds your code base.

By default it just creates a blib/ directory and copies any .js and .pod files from your lib/ directory into the blib/ directory.


This action is helps module authors to package up their module for JSAN. It will create a tarball of the files listed in MANIFEST and compress the tarball using GZIP compression.

By default, this action will use the Archive::Tar module. However, you can force it to use binary "tar" and "gzip" executables by supplying an explicit tar (and optional gzip) parameter:

  ./Build dist --tar C:\path\to\tar.exe --gzip C:\path\to\zip.exe


Reports which files are in the build directory but not in the MANIFEST file, and vice versa. (See manifest for details.)


Performs the 'realclean' action and then the 'distcheck' action.


Creates a "distribution directory" named dist_name-dist_version (if that directory already exists, it will be removed first), then copies all the files listed in the MANIFEST file to that directory. This directory is what the distribution tarball is created from.


Creates the META.json file that describes the distribution.

META.json is a file containing various bits of metadata about the distribution. The metadata includes the distribution name, version, abstract, prerequisites, license, and various other data about the distribution. This file is created as META.json in JSON format. It is recommended that the JSON module be installed to create it. If the JSON module is not installed, an internal module supplied with Module::JSAN will be used to write the META.json file, and this will most likely be fine.

META.json file must also be listed in MANIFEST - if it's not, a warning will be issued.

The format of META.json file is based on the metadata format for CPAN, the specification of its current version can be found at


Uses Module::Signature to create a SIGNATURE file for your distribution, and adds the SIGNATURE file to the distribution's MANIFEST.


Performs the 'distdir' action, then switches into that directory and runs a perl Build.PL, followed by the 'build' and 'test' actions in that directory.


This action will build a documentation files. Default markup for documentation is POD. Alternative markup can be specified with docs_markup configuration parameter (see Synopsis). Currently supported markups: 'pod', 'md' (Markdown via Text::Markdown), 'mmd' (MultiMarkdown via Text::MultiMarkdown).

Resulting documentation files will be placed under /docs directory, categorized by the formats. For 'pod' markup there will be /doc/html, /doc/pod and /doc/text directories. For 'md' and 'mmd' markups there will be /doc/html and /doc/[m]md directories.


This action will simply print out a message that is meant to help you use the build process. It will show you a list of available build actions too.


This action will install current distribution in your "LOCAL JSAN LIBRARY".


This is an action intended for use by module authors, not people installing modules. It will bring the MANIFEST up to date with the files currently present in the distribution. You may use a MANIFEST.SKIP file to exclude certain files or directories from inclusion in the MANIFEST. MANIFEST.SKIP should contain a bunch of regular expressions, one per line. If a file in the distribution directory matches any of the regular expressions, it won't be included in the MANIFEST. Regular expression should match the full file path, starting from the distribution's root (lib/Your/Module.js, not Module.js)

The following is a reasonable MANIFEST.SKIP starting point, you can add your own stuff to it:

    \b.svn\b            # ignore all SVN directories
    ^\.git\b            # ignore top-level .git directory  

Since # can be used for comments, # must be escaped.

See the distcheck and skipcheck actions if you want to find out what the manifest action would do, without actually doing anything.


This action is just like the clean action, but also removes the _build directory and the Build script. If you run the realclean action, you are essentially starting over, so you will have to re-create the Build script again.


Reports which files are skipped due to the entries in the MANIFEST.SKIP file (See manifest for details)


Unless specified otherwise, a directive is accumulative - it can be used more that once to add value to a list.

All the configuration directives also can be used in DSL notation, with mostly omitted punctuation, including trailing semi-colon. Some of directives have synonyms.


Functions in this section are used when generating metadata for META.json file.



    name 'Useful.Module.Indeed';
    module_name 'Useful.Module.Indeed';

Specifies the name of the main module for this distribution. This will also set the distribution's name.


    dist_name 'useful-module-indeed';

Specifies the name for this distribution. Most authors won't need to set this directly, they can use module_name to set dist_name to a reasonable default. However, generally, distributions may have names that don't correspond directly to their's main module name, so dist_name can be set independently.

This is a required parameter.



    version '0.001_001';

Specifies a version number for the distribution. This is a required parameter.



    abstract        'JavaScript implementation of MD5 hashing algorithm';

This should be a short description of the distribution.



    dist_author 'John Doe <>';
    author 'Jane Doe <>';

This should be something like "John Doe <>", or if there are multiple authors, this routine can be called multiple times, or an anonymous array of strings may be specified.


    license 'lgpl';

Specifies the licensing terms of your distribution. Valid options include:


The distribution is licensed under the Apache Software License (


The distribution is licensed under the Artistic License, as specified by the Artistic file in the standard Perl distribution.


The distribution is licensed under the Artistic 2.0 License (


The distribution is licensed under the BSD License (


The distribution is licensed under the terms of the GNU General Public License (


The distribution is licensed under the terms of the GNU Lesser General Public License (


The distribution is licensed under the MIT License (


The distribution is licensed under the Mozilla Public License. ( or


The distribution is licensed under some other Open Source Initiative-approved license listed at


The distribution may be copied and redistributed under the same terms as Perl itself (this is by far the most common licensing option for modules on CPAN). This is a dual license, in which the user may choose between either the GPL or the Artistic license.


The distribution may not be redistributed without special permission from the author and/or copyright holder.


The distribution is licensed under a license that is not approved by but that allows distribution without restrictions.



    meta_add    'provides', { 'Useful.Module' => { file => 'lib/Useful/Module.js', version => '0.001_010'} };
    meta_merge  'resources', 'bugtracker' => '';

meta_add and meta_merge adds their parameters to the META.json file.

The first parameter is the key to add or merge to, and the second parameter is the value of that key (which may be a string, an arrayref, or a hashref.)

The one difference is that meta_add overwrites anything else in that key, while meta_merge will merge an arrayref or hashref into the current contents of the key.

Also, meta_merge allows a hashref to be ommitted if it contains only one value.

Lists of modules

All lists of modules take a module name (with an optional version) or a hashref that contains a list of modules and versions.

Versions are specified as Module::Build::Authoring specifies them.

If the version parameter is omitted when one module is being added to the list, the version is assumed to be 0.


    requires 'Useful.Module' => 2.17;
    #or in DSL notation
    requires Useful.Module      2.17

Modules listed using this function are required for using the module(s) being installed.


    recommends 'Useful.Module' => 2.17;
    #or in DSL notation
    recommends Useful.Module      2.17

Modules listed using this directive are recommended, but not required, for using the module(s) being installed.


    build_requires 'Useful.Module' => 2.17;
    #or in DSL notation    
    build_requires Useful.Module    2.17

Modules listed using this function are only required for running ./Build itself, not Build.PL, nor the module(s) being installed.


    conflicts 'Useful.Module' => 2.17;
    #or in DSL notation    
    conflicts Useful.Module    2.17

Modules listed using this function conflict in some serious way with the module being installed, and the Build.PL will not continue if these modules are already installed.


Functions listed here are not accumulative - only the last value a flag has been set to will apply.


    create_makefile_pl 'passthrough';
    create_makefile_pl 'small';         #not supported
    create_makefile_pl 'traditional';   #not supported

This function lets you use Module::Build::Compat during the distdir (or dist) action to automatically create a Makefile.PL. The only supported parameter value is 'passthrough', which delegates all actions from Makefile.PL to actions from Build.PL with corresponding names.


    dynamic_config 1;
    dynamic_config 0;

This function indicates whether the Build.PL file must be executed, or whether this module can be built, tested and installed solely from consulting its metadata file. The main reason to set this to a true value is that your module performs some dynamic configuration as part of its build/install process. If the flag is omitted, the META spec says that installation tools should treat it as 1 (true), because this is a safer way to behave.


    sign 1;

If this is set to 1, Module::Build will use Module::Signature to create a signature file for your distribution during the distdir action.

Other functions


    add_to_cleanup 'Useful.Module-*';
    add_to_cleanup 'Makefile';

Adds a file specification (or an array of file specifications) to the list of files to cleanup when the clean action is performed.



Creates the Build.PL to be run in future steps, and returns the Module::Build object created.

This directive should appears the last in the builder script. It can be omitted if script is written in the DSL notation.


    repository '';

Alias for

    meta_merge 'resources', 'repository' => $url 


    bugtracker '';

Alias for

    meta_merge 'resources', 'bugtracker' => $url 


This module uses concept of local JSAN library, which is organized in the same way as libraries for other languages.

The path to the library is resolved in the following order:

1. --install_base command-line argument

2. environment variable JSAN_LIB

3. Either the first directory in $Config{libspath}, followed with /jsan (probably /usr/local/lib on linux systems) or C:\JSAN (on Windows)

As a convention, it is recommended, that you configure your local web-server that way, that /jsan will point at the /lib subdirectory of your local JSAN library. This way you can access any module from it, with URLs like: '/jsan/Test/Run.js'


Nickolay Platonov, <nplatonov at>


Many thanks to Module::Build authors, from which a lot of content were borrowed.


Copyright 2009 Nickolay Platonov, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.