@servant/servant-cli
Version:
Servant builder for node modules. Cli client fro servant.
363 lines (284 loc) • 17.5 kB
Markdown
# ![Servant][logo] Servant builder API
Quick references: **[Command line][4]**, **[Node API][3]**, **[servant.json][2]**, **[dev-server][5]**
## What is it?
Servant builder is simple build tool for developers, that wants to build and manage modularized large projects in
monorepo or separated into more repositories. With this tool you will be able to control used libraries, build and rebuild
all packages at all or only selected once, run tests in more browsers and device, validate all your code against
eslint or prettier and finally publish your packages into repository. Servant basically try to learn the best way of
managing and developing of multiple modules projects and its maintenance with grace. It's try to be simple but powerful
tool and good servant :wink:
### Key features
- **Monorepo manage and configuration** Manage monorepo with one configuration file that can contains definition
for your monorepo, directory structure, validator settings, publish settings and more! There will be only small
config files in every module to customize names and overriding some specific settings.
- **Installing and update at once** Make install and update npm commands at once for all defined modules or for
some specific modules only.
- **Controlling and unifying dependencies versions** Manage all dependencies, unify across all packages to be same in
version. Servant will automatically warn you if there are some dependencies that are not same across all packages
and provide same commands to unify this versions across all packages.
- **Testing on more browsers and devices** Servant allows you to run tests against more than 70 devices in 3 different
browsers. This all because Servant using playwright library to run tests in. But even if you are not want to use
playwright, Servant try to run all tests in Chrome browsers. And that is possible only one simple configuration
record in configuration file.
- **Validating quality of your code** Check quality of your code by using eslint and prettier: servant can run validation
of all supported validators in one step and report all errors and warnings on one place with nice command line results.
These validators can be manage by using or not using config files related to supported validator and can be turned on
only for some modules or for all.
- **Smart publishing into repository** Servant can also provide publish of all your packages into repository. And because
we need some kind of versioning manage, you are able to choose if Servant will increase packages patch, minor, major or
any prerelease version and also commit some message about version increment into git. Servant can also fix packages
versions or removing devDependencies during publishing.
- **Development server with "_Servants link_"** For better developer experience, Servant has own dev server, that can provide
automatically rebuilding on change. This server automatically includes all necessary libraries that are defined in
dependencies and by default is include only libraries, that are compatible with browser. So you are able to check if
your modules will be work as package in browser.
Servant also come with feature called "**_Servants link_**". If there are more Servants run in watch mode, there are
communicating each others. Servant detects others packages and can rebuild modules that are connected through dependencies.
**Let's look on some example**. You have a company monorepo "main-app" with packages. Also, there is company repo "library-app".
Some package from "main-app" has dependency to "library-app". Both repos use Servant as build tool. If you run "main-app" and
"library-app" in watch mode, Servant run from "main-app" detect that there is a "library-app" Servant running and link this into
"main-app". So now "main-app" use live build of library "library-app" and also, if you make some changes Servant first ensure
rebuild of "library-app" and then "main-app". And that's all :) You never need to create some link and another hacks manually!
- **Code generators** Servant provide external or custom generators that can provide fast and standard way how to create
predefined components, code samples and other content. Just run generators, select desired on and answers all questions
that generators need. After that content will be generated into wanted modules and selected folder.
> **Caveats**
>
> Servant dev serves has no support for hot module replacement for now. This will be implemented in future releases so now
> you need make pages reload after rebuild of modules.
![Servant preview][preview]
### Installation and start!
#### 1. Globally installed
You need the latest version of nodejs and then run:
> `npm install @servant/servant-cli -g`
Then you can run in current directory:
> `servant clean`
> **Caveats**
>
> Installing globally is not recommended.
Servant will be complaining about missing [`package.json`][1] and [`servant.json`][2]. We will create it.
Servant has special flag to init main project or submodule. We will create main project now with using
`--init` flag and answer all questions that servant give us.
> `servant --init`
After init project with calling `"node_modules/.bin/servant" --init`, Servant create [`package.json`][1]
file with script called "servant". Now you can use `npm run servant` to call servant from your
current directory.
> **Caveats**
>
> If you want to pass arguments into Servant run through `npm run` you must separate arguments
> with `--`
>
> **For example:**
>
> `npm run servant -- clean build --production`
#### 2. Locally installed
You need the latest version of nodejs and then run:
> `npm install @servant/servant-cli`
Then you can run in current directory:
> `"node_modules/.bin/servant" clean`
Servant will be complaining about missing [`package.json`][1] and [`servant.json`][2]. We will create it.
Servant has special flag to init main project or submodule. We will create main project now with using
`--init` flag and answer all questions that servant give us.
> `node_modules/.bin/servant --init`
After init project with calling `"node_modules/.bin/servant" --init`, Servant create [`package.json`][1]
file with script called "servant". Now you can use `npm run servant` to call servant from your
current directory.
> **Caveats**
>
> If you want to pass arguments into Servant run through `npm run` you must separate arguments
> with `--`
>
> **For example:**
>
> `npm run servant -- clean build --production`
#### 3. Installed and init with `npx`
You need the latest version of nodejs and then run
> `npx @servant/servant-cli --init`
This command run init runtime of servant, that will create skeleton of first project. There is wizard that
can help to create settings that you need and also prepare first files and make install of all dependencies.
![Servant init example][init]
### Supported technologies
- **less (`*.less`)**: You can use less in your module. Servant automatically build it and add to folder for distribution. Servant
also make automatically conversion from **.less to .d.ts** typescript definition for usage in your project.
- **sass (`*.scss`)**: You can use sass in your module. Servant automatically build it and add to folder for distribution. Servant
also make automatically conversion from **.scss to .d.ts** typescript definition for usage in your project.
- **css (`*.css`)**: You can use css in your module. Servant automatically build it and add to folder for distribution. Servant
also make automatically conversion from **.css to .d.ts** typescript definition for usage in your project.
- **typescript (`*.ts`, `*.tsx`)**: Servant is use for Typescript and in current version it's one of two supported language.
Use .ts files and Servant do the rest.
- **javascript (`*.js`, `*.jsx`)**: Servant is use for Javascript and in current version it's one of two supported language.
Use .js files and Servant do the rest.
### Used technologies
Servant used these technologies for building and creating the best developer experience for developing in
supported technologies.
- **webpack**: Webpack is used for building and bundling. Servant automatically generate config file for webpack so
is not necessary to do something.
- **typed-css-modules**: Module for building `*.d.ts` definitions from less, sass or css files.
- **eslint**: Module for validating `*.ts` and `*.js` files.
- **prettier**: Module for formatting lots of files that are supported by this tool.
### Playground
You can use playground that is used for trying Servant in real project. Servant playground has it's own repo and
can be accessed on link [https://gitlab.com/stanislavhacker/servant-playground][playground]. More info is inside this
repo!
### Servant project structure
If you want to use Servant, you must create the right folder structure for right behaviour. Servant needs it and
for working with it. This is the best approach to your project and for Servant of course.
.
├── module.one # Example module (folder)
│ ├── package.json # Package json for module one
│ ├── servant.json # Servant config file for module one
│ ├── (tsconfig.json) # OPTIONAL: Typescript config for module one
│ ├── (.eslintrc.json) # OPTIONAL: Eslint config for module one
│ └── (.prettierrc.json) # OPTIONAL: Prettier config for module one
├── ...
├── module.two # Example module (folder)
│ ├── package.json # Package json for module two
│ ├── servant.json # Servant config file for module two
│ ├── (tsconfig.json) # OPTIONAL: Typescript config for module two
│ ├── (.eslintrc.json) # OPTIONAL: Eslint config for module two
│ └── (.prettierrc.json) # OPTIONAL: Prettier config for module two
├── ...
├── package.json # Required file for dependencies resolving
├── (tsconfig.json) # OPTIONAL: Only use it if you want to do typescript module
├── (.eslintrc.json) # OPTIONAL: Root eslint config for all modules (can share default rules, ..)
└── servant.json # Main config file of servant
### Config `servant.json`
Main configuration file for Servant. It's described in [separate section "Config 'servant.json'"][2].
### Servant NodeJs api
Servant can also be used from node js process. For this there is available simple Servant api that can provide
all necessary information and can be used inside your integration module or another runtime. It's described
in [separate section "Servant NodeJs api"][3].
### Servant command line api
Servant is primary used for calling from command line. Can be used many ways with lot's of predefined commands
and options. It's designed for fast creating and managing large projects composed from independent modules.
Command line api is described in [separate section "Servant command line api"][4].
## Special Features
### Servant `package.json` scripts behaviour
Servant can be run from npm scripts in `package.json`. There is a small example what can be defined
in root `package.json`. Some scripts are automatically added after usage of `--init` flag.
**root/package.json**
```json
{
...
"scripts": {
"servant": "servant",
"clean": "servant clean",
"prune": "servant clean --prune",
"build": "servant clean build",
"rebuild": "servant clean build --changed",
"production": "servant clean build --production"
},
...
}
```
But this is also valid for submodules. You can specify for example these scripts in submodule
`package.json`.
**root/submodule/package.json**
```json
{
...
"scripts": {
"clean": "servant clean",
"build": "servant clean build",
"rebuild": "servant clean build --changed"
},
...
}
```
**Servant automatically** detects, that you are running command in submodule and
run this in context of parent project. Basically is doing same thing as if you use [`--only`][4]
flag on command line.
### Local shared dependencies
Sometimes is necessary to shared some dependencies to not have been includes from more places. (For example
`react` or `react-dom` must be included only once in project). Look on current example of project structure.
.
├── module.one
│ └── package.json
│ "dependencies": {
│ "react": "18.0.0",
│ "react-dom": "18.0.0",
│ "glob": "3.0.0"
│ }
├── module.two
│ └── package.json
│ "dependencies": {
│ "react": "18.0.0",
│ "react-dom": "18.0.0",
│ "express": "10.0.0"
│ }
├── ...
├── package.json
│ "dependencies": {}
└── servant.json
As you can see, there are same react modules in `module.one` and `module.two`. And if you run this
in nodejs context, node require react for module one from `module.one/node_modules/react` and for
module two from `module.two/node_modules/react`. And in this case, React will throw error that
there are two different versions of react in project. You can use local shared dependencies feature
to resolve this problem. Just update package json dependencies definition line on next example.
.
├── module.one
│ └── package.json
│ "dependencies": {
│ "react": "file:../node_modules/react",
│ "react-dom": "file:../node_modules/react-dom",
│ "glob": "3.0.0"
│ }
├── module.two
│ └── package.json
│ "dependencies": {
│ "react": "file:../node_modules/react",
│ "react-dom": "file:../node_modules/react-dom",
│ "express": "10.0.0"
│ }
├── ...
├── package.json
│ "dependencies": {
│ "react": "18.0.0",
│ "react-dom": "18.0.0",
│ }
└── servant.json
This will cause, that only one react will be installed in root `node_modules` folder and will be
shared to all submodules that used local path in version definition. This also alter dependency
graph and can change order of building, but this is expected. Dont be afraid of local versions,
with publish command, Servant automatically update all local versions to real versions!
> **Caveats**
>
> You can create circular dependencies with this feature. On next example there is a structure
> of circular dependencies. In this case module `module.one` depends on `module.two` but `module.two`
> wants to share `react` and `react-dom`\*\* from `module.one`. This is a circular dependencies and
> Servant wil end with error.
.
├── module.one
│ └── package.json
│ "dependencies": {
│ "module.two": "file:../module.two",
│ "react": "18.0.0",
│ "react-dom": "18.0.0",
│ "glob": "3.0.0"
│ }
├── module.two
│ └── package.json
│ "dependencies": {
│ "react": "file:../module.one/node_modules/react",
│ "react-dom": "file:../module.one/node_modules/react-dom",
│ "express": "10.0.0"
│ }
├── ...
├── package.json
│ "dependencies": {}
└── servant.json
### Donate me
| QR | Paypal |
| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|  | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DUT8W343NVGQQ&source=url) |
### License
[Licensed under GPLv3][license]
[logo]: https://gitlab.com/stanislavhacker/servant/raw/master/logo.png
[preview]: https://gitlab.com/stanislavhacker/servant/raw/master/assets/servant.example1.gif
[init]: https://gitlab.com/stanislavhacker/servant/raw/master/assets/servant.init.gif
[1]: https://docs.npmjs.com/files/package.json
[2]: https://gitlab.com/stanislavhacker/servant/blob/master/servant/doc/servant.json.md
[3]: https://gitlab.com/stanislavhacker/servant/blob/master/servant/doc/servant.nodejs.md
[4]: https://gitlab.com/stanislavhacker/servant/blob/master/servant-cli/doc/servant.clia.md
[5]: https://gitlab.com/stanislavhacker/servant/blob/master/servant-development/doc/servant.devserver.md
[license]: https://gitlab.com/stanislavhacker/servant/blob/master/LICENSE