Creating Packages

Packages are defined by a package.json file that specifies a package. It defines the package name, version, author details and dependencies. The format is specified by CommonJS and also used by the NPM and you should be able to use a single package.json file for both Pak and NPM if you wish.

Creating package.json

You can create a package.json file with pak init

$ pak init

This will generate a stub package.json that you can edit to reflect the details of your package.

For example:

{
    "name": "Package name - one word"
    "description": "Package description - one line"
    "version": "1.2.3",
    "keywords": [
        "comms", "websockets", "sockets", "ssl",
    ],
    "author": {
        "name": "Your name",
        "email": "Your email",
        "url": "Your web site"
    },
    "bugs": {
        "email": "name@example.com",
        "url": "http://example.com/bugs"
    },
    "license": "GPL",
    "dependencies": {
        "jquery": "1.9.x",
        "angular": "~1.2",
    },
    "files": [
        "dist/**"
    ],
    "ignore": [
        "*.tmp"
    ],
    "pak": {
        "import": true,
        "mode": "debug"
    }
}

At a minimum, a package.json must have a name, description and version. Other fields are optional. Versions follow the Semver 2 standard. i.e. major.minor.patch[-pre-release]. See Package Versions for more details.

Standard Fields

Pak Configuration Properties

Pak defines some properties in the package.json file under the pak property. All other property names under the pak property are reserved. If you need custom configuration settings for your application, you should create your own top-level package.json property set.

NameDescription
blendProperties to blend from a package into the application package.json when installing the package.
exportExport instructions to export package files from the paks directory into the application's lib directory.
frozenDefine the package as frozen and impervious to upgrades.
importEnable exporting of package conents when installing packages. Defaults to false.
manageArray of external json files to manage by blending their properties when installing the package.
modeApplication execution mode. Selects a property set from the pak.modes collection and copy to the top level.
modesProperties to be blended into the top-level application package.json.
originLocation of the package in the Pak cache.
overrideLocal overrides for package package.json properties.
preciousProtect a package in the cache from pruning unless forced.
versionPak program version (expression) required by this package.

Selecting Package Files

When creating a package, you need to specify which files should go into the package. Often you have local files that you do not want to publish. Use the files property to specify the files that should be in the package and use the ignore property to specify the files to keep out. These properties may be filename patterns that optionally include wild cards, or they may be arrays of patterns. For example:

{
    "files": [
        "dist/js/*",
        "dist/css/*",
        "dist/less/**",
        "!dist/less/demo/**"
    ]
    "ignore": [
        "*.tmp"
    ]
}

You can use the ** wild card to match files in all subdirectories, and use ! to negate a pattern and exclude files from the set. When Pak publishes a package, it will always include the package.json, README.md and LICENSE.md files. You do not need to specify these files.

Locations

During package installation, the package contents will be cached under ~/.paks/PACKAGE/ACCOUNT/VERSION, where PACKAGE is the name of the package, ACCOUNT is the GitHub account name or @npm if the package is being hosted on NPM. Once installed in an application, the package files will be saved under the paks/PACKAGE local directory.

Exporting Runtime Files

Often a package will have some files that are used during development and some that are used to run the application. Pak supports exporting runtime files so the application can easily deploy just the runtime application separate from the development time files.

Package files that are only needed for development can be accessed from the paks/PACKAGE directory. For example: Less or Sass stylesheets can be accessed under the paks directory and do not need to be exported. Runtime files are exported to the lib/PACKAGE directory.

Export Instructions

A package can define export instructions that specify exactly which files to export and where to export the files. While this is useful for many packages, it is especially useful when creating meta-packages that wrap existing third-party packages for which you cannot modify.

Export instructions in a package.json file may be specified two ways:

Export properties provide a simple, and flexible means of selecting and remapping the files to export. You specify the file patterns to export, the destination directory and other optional processing instructions. For example:

"export": {
    "from": [
        "src/js/**",
        "src/css/**",
    ],
    "to": "lib/myapp",
    trim: 1
    "overwrite": true,
}

This copies the files under src/js and src/css to the lib/myapp directory after trimmming one segment off the path. i.e. this trims the src segment from the filenames. The result will be the directories lib/myapp/js and lib/myapp/css.

You may also use these conventient short forms. For example:

"export": "*.js"

"export": [ "*.js", "**.css" ]

The export property can be set to a string, an array of strings, an object instruction, or an array of object instructions. In the example above, the **.css selects all CSS files in any subdirectory.

File Destinations

The to property defines the destination directory relative to the lib/PACKAGE directory for the package. You may use ${TOP} to refer to the top application directory and thus export files outside of the lib directory.

Export Properties

The full set of export properties are:

PropertyDescription
from Filename patterns to copy. May be a string or array of strings. May include wild-cards.
overwrite If false, then files will only be exported once if they do not already exist. This prevents upgrades from overwriting files.
to Optional target directory for the files. Defaults to lib/PACKAGE where PACKAGE is the name of the package. Use ${TOP} for the application's top directory and ${LIB} for the application's export lib directory.
trim Number of directory components to trim from filenames when exporting.

Wild Cards

The from property value (or the export property if it is set to a simple string) may contain wild cards. The following wild cards are supported.

Scripted Export

If you have export needs that go beyond what can be expressed via export properties, you can also use the full scripting power of Ejscript to create custom export scripts. For example:

"export": {
    "script": `
        let path = Path('paks/jquery')
        for each (file in path.files(['**/*.js'])) {
            if (file.contains('min.js')) {
                continue
            }
            path.copy('lib/jquery/' + file.basename)
        }
    `
}

Extended JSON

Pak supports an extended JSON syntax where multi-line strings can be used. Strings can be delimited by single, double or back quote characters. Also, property names do not need to be quoted. However, if you are using the package.json for any other purposes, you may need to use strict JSON with single line strings only. In this case, it may be easier to put your export script in a separate file.

For example:

 "export": {
    "script": "load('export.js')"
}

Blending Package Configuration

Pak provides JSON blending services for packages to merge JSON configuration from packages into an application. This feature can help automate the installation and configuration of packages. For example: the Expansive web site generator uses this facility to blend expansive.json configuration files from packages such as skeletons and plugins.

Blending is a process of merging a package's JSON properties into the application. Blending may occur from the package's package.json file or external files may be blended.

Blending Files

The pak.manage property can list an array of file to blend. For example:

"pak": {
    "manage": [
        "expansive.json",
        "esp.json"
    ] 
}

When a package containing this definition is installed, the package's expansive.json and esp.json files will be blended into files of the same name in the applications directory. If the files do not exist, they will be created.

Blending Properties

The pak.blend property collection specifies a collection of properties that are to be blended into the top level of the application's package.json.

"pak": {
    "blend": {
        "pak": {
            "?mode": "debug",
            "?import": true,
        }
    }
}

This will define the pak.mode and pak.import properties in the application's package.json file if they do not already exist.

Property Blend Prefixes

Properties from the package's JSON file are created, added, subtracted or set in the application package.json file. To assist with blending, properties can have prefixes to control the blending.

PrefixDescription
+Add elements to existing arrays
-Remove elements to existing arrays
=Replace existing properties of the same name
?Create only if the property does not already exist

Want More?

For more details, see:

© Embedthis Software, 2003-2015. All rights reserved.