Configuration
Overview
Currently Fastpack only accepts the configuration as command-line arguments. The reason for it is simplicity and ease-of-use. We are thinking on some other possible options (JSON/YAML/TOML configuration, guessing the proper configuration), but all of those seem to be either clunky or too magical. Moreover, you can easily emulate the "configuration file" using the simple Shell scripting:
$ cat ./build.sh
#!/bin/bash
fpack \
./ui/index.js \
-o build \
-w \
--dev \
--nm "$(pwd)/node_modules" \
--nm node_modules \
--preprocess='^ui/.+\.js$' \
--preprocess='^node_modules/components/.+\.js$'
Overall, we try to maintain the strict policy of adding new configuration parameters - only add them if it is unavoidable. We have given up on the "zero configuration" idea, but still trying to preserve the simplisity as much as we can.
Please note, fastpack is under heavy development now and these APIs are not anywhere close to be absolutely stable. Very likely, there will be breaking changes and additions in future releases.
Commands
Fastpack delivers 3 basic commands for a typical tasks: build
, watch
, and serve
. To get help om any of this, you can use the --help
flag, like this:
$ fpack --help
NAME
fpack - Pack JavaScript code into a single bundle
SYNOPSIS
fpack COMMAND ...
COMMANDS
PLEASE NOTE: production mode is temporarily disabled. In the meantime,
please always use the `--development` flag.
build
rebuild the bundle on a file change
help
Show this message and exit
serve
watch for file changes, rebuild bundle & serve
watch
watch for file changes and rebuild the bundle
...
Or for a specific command:
$ fpack serve --help
NAME
fpack-serve - watch for file changes, rebuild bundle & serve
SYNOPSIS
fpack serve [OPTION]... [ENTRY POINTS]...
ARGUMENTS
ENTRY POINTS
Entry points. Default: ['.']
OPTIONS
-d, --debug
Print debug output
--development
Build bundle for development
build
This is the main command. Currently all the other commands run the build
behind the scenes. Since this command is the most used - it could be omitted.
I.e. these calls are identical:
$ fpack --dev index.js
$ fpack build --dev index.js
watch
This is useful in development when you want the bundle to be updated as you change the code. Example:
$ node_modules/.bin/fpack watch --dev index.js
Packed in 0.125s. Bundle: 5.29Mb. Modules: 1124. Cache: used. Mode: development.
Watching directory: /Users/zindel/demo
(Ctrl+C to stop)
Packed in 0.090s. Bundle: 5.29Mb. Modules: 1124.
serve
This is the watch mode combined with the serving of the latest bundle. This is very much inpired by the create-react-app. I.e.:
- the static content of the
public/
directory will be served at the server root - the
public/index.html
will be modified by including the<script>...</script>
required to serve the bundle - by default the URL to access it is
http://localhost:3000
, but you can change the port using the--port
argument
Example:
$ node_modules/.bin/fpack serve --port 8181 --dev index.js
Server running at http://localhost:8181
Packed in 0.131s. Bundle: 5.29Mb. Modules: 1124. Cache: used. Mode: development.
Watching directory: /Users/zindel/demo
(Ctrl+C to stop)
Packed in 0.090s. Bundle: 5.29Mb. Modules: 1124.
Common Arguments
project directory
The working directory fpack
binary was executed from. Typically, this will be
the root of your project containing the package.json
, other configuration
files, and the source code. You cannot require/import the module outside of the
project directory. This is done for security reasons, so that
require('../../etc/passwd')
is impossible. If you really need to access some
outside files, create the symlink inside and use it in require()
or import
statements.
entry points
The list of positional arguments to the fpack
binary. For example:
$ fpack '.' ui/index.js some-module
Defaults to ['.']
. '.'
resolves in a following way:
- if
package.json
exists in the project directory, then following values will be used this order (first non-empty):"module"
,"main"
; - if nothing of the above worked - use
index.js
.
There is one little trick fpack
accounts for considering the entry point.
These 2 forms are considered identical, when specifying the entry point:
./lib/index.js
and lib/index.js
. This is done in order to simplify
command-line usage and Tab-completion.
--development
Please make sure to always specify this flag for the moment. (Will be fixed in future releases)
By default fpack
runs in production mode:
process.env.NODE_ENV
is replaced with the"production"
string;- all conditionals using
process.env.NODE_ENV
patched in a way that only "production" branch remains in the code; - bundle is built in a flat way, removing the module structure, appying tree-shaking, and pre-optimizing for minification (much like Rollup does).
- persistent cache is not used.
In development mode:
process.env.NODE_ENV
is replaced with the"development"
string;- all conditionals using
process.env.NODE_ENV
patched in a way that only "development" branch remains in the code; - bundle is built in a scoped way, i.e. the Object containing all the modules and dependencies between those;
- development bundles are easier and faster to build;
- watching the filesystem only takes effect when executed in development mode.
--output
Output directory. Defaults to ./bundle
. Shortcut: -o
.
--target
Build target. Defaults to app
. Possible values:
- app: application target. No additional code generated.
- esm: EcmaScript modules target. One
export
statement is generated listing all the symbols from the first entry point - cjs: CommonJS target.
module.exports = require('first entry point');
statement is added to the end of the bundle.
--mock
Replace module requests with certain substitution. Here is an example which illustrates the usage:
$ fpack --dev index.js \
--mock fs \
--mock path:path-browserify \
--mock assert:./my-assert-implementation.js
In the command above, the first --mock fs
makes all require('fs')
or
import ... from 'fs'
to be resolved into the empty module. The second one
uses the path-browserify
package in place of the path
accross the code. The
last one uses the local file for the same purpose.
--resolve-extension
Provide extensions to be considered by the resolver for the extension-less path. Extensions will be tried in the specified order. If no extension should be tried, provide '' as an argument. Defaults to [.js, .json]
Example:
$ fpack --dev index \
--resolve-extension ts \
--resolve-extension tsx \
--resolve-extension js
The example above will make resolver these names (in exact order): index.ts
,
index.tsx
, index.js
--project-root
Ancestor to which module requests will be resolved. Defaults to '.'
This becomes especially useful with the monorepo setup. For example, let's say
the monorepo shares the same node_modules
for the packages a
& b
:
/monorepo $ tree
|-- a
| |-- index.js
| `-- package.json
|-- b
| |-- index.js
| `-- package.json
`-- node_modules
Now, to build the a
you can do the following:
/monorepo/a $ fpack --project-root ../ --dev index.js
--preprocess
Preprocess the file before adding it to the bundle. Can be added multiple
times. Has the following form: PATTERN:PROCESSOR?OPTIONS[!...]
:
PATTERN
is the PCRE regular expression which will be applied to filename to check if processor should be applied to it.PATTERN
is applied to a filename excluding the project-directory. For example/my/project/lib/index.js
will match the regexp^lib.+js$
, but not^/my.+js$
.PROCESSOR
is one ofbuiltin
or Webpack loader.builtin
provides the set of JavaScript transpilers: stripping Flow types, object spread & rest operators, class properties (including statics), class/method decorators, and React-assumed JSX conversion.builtin
could be omitted, i.e.\.js$
and\.js$:builtin
are equal.- Webpack loader may accept some options in a form
'x=y&a=b
. - You can apply several preprocessors to one file separating them using the
!
. In this case preprocessors are applied right to left.
Here is an example of packing the create-react-app-based application in development mode:
fpack src/index.js \
--development \
--preprocess='^src.+\.js$' \
--preprocess='\.svg$:url-loader' \
--preprocess='\.css$:style-loader!css-loader?importLoaders=1!postcss-loader?path=postcss.config.js'
And production:
fpack src/index.js \
--preprocess='^src.+\.js$:babel-loader?filename=.babelrc' \
--preprocess='\.svg$:file-loader?name=static/media/[name].[hash:8].[ext]&publicPath=http://localhost:4321/pack-cra/prod/' \
--preprocess='\.css$:style-loader!css-loader?importLoaders=1!postcss-loader?path=postcss.config.js'
--node-modules
Provide the list of 'node_modules' locations. Defaults to [node_modules]
. If
absolute path is specified, it is taken as is, otherwise every parent directory
is searched up to the project-directory.
Shortcut: --nm
.
--no-cache
Do not use persistent cache. Has no effect in the production mode since persistent cache is not used anyway.
--debug
Print debugging output.
--version
Display version and exit.
--help
Display help message.