Creating Packages
Packages are defined by a pak.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 package.json file.
Creating pak.json
You can create a pak.json file with pak init
$ pak init
This will generate a stub pak.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" ], "import": true, "profile": "debug" }
At a minimum, a pak.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
dependencies — List of packages and the acceptable versions. Version fields may include expressions that describe a range of acceptable versions. For example:
Topic Description version (allows prereleases) ^version (same as >=1.2.3 <2.0.0, does not allow prereleases) ~version (same as >=1.2.3 <2.0.0, allows prereleases) 1.2.X (any version starting with 1.2 (allows prereleases) >, >=, <, <=, ==, != version Version expression expression || expression either expression qualifies expression && expression both expressions must qualify expression expression same as && - files — list of files to include when caching and installing the package. These are applied before considering export definitions.
- ignore — list of files to exclude when caching and installing the package. These are applied before considering export definitions.
Pak Configuration Properties
All property names under the pak property are reserved. If you need custom configuration settings for your application, you should create your own unique top-level pak.json property.
Name | Description |
---|---|
blend | Properties to blend from a package into the application pak.json when installing the package. |
export | Export instructions to export package files from the paks directory into the application's lib directory. |
frozen | Define the package as frozen and impervious to upgrades. |
import | Enable exporting of package conents when installing packages. Defaults to false. |
manage | Array of external json files to manage by blending their properties when installing the package. |
origin | Location of the package in the Pak cache. |
override | Local overrides for package pak.json properties. |
precious | Protect a package in the cache from pruning unless forced. |
profile | Application execution profile. Selects a property set from the profiles collection and copy to the top level. |
profiles | Properties to be blended into the top-level application pak.json. |
version | Pak 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 pak.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 pak.json file may be specified two ways:
- Export properties
- Export scripts
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:
Property | Description |
---|---|
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.
- The wildcard ? matches any single character.
- * matches zero or more characters in a filename or directory.
- ** matches zero or more files or directories and matches recursively in a directory tree.
- ! Negates pattern. This removes matching patterns from the set. These are applied after all source patterns have been processed.
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 pak.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 pak.json file or external files may be blended.
Blending Files
The pak.manage property can list an array of file to blend. For example:
{ "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 pak.json.
{ "blend": { "?profile": "debug", "?import": true, } }
This will define the profile and import properties in the application's pak.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 pak.json file. To assist with blending, properties can have prefixes to control the blending.
Prefix | Description |
---|---|
+ | 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: