@mapbox/batfish
Version:
The React-powered static-site generator you didn't know you wanted
516 lines (332 loc) • 19.8 kB
Markdown
# Configuration
To use the Batfish CLI, your configuration file should be a Node module that exports a function returning a configuration object.
```js
module.exports = () => {
return { .. };
};
```
(This format mirrors Webpack's configuration setup, which allows for unlimited flexibility and extensibility.)
By default, the Batfish CLI looks for a `batfish.config.js` file in the current working directory.
You can specify an alternate location.
**Below, "project directory" means either**:
- the directory of your configuration module, if one is provided; or
- the current working directory, if no configuration module is provided.
## Table of contents
- [Basic options](#basic-options)
- [siteBasePath](#sitebasepath)
- [siteOrigin](#siteorigin)
- [publicAssetsPath](#publicassetspath)
- [applicationWrapperPath](#applicationwrapperpath)
- [stylesheets](#stylesheets)
- [browserslist](#browserslist)
- [pagesDirectory](#pagesdirectory)
- [outputDirectory](#outputdirectory)
- [temporaryDirectory](#temporarydirectory)
- [Advanced options](#advanced-options)
- [dataSelectors](#dataselectors)
- [vendorModules](#vendormodules)
- [hijackLinks](#hijacklinks)
- [webpackLoaders](#webpackloaders)
- [webpackPlugins](#webpackplugins)
- [webpackStaticIgnore](#webpackstaticignore)
- [babelPlugins](#babelplugins)
- [babelPresets](#babelpresets)
- [babelPresetEnvOptions](#babelpresetenvoptions)
- [babelExclude](#babelexclude)
- [babelInclude](#babelinclude)
- [postcssPlugins](#postcssplugins)
- [fileLoaderExtensions](#fileloaderextensions)
- [jsxtremeMarkdownOptions](#jsxtrememarkdownoptions)
- [includePromisePolyfill](#includepromisepolyfill)
- [inlineJs](#inlinejs)
- [production](#production)
- [developmentDevtool](#developmentdevtool)
- [productionDevtool](#productiondevtool)
- [clearOutputDirectory](#clearoutputdirectory)
- [unprocessedPageFiles](#unprocessedpagefiles)
- [includePages](#includepages)
- [ignoreWithinPagesDirectory](#ignorewithinpagesdirectory)
- [webpackConfigClientTransform](#webpackconfigclienttransform)
- [webpackConfigStaticTransform](#webpackconfigstatictransform)
- [port](#port)
- [verbose](#verbose)
## Basic options
### siteBasePath
Type: `string`.
Default: `'/'`.
**You probably want to set this one.**
Root-relative path to the base directory on the domain where the site will be deployed.
Used by `prefixUrl` and `prefixUrl.absolute` (see ["Prefixing URLs"]).
### siteOrigin
Type: `string`.
**You probably want to set this one.**
Origin where the site will be deployed.
*Required if you want to use `prefixUrl.absolute`* (see ["Prefixing URLs"]).
Also, *required if you want a sitemap*.
### publicAssetsPath
Type: `string`.
Default: `'assets'`
Default folder where batfish assets will be placed for static webpack build (aka `npm run build`)
### applicationWrapperPath
Type: `string`.
Absolute path to a module exporting a React component that will wrap your React application.
The component must be exported with `export default = YourWrapperComponent` or `module.exports = YourWrapperComponent`.
This component will mount only once, wrapping Batfish's `Router` component, which in turn wraps your pages.
### stylesheets
Type: `Array<string>`.
An array of **URLs, filenames, or globs** pointing to stylesheets that you want to include in your site.
If an item is a URL, it must start with `http(s)` and must be publicly available, so Batfish can download it and work it into the CSS optimizations.
If using filenames and globs, provide absolute paths.
*If you need to control the order of your stylesheets, avoid globs.*
Batfish cannot guarantee the order in which files matching your glob will be concatenated.
`url()`s referenced in your stylesheets will be hashed and copied to Batfish's [`outputDirectory`].
### browserslist
Type: `Array<string>`.
Default: `['> 5%', 'last 2 versions']`.
A [Browserslist](https://github.com/ai/browserslist) value to specify which browsers you need to support.
This option is used to process your CSS through [Autoprefixer].
### pagesDirectory
Type: `string`.
Default: project directory + `src/pages/`.
Absolute path to your project's directory of pages.
### outputDirectory
Type: `string`.
Default: project directory + `_batfish_site/`.
Absolute path to a directory where site files should be written.
**You probably want to `.gitignore` this directory.**
### temporaryDirectory
Type: `string`.
Default: project directory + `_batfish_tmp`.
Absolute path to a directory where Batfish will write temporary files.
It must be within the project directory.
**You probably want to `.gitignore` this directory.**
## Advanced options
### dataSelectors
Type: `{ [string]: (Object) => any }`.
An object of selector functions for selecting processing data before it is injected into the page.
Keys are selector names and values are functions that accept an object of build-time data and return a value that can be stringified into JSON.
The object received as an argument contains the following properties:
- `pages`: An array of objects for pages.
Each page object includes the following:
- `path`: The page's URL path.
- `filePath`: Absolute path to the page's file.
- `frontMatter`: Parsed front matter from the page's file.
The return values of `dataSelectors` *must be stringifiable as JSON*.
These values can be used in your components pages by `import`ing modules from `@mapbox/batfish/data/*`.
See ["Injecting data"].
### vendorModules
Type: `Array<string>`.
Identifiers of npm modules that you want to be added to the vendor bundle.
The purpose of the vendor bundle is to deliberately group dependencies that change relatively infrequently — so this bundle will stay cached for longer than the others.
### hijackLinks
Type: `boolean`.
Default `true`.
By default, links are hijacked (with [link-hijacker]) and checked against your site's routes.
If the link targets one of your routes, it will make a client-side change, instead of functioning as a regular link (with a regular page load).
You can prevent this behavior by adding `data-batfish-no-hijack` to the link itself or to any of its descendents.
If you want to disable this link-hijacking altogether, handling it all yourself, you can set this option to `false`.
### webpackLoaders
Type: `Array<Object>`.
Additional loader configuration to pass to Webpack during both Webpack builds (client bundling and HTML generating).
Each object should be a [Webpack Rule](https://webpack.js.org/configuration/module/#rule).
**Warning:** You may need remove the extensions for files your new loader(s) handles from [`fileLoaderExtensions`](#fileloaderextensions).
### webpackPlugins
Type: `Array<Object>`.
Additional plugin configuration to pass to Webpack during the client bundling task.
### webpackStaticIgnore
Type: [Webpack `Condition`].
Any modules matching this description will be ignored (with the [ignore-loader](https://github.com/cherrry/ignore-loader)) during the static Webpack build.
**Any dependencies that cannot execute in Node (e.g. because they reference `window` or `document`) should be targeted by this option.**
You may need to other precautions, as well.
But most of the time, this will help you use browser-only libraries without breaking your static build.
### babelPlugins
Type: `Array<string>`. Default: `[]`.
Additional plugins to pass to Babel during both Webpack builds (client bundling and HTML generating).
**You should `require.resolve()` your plugins.**
Otherwise, Babel might end up looking in the wrong place for the npm package.
*(The prior recommendation to `require` plugins is deprecated. Instead of `require`ing plugins you should `require.resolve` them.)*
For example:
```js
{ babelPlugins: [require.resolve('babel-plugin-transform-fancy-syntax')] }
```
Plugins you provide are concatenated to the following default plugins:
- Always
- [babel-plugin-syntax-dynamic-import](https://babeljs.io/docs/plugins/syntax-dynamic-import/)
- [babel-plugin-transform-class-properties](https://babeljs.io/docs/plugins/transform-class-properties/)
- [@mapbox/babel-plugin-transform-jsxtreme-markdown](https://github.com/mapbox/jsxtreme-markdown/tree/master/packages/babel-plugin-transform-jsxtreme-markdown): See [`jsxtremeMarkdownOptions`].
- Development only
- [babel-plugin-transform-react-jsx-source](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source)
- [babel-plugin-transform-react-jsx-self](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-self)
- Production only
- [babel-plugin-transform-react-remove-prop-types](https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types)
### babelPresets
Type: `Array<string>`. Default: `[]`.
Additional presets to pass to Babel during both Webpack builds (client bundling and HTML generating).
**You should `require.resolve()` your presets.**
Otherwise, Babel might end up looking in the wrong place for the npm package.
*(The prior recommendation to `require` presets is deprecated. Instead of `require`ing presets you should `require.resolve` them.)*
For example:
```js
{ babelPresets: [require.resolve('babel-preset-magic')] }
```
The two presets [babel-preset-react] and [babel-preset-env] are automatically applied.
You can pass options to [babel-preset-env] with the option [`babelPresetEnvOptions`].
### babelPresetEnvOptions
Type: `Object`. [Options for babel-preset-env].
[babel-preset-env] is always used.
By default, it is passed no options.
That means the latest standard syntax will be available (not `stage-x`): `es2015`, `es2016`, etc..
Use this option to further customize your build by passing any of the other many [options for babel-preset-env](https://babeljs.io/docs/plugins/preset-env/#options).
### babelExclude
Type: [Webpack `Condition`].
Default: `/[/\\\\]node_modules[/\\\\]/`. (A nasty regular expression that excludes all nested `node_modules`.)
By default, all packages installed by npm are excluded from Babel compilation (see [`babelExclude`]).
If you'd like to change that (e.g. to exclude more files), provide a valid [Webpack `Condition`].
Make sure your condition somehow excludes the majority of `node_modules` from compilation, or your builds could slow down dramatically.
### babelInclude
Type: `Array<string | Condition>`.
Default: `[]`.
By default, all packages installed by npm are excluded from Babel compilation (see [`babelExclude`]).
If, however, you use a library that includes ES2015+ but does not get compiled for publication (e.g. any of the [promise-fun](https://github.com/sindresorhus/promise-fun) modules), then you'll need to pass that module through Babel.
That's what this option is for.
The easiest way to include an npm package in your compilation is to pass its name as a string.
But if you have more complex needs, any valid [Webpack `Condition`] will work here.
All conditions will be combined with `test: /\.jsx$/` so only `.js` or `.jsx` files are compiled.
Some examples:
To compile `p-queue`:
```js
[`p-queue`]
```
To compile both `p-queue` and `@mapbox/mapbox-gl-style-spec` *except for* its `dist/` directory and any nested `node_modules`:
```js
[
'p-queue',
{
include: path.resolve(__dirname, 'node_modules/@mapbox/mapbox-gl-style-spec'),
exclude: [
path.resolve(
__dirname,
'node_modules/@mapbox/mapbox-gl-style-spec/dist'
),
path.resolve(
__dirname,
'node_modules/@mapbox/mapbox-gl-style-spec/node_modules'
)
]
}
]
```
### postcssPlugins
Type: `Array<Function> | Function`.
Default: [Autoprefixer].
All of the CSS you load via [`stylesheets`] is run through [PostCSS](http://postcss.org/), so you can apply any [PostCSS plugins](https://github.com/postcss/postcss/blob/master/docs/plugins.md) to it.
By default, only [Autoprefixer] is applied.
If a function is provided, it will receive the default array as an argument and should return a new array.
A transform function is probably preferable if you only need to add or remove an item or two from the default array.
### fileLoaderExtensions
Type: `Array<string> | Function`.
Default: `['jpeg', 'jpg', 'png', 'gif', 'webp', 'mp4', 'webm', 'woff', 'woff2']`.
An array of extensions for files that you would like to Webpack's [file-loader](https://github.com/webpack-contrib/file-loader).
If a function is provided, it will receive the default array as an argument and should return a new array.
A transform function is probably preferable if you only need to add or remove an item or two from the default array.
### jsxtremeMarkdownOptions
Type: `Object`.
Markdown pages are passed through [jsxtreme-markdown-loader](https://github.com/mapbox/jsxtreme-markdown-loader), which runs the Markdown through [`jsxtremeMarkdown.toComponentModule`].
This option is passed directly to [`jsxtremeMarkdown.toComponentModule`].
Please read the documentation for [`jsxtremeMarkdown.toComponentModule`'s `options`](https://github.com/mapbox/jsxtreme-markdown#options-1) for complete details.
But here are some of the options you are more likely to want to use with Batfish:
- `remarkPlugins` and `rehypePlugins` allow you provide [remark](https://github.com/wooorm/remark) and [rehype](https://github.com/wooorm/rehype) plugins, which get applied as your Markdown is converted to a React component.
There are a wide variety of plugins, from header slug insertions to Markdown syntax extensions to code block syntax highlighting and so on.
- `prependJs` allows you to prepend JS to *every* Markdown page in your site.
For example, if you have a utility function that you want to make available to every Markdown page, you can use this option to `import` it.
### includePromisePolyfill
Type: `boolean`.
Default: `true`.
Webpack and Batfish both rely on Promises, so if you want to support IE11 you'll need a Promise polyfill.
By default, [es6-promise](https://github.com/stefanpenner/es6-promise)'s auto-polyfill is inserted at the beginning of the vendor bundle.
**If you'd like to use your own Promise polyfill, you should set this option to `false`** (e.g. if [core-js](https://github.com/zloirock/core-js) is throwing in polyfills via some Babel tool or other).
### inlineJs
Type: `Array<Object>`.
If you want to inline JS into static HTML before the Webpack bundle, this is the best way to do it.
On the development server, they will be added at the beginning of the Webpack bundle for debugging (sourcemaps should be available).
For the static build, they will be injected directly into the `<head>`.
Each item is an object with the following properties:
Type: - **filename** `string` path to the JS file.
Type: - **uglify** `boolean`: `true`. Whether or not to process the file with [UglifyJs] before inserting into the `<head>` during the static build.
### production
Type: `boolean`.
Default: `false` for `start`, `true` for `build`.
Whether or not to build for production (e.g. minimize files, trim React).
### developmentDevtool
Type: `string | false`.
Default: `'cheap-module-source-map'`.
A [Webpack devtool value](https://webpack.js.org/configuration/devtool/#devtool).
The Webpack docs explain the benefits and drawbacks of each.
### productionDevtool
Type: `string | false`.
Default: `false`.
A [Webpack devtool value](https://webpack.js.org/configuration/devtool/#devtool).
The Webpack docs explain the benefits and drawbacks of each.
### clearOutputDirectory
Type: `boolean`.
Default: `true`.
By default, the [`outputDirectory`] will be cleared before `start` and `build` execute.
Set this to `false` to leave the [`outputDirectory`] as it is and only add files to it.
### unprocessedPageFiles
Type: `Array<string>`.
An array of globs **relative to the [`pagesDirectory`]**.
By default, all `.js` and `.md` files within the [`pagesDirectory`] are processed as pages, producing HTML files at their paths.
If you would like instead to copy `.js` or `.md` files as static files, without creating corresponding HTML files, use this option.
For example, if you have a `scripts/` directory and all the `.js` files within it are *not* pages, but are static JavaScript files that you want to expose at `/scripts/*.js` URLs, you could set `unprocessedPageFiles` to `['scripts/**/*.js']`.
### includePages
Type: `Array<string>`.
An array of globs indicating the pages of your site that you want to build.
You can use this option during development to speed up your builds by only building the specified pages.
Fewer files will be fed into Webpack, which means the build will go faster.
This is the option that `batfish start --include` manipulates; typically, you'll interface with this option that way, instead of setting it directly in your configuration.
**You should only use this option during development.**
### ignoreWithinPagesDirectory
Type: `Array<string>`.
An array of globs **relative to the [`pagesDirectory`]**.
By default, all files within the [`pagesDirectory`] that are *not* `.js` and `.md` files are copied to corresponding paths in the [`outputDirectory`].
(See ["Non-page files within the pages directory"] for why you might use this feature.)
Sometimes, however, you want to colocate files with your pages and *do not* want those files to be copied into the [`outputDirectory`], because you don't want them to available at public URLs when you deploy your site.
This option allows you to provide globs specifying files in the [`pagesDirectory`] that should *not* be copied.
For example, if you have HTML files in your [`pagesDirectory`] that your JS pages will import with [Webpack's raw-loader], you could prevent them from being copied to the [`outputDirectory`] with `ignoreWithinPagesDirectory: ['**/*.html']`.
### webpackConfigClientTransform
Type: `Function`.
The Webpack config for client-side bundles will be passed through this function before it's used.
**Only use this option if you know what you're doing!**
You need to be careful not to change configuration that Batfish relies on.
### webpackConfigStaticTransform
Type: `Function`.
The Webpack config for static, server-side bundling will be passed through this function before it's used.
**Only use this option if you know what you're doing!**
You need to be careful not to change configuration that Batfish relies on.
### port
Type: `number`.
Default: `8080`.
Preferred port for development servers.
If the specified port is unavailable, another port is used.
### verbose
Type: `boolean`.
Default: `false`.
If `true`, more information will be logged to the console.
[uglifyjs]: https://github.com/mishoo/UglifyJS2
[autoprefixer]: https://github.com/postcss/autoprefixer
["prefixing urls"]: ../README.md#prefixing-urls
[`outputdirectory`]: #outputdirectory
[`pagesdirectory`]: #pagesdirectory
[`stylesheets`]: #stylesheets
[`babelexclude`]: #babelexclude
[`jsxtrememarkdownoptions`]: #jsxtrememarkdownoptions
["injecting data"]: ./advanced-usage.md#injecting-data
[`jsxtrememarkdown.tocomponentmodule`]: https://github.com/mapbox/jsxtreme-markdown#tocomponentmodule
[link-hijacker]: https://github.com/mapbox/link-hijacker
[webpack `condition`]: https://webpack.js.org/configuration/module/#condition
[babel-preset-react]: https://babeljs.io/docs/plugins/preset-react/
[babel-preset-env]: https://babeljs.io/docs/plugins/preset-env/
[`babelpresetenvoptions`]: #babelpresetenvoptions
[options for babel-preset-env]: https://babeljs.io/docs/plugins/preset-env/#options
["non-page files within the pages directory"]: ../README.md#non-page-files-within-the-pages-directory
[webpack's raw-loader]: https://github.com/webpack-contrib/raw-loader