What is servant.json file?

What is servant.json file?

Main configuration file for Servant. It's used for modules and package definition. In this file there is described some properties that Servant needs to known. Lots of properties are not required, because Servant can derive it from package.json, but some needs to be defined to proper Servant work.

There is example of the smallest config file

Module servant.json

{
  "output": {
    "directory": "./dist",
    "filename": "servant.js"
  },
  "entry": "./src/index",
  "target": "node"
}

Of course, this config file can be even smaller for subproject, because config files are merged from parent to child module. So you can define one definition for all modules and then override only changed.

Main servant.json

{
  "package": "servant",
  "target": "node",
  "modules": [
    "servant*/",
  ],
  "entry": false,
  "output": {
    "directory": "./dist"
  },
  "src": [
    "src/**/*"
  ],
  "tests": [
    "tests/**/*"
  ],
}

Submodule servant.json

{
  "output": {
    "filename": "servant.js"
  },
  "entry": "./src/index"
}

For all modules all paths and structure of project will be same. Same src and tests paths, same target and some output folder. Only bundled name and entry point is defined for every module. And that's all.

But, there is more to configure in servant.json. Structure and all properties of servant.json are described below.

Structure of servant.json

This is an example structure of servant json. It's used for loading data about project structure and automatically generation of webpack config and jasmine config.

      {
        "package": "package-name",
        "modules": ["module-*/"],
        "output": {
          "directory": "./dist",
          "filename": "package-name-dist.js",
          "resolve": ["js"]
        },
        "entry": "./index",
        "test": "tests/index",
        "src": ["src/**/*"],
        "tests": ["test/**/*", "tests/**/*"],
        "resolve": ["ts", "js", "tsx", "jsx"],
        "resources": ["fonts/*", "images/*", "npm:react//umd/react.production.min.js"],
        "clean": ["js.map"],
        "prettify": {
            "sources": ["doc/**/*", "fixtures/**/*"],
            "extensions": ["md", "json"]
        },
        "temp": ".temp",
        "libraries": {
          "simple-git/promise": "simple-git/promise"
        },
        "mappings": {
          "react": "./umd/react.production.min.js",
          "@resources/fonts": false
        },
        "target": "node-cli",
        "publish": {
          "increment": "patch",
          "access": "public",
          "stripDev": true,
          "commitMessage": "Incrementing version by '$increment' number. New version is '$version'."
        },
        "registry": "https://registry.npmjs.org",
        "issues": {
          "#([0-9]{1,})": "http://issue-tracker.rg/id/$0"
        },
        "testing": {
            "browsers": ["Webkit", "Firefox", "Chromium"],
            "devices": ["iPad Mini", "iPhone 6"]
        },
        "server": {
          "entries": {
             "package-name": {
               "title": "Debug Server for package-name",
               "template": "./package-name/template.html"
             }
          },
          "css": ["http://fonts.googleapis.com/css?family=Open+Sans", "./globals/styles.css"],
          "js": ["https://code.highcharts.com/highcharts.js"]
        }
      }

INFO

There is available JSON schema mapping for servant.json. If you install package is available in /dist/servantJson.schema.json or in gitlab.

Property "package": string

Name of whole package. Is used only for printing this name into Servant console. If field is not provided, it's load from package.json "name" field.

Default: package.json name field or ""

Examples:

  • "package": "package-name"
  • "package": "MySuperProject"

Property "modules": Array<string>

Array of glob patterns for loading and determining modules. It's recommended to use prefixes for you inner modules directories, so you can distinguish between modules directories and helpers and tools directories. For example you use for main modules module.name and for views modules view.name.

Default: ["./"]

Examples:

  • "modules": ["module-*/"]
  • "modules": ["module-*/", "views-*/", "utils-*/"]

Property "src": Array<string>

Array of glob patterns for determining src files of module. If it's specified in main servant.json it's used as a default for every submodule. You can override it in submodule servant.json. Doing this you can have different structures for each module. But this approach is not recommended.

Default: ["src/**/*"]

Examples:

  • "src": ["src/**/*"]
  • "src": ["src/**/*", "utils/**/*"]

Property "tests": Array<string>

Array of glob patterns for determining tests files of module. If it's specified in main servant.json it's used as a default for every submodule. You can override it in submodule servant.json. Doing this you can have different structures for each module. But this approach is not recommended.

Default: ["tests/**/*"]

Examples:

  • "tests": ["tests/**/*"]
  • "tests": ["tests/**/*", "test/**/*"]

Property "clean": Array<string>

Array of all extension that are removed by clean command. By default clean command clearing you dist files defined in package.json "files" field and also all files under temporary directory. But it can additionally clean some other files with specified extensions. This is used for cleaning autogenerated files for example. You don't need specify autogenerated files for ts, tsx or less files. Servant automatically clean all js or jsx files for typescripts files and css files for less or sass files.

Caveats

Clean property id also used by tests command for not including files that are not part of project! So it's necessary to have clean property properly set up!

Default: []

Examples:

  • "clean": ["js.stats", "log", "js.map"]
  • "clean": ["tmp"]

Property "prettify.sources": Array<string>

Array of glob patterns for determining directories and files for prettier validation by validate command. By default validate command prettify src and tests files defined in servant.json "src" and "tests" field. This glob can be extended by adding come folders here. For example if it's necessary to validate documentation or exampel files.

Default: []

Examples:

  • "prettify": { "sources": ["docs/**/*", "fixtures/**/*"] }

Property "prettify.extensions": Array<string>

Array of all extension that are prettified and validated by validate command. By default validate command prettify src and tests files defined in servant.json "src" and "tests" fields. But it can additionally validate some other files with specified extensions. This is used for validating another files than sources. For example, it can validate documentation markdown files, examples json files and others. Can prettify all files supported by prettier.

Default: []

Examples:

  • "prettify": { "extensions": ["md", "json"] }

Property "temp": string

Temporary dirname that is removed by clean command. By default clean command clearing you dist files defined in package.json "files" field and also all files under temporary directory. Some commands can create files under this temp directory. You can also use this dir to store some temporary files here. But don't forget that will be deleted by clean command!

Default: ".temp"

Examples:

  • "temp": ".temp"
  • "temp": "tmp"

Property "output.directory": string

Directory for final build output. There will be saved all resources and bundled files. This is used by build command.

Default: "./dist"

Examples:

  • "output": { "directory": "./dist" }
  • "output": { "directory": "./bundle" }

Property "output.filename": string

Name of bundled file. This is used by build command.

Default: "index.js"

Examples:

  • "output": { "filename": "./index.js" }

Property "output.resolve": Array<string>

Determine all extensions than will be resolved by Servant if he tries to load data from dist folder. For example if you copying resources that are necessary for loading into tests page, used this property to force this files. By default Servant will try to resolve this files and load into test page or into development mode page. By default you don't need change this, so ommit this property in your servant.json.

Default: ["js", "css"]

Examples:

  • "output": { "resolve": ["js", "css"] }

Property "entry": string | boolean

Main entry point into your module. It can be *.js or *.ts file or file without extension. If it's specified in main servant.json it's used as a default for every submodule. You can override it in submodule servant.json. Doing this you can have different structures for each module. This is used by build command.

Value false

You can provided false value for entry. This mean, that module is not intended for build and will not produce any output do dist folder.

Resolving .css files

Servant can resolve .css two ways.

  1. First way is to import .css file in your .ts file. It can be done like import * as css from "./my.css";. Because Servant have css to d.ts converter it can generate d.ts from css and your IDE can hint class names for you. Servant will be used css file as normal module and can build bundled css file into output folder.
  2. Second way is add file beside your entry point file, with same name, but with extension .css, .scss or .less. Servant will load this file and copy result file into output folder. If this file is .less or .scss, Servant build it before copying.

    For example: If you have "./src/index" as entry, create "./src/index.less" file, and it's done!

    For example: If you have "./src/index" as entry, create "./src/index.scss" file, and it's done!

Default: "./src/index"

Examples:

  • "output": "./src/index"
  • "output": "./src/entry.js"
  • "output": false

Property "test": string

Main entry point for tests into your module. It's used only for module that are build for web browsers or for universal use It can be *.js or *.ts file or file without extension. If it's specified in main servant.json it's used as a default for every submodule. You can override it in submodule servant.json. Doing this you can have different structures for each module. This is used by build command.

Default: "./tests/index"

Examples:

  • "output": "./tests/index"
  • "output": "./tests/index.ts"

Property "resolve": Array<string>

Determine all extensions than must be resolved by Servant. It's similar to webpack resolve property. By default you don't need change this, so ommit this property in your servant.json.

Default: ["ts", "js", "tsx", "jsx"]

