Advanced
Creating binary files
A binary is an executable file distributed in an npm package via the bin field. Packemon offers first class support for binary files by:
- Prepending a
#!/usr/bin/env node
shebang to the output file. Do not include this in the source file! - Updating the
bin
field inpackage.json
to the output file (if not already defined).
To make use of this functionality, you must define an input with the name
bin
, or store your bins in a bin
directory.
{
"name": "package",
"packemon": {
"inputs": {
"bin": "src/bin.ts"
},
"platform": "node"
}
}
The contents of the binary source file can be whatever you want, but do be aware that code in the module scope will be executed immediately when the file is executed by Node.js.
Customizing Babel, swc, and Rollup
This is an advanced escape hatch and should be avoided unless absolutely necessary, for example, processing CSS files in a way that Packemon does not support.
Customizing the Babel, swc, and Rollup configs are an opt-in feature, and require the following conditions to be met:
- A
--loadConfigs
option is passed on the command line. This enables searching and loading of config files, otherwise, we want to avoid the filesystem lookups. - A
packemon.config.{ts,js}
file at the monorepo/polyrepo root, which applies customizations to all packages. Or optional.packemon.{ts,js}
files within each package, which applies customizations to that package individually. An example of this is found below, or view the @boost/config docs.
- Polyrepo
- Monorepo
/
├── src/
├── package.json
├── packemon.config.js
├── LICENSE
└── README.md
/
├── packages/
│ ├── foo/
│ | ├── src/
│ | ├── .packemon.js
│ | ├── package.json
│ | ├── LICENSE
│ | └── README.md
│ ├── bar/
│ | ├── src/
│ | ├── .packemon.js
│ | ├── package.json
│ | ├── LICENSE
│ | └── README.md
│ └── baz/
│ ├── src/
│ ├── .packemon.js
│ ├── package.json
│ ├── LICENSE
│ └── README.md
├── lerna.json
├── package.json
├── packemon.config.js
├── LICENSE
└── README.md
Both of these config files have the same structure, and may define the fields below. All of these
fields require a function (except swc
), which is passed the finalized config as an argument (with
output fields also accepting the current build as the 2nd argument). This config can then be mutated
in place.
babelInput
- For parsing syntax into an AST (TypeScript, JSX, etc).babelOutput
- For applying transformations.rollupInput
- For defining inputs, outputs, and more.rollupOutput
- For customizing each output.swc
- Enables swc instead of Babel.swcInput
- For parsing syntax into an AST (TypeScript, JSX, etc).swcOutput
- For applying transformations.
- TypeScript
- JavaScript
import type { ConfigFile } from 'packemon';
import linaria from '@linaria/rollup';
const config: ConfigFile = {
babelOutput(config, build) {
config.presets.push('@linaria/babel-preset');
},
rollupInput(config) {
config.plugins.unshift(linaria());
},
};
export default config;
const linaria = require('@linaria/rollup');
module.exports = {
babelOutput(config) {
config.presets.push('@linaria/babel-preset');
},
rollupInput(config) {
config.plugins.unshift(linaria());
},
};
We suggest not mutating the config that Packemon generates, as it may break our assumptions. Instead, prefer to only apply additions that add new functionality.
Stamping releases
For situations where you update Packemon and want to release every package, even those that have
not been modified since the last release, you can use stamping. Stamping is a very simple concept
where we modify the package.json
of each package with a release
timestamp, and can be achieved
by passing --stamp
to the build
or pack
commands.