Examples:

  • "output": ["ts", "js", "tsx", "jsx"]

Property "resources": Array<string>

Array of glob patterns for resources files of module. If it's specified in main servant.json it's used as a default for every submodule. You can override it in submodule servant.json. Doing this you can have different structures for each module. Every module has different sets of resources so it must be defined in every module separately.

Resources can be also defined as path into another installed npm module. For example you want to copy documentation for submodule into you dist package. Npm can install modules into different folders so you don't known where the documentation really is. In this case you can use path npm:my-module//docs/doc.md . Where my-module is npm module name and rest is path inside module.

Default: []

Examples:

  • "resources": ["fonts/*.ttf"]
  • "resources": ["fonts/*", "images/*.jpg"]
  • "resources": ["npm:react//umd/react.production.min.js"]

Property "watch": Array<string>

Array of glob patterns for watched files in module. This property is used by --changed flag. All files in this array are watched and if there are some changes in in, Servant can rebuild a module. You can watch node_modules directory, some hot folder for resources and so on.

Default: []

Examples:

  • "watch": ["node_modules/**/*"]
  • "watch": ["graphics/**/*"]

Property "libraries": Map<string, string>

Directory of all libraries that will not be build into output file. By default every dependency and every node module is not bundled into output. But if there are some special cases (for example: you use library "simple-git" but you need import "simple-git/promise") Servant is not able to determine library to not include. So if you wan't this library as build into output, you must specify in there.

Default: {}

Examples:

  • "libraries": {"simplge-git/promies": "simplge-git/promies"}

Property "mappings": { [key: string]: string | false }

There are defined all links on external libraries. For example if you use react as external library (that is not part of your build) you can defined link where library sources are located. Servant known most uses libraries. Now only react and react-dom are automatically resolved.

Path for file is relative inside module! Path for module is automatically resolved by Servant. If you are a developer and you want to add new module into automatically detections, add path inside file servant.json.module.ts and create merge request.

false value can be used as value in mapping. Servant do not try to include this modules and skip it. This is good for resource only modules (fonts, images and so on).

Default: {}

Examples:

  • "mappings": {"react": "./dist/react.production.js"}
  • "mappings": {"react-dom": "./dist/react-dom.production.js"}
  • "mappings": {"@fortawsome/fontawsome": false}

Property "target": "web" | "node" | "node-cli"

This is setting of output target. You must specify for what is module used.

web target

If you set up "web" as target, Servant will include modules like "path", "fs" and all others internal node js modules. This cause that if you use this module in project, module will be bundled into output file! This can cause unexpected behaviour in browser!

node target

If you set up "node" as target, Servant will not include modules like "path", "fs" and all others internal node js modules. This cause that if you use this module in project, module will not be bundled into output file because we expected that this module is inside nodejs.

node-cli target

This setup is similar like node, but is expected, that this module will be used as command line application,

Default: "web"

Examples:

  • "target": "web"
  • "target": "node"

Property "publish.increment": "major" | "premajor" | "minor" | "preminor" | "patch" | "prepatch" | "prerelease" | "none"

This is increment type used by publish command. Servant will increase semver version fo your module by specify type. If you don't want to increment version automatically, set "none" as increment.

Default: "patch"

Examples:

  • "publish": {"increment": "none"}
  • "publish": {"increment": "minor"}

Property "publish.access": "public" | "restricted"

Define if you publish public or restricted package. Is is used by publish command and if you want to use "restricted" on default registry, you need paid account!

Default: "public"

Examples:

  • "publish": {"access": "public"}
  • "publish": {"access": "restricted"}

Property "publish.stripDev": boolean

Define if you want to delete devDependencies from published package.json. Servant will delete this property and make package without development dependencies.

Default: false

Examples:

  • "publish": {"stripDev": true}

Property "publish.commitMessage": string

Commit message that will be attached to commit if you use --commit flag in publish command. For every module Servant make single commit with this message. You can use variables that will be replaced in final message

Variables:
  • $version - Will be replaced for current module version
  • $increment - Will be replaced for current increment style defined in increment property in servant.json

Default: Incrementing version by '$increment' number. New version is '$version'.

Examples:

  • "publish": {"commitMessage": "New version $version."}

Property "registry": string | Object

You can setup your registry if you do not use default "registry.npmjs.org". Registry is used by publish, install and update commands.

Default: ""

Examples:

  • "registry": "/local/registry/npm"
  • "registry": "http://www.my.registry.com"

Example with more scopes:

  • "registry": { "default": "http://www.my.registry.com", "@scope": "http://scope.registry.com", "@ext": "http://ext.registry.com" }

Property "issues": Object

Settings for bug name resolving in test name. It's used by tests command and is used for collecting all bugs that are reported in test or suit name. On end of tests task you can view the count of tested issues and all passed tests for it.

Key of object is pattern for resolving issue in tests name.

Value if object is url for issues that are testing. This url is show in list of all tested issues on end. You can use $0 for whole matching string and the $1, $2, ... for groups.

Default: {}

Examples:

  • "issues": { "#([0-9]{1,})": "http://issue-tracker.rg/id/$0" }

Property "testing.browsers": Array<string>

This settings is used for define in which browsers tests will be run. You can setup here Webkit, Chromium and Firefox. All browsers can be run in headless or gui mode (--gui switch in command line). If you omitted whole testing property, Servant will fallback into only "Chrome" browser testing.

Caveats

This is special feature that use playwright module from Microsoft to run tests against more browsers and you need install optional module @servant/servant-playwright to get this working. So after install Servant run npm install @servant/servant-playwright --save-dev to install this optional module. Be careful because this module is big (about 300 MB to download)!

Property "testing.devices": Array<string>

This settings is used for define in which device tests will be run. You can setup here more than 70 devices. Full list of devices can be found on playwright.

Caveats

This is special feature that use playwright module from Microsoft to run tests against more browsers and you need install optional module @servant/servant-playwright to get this working. So after install Servant run npm install @servant/servant-playwright --save-dev to install this optional module. Be careful because this module is big (about 300 MB to download)!

Property "server": Object

Settings for development server of Servant. There are all settings that you need if you use --server flag for running development server.

Default: {}

Examples:

  • "server": {...}

Property "server.css": Array.<string>

List of all externals css libraries. You can specify url or relative path.

Default: []

Examples:

  • "server.css": ["http://fonts.googleapis.com/css?family=Open+Sans", "./globals/styles.css"]

Property "server.js": Array.<string>

List of all externals js libraries. You can specify url or relative path.

Default: []

Examples:

  • "server.js": ["http://libs.js/jquery.js", "./globals/my.js"]

Property "server.entries": { [key: string]: Entry }

List of all entries. You define module name (defined in package.json) as key. Then you can define other properties, but these properties are not necessary for running development server. If you not defined any entry, development server will no start :). Default port for running is 9000. For every entry that you define here, Servant will increment port number and create new dev server with this entry. If ports are used, Servant automatically increments ports and find first not used.

Default: {}

Examples:

  • "server.entry": { "package.name": {} }
  • "server.entry": { "package.name": {"title": "Package Name", "template": "./debug.html""} }
Entry

Entry is used for define some entry information about module in development server.

  • Entry.title - Define title of development page with module.
  • Entry.template - Define template file with data for development server.
Entry template definition

Template file is used for injecting data into development server. For now, you can inject only css styles, javascript files and meta tags. In example, you must defined template as root. Then you can use style, script and meta here. You can define more styles, scripts and meta tags in template.

  • meta - You can define meta tags and servant include this meta tags into dev server index.html
  • body - You can define body html content and servant include this body into dev server index.html
  • style - You can define css here. This css will be used in development.
  • script - You can define js content here. This script will be injected on the end of body tag.
   <template>
       <meta name="author" content="John Doe" />
       <meta name="viewport" content="initial-scale=1, maximum-scale=1" />
       <style type="text/css">
           body {
               margin: 0;
               padding: 0;
           }
       </style>
       <script type="text/javascript">
           let item = window["package-name"];
           item.render(document.body);
       </script>
       <script type="text/javascript">
           ...
       </script>
       <body><![CDATA[
           <div id="main-app"></div>
           <span id="anchor">Anchor</span>
           <div id="modal-app"></div>
       ]]>
       </body>
       <body>
           <div id="main-app">Content</div>
       </body>
   </template>

And thats all. This is a whole configuration of servant.json file. Now it will be pretty easy to configure Servant as you want and customize main parts of monorepo. Config options will be increased as new features will be derived and also this article will be updated. See you on next chapter.

Did you find this article valuable?

Support Stanislav Hacker by becoming a sponsor. Any amount is appreciated!