-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Contributing
Xterm.js is maintained by several core team members, but we would love to receive contributions from everyone!
To contribute either code, documentation or issues to xterm.js please read the Contributing document beforehand. All you need to contribute is an editor that supports JavaScript/TypeScript, a browser. You will need Node.js installed locally to get all the features working in the demo.
⚠️ The xterm.js repo contains a barebones demo implementation, designed for the development and evaluation of the library only. Note that exposing the demo to the public as is would introduce security risks for the host.
- Linux and macOS
- Yarn
- A C++ compiler such as GCC-C++ or Clang - see node-pty's dependency instructions
- Windows
- Yarn
- node-gyp must be is installed and configured correctly - see node-pty's dependency instructions
⚠️ Do not use ConEmu, as it seems to break the demo for some reason
- Dev Container
The first step is to install dependencies:
yarn
yarn setup
Building the demo involves several watch scripts each run in separate terminals. If you're using VS Code there is a build task setup such that Ctrl/Cmd+Shift+b will run all the tasks for you.
# Compiles core, all addons and integration tests to out-esbuild/, this also
# bundles non-minified versions core and addons to lib/
yarn run esbuild-watch
# Verify typescript types (since esbuild does not do this) and outputs to out/
yarn run tsc-watch
# Bundles the demo
yarn run esbuild-demo-watch
# Runs the demo server
yarn start
If these all run successfully, you should be able to access the demo at http://127.0.0.1:3000
Unit tests are run with yarn test-unit
:
# All unit tests
yarn test-unit
# Absolute file path
yarn test-unit out-esbuild/browser/Terminal.test.js
# Filter by wildcard
yarn test-unit out-esbuild/**/Terminal.test.js
# Specific addon unit tests tests
yarn test-unit addons/addon-image/out-esbuild/*.test.js
# Multiple files
yarn test-unit out-esbuild/**/Terminal.test.js out-esbuild/**/InputHandler.test.js
These use mocha to run all .test.js
files within the esbuild output (out-esbuild/
).
Integration tests are run with yarn test-integration
:
# All integration tests
yarn test-integration
# Core integration tests
yarn test-integration --suite=core
# Specific addon integration tests
yarn test-integration --suite=addon-search
These use @playwright/test
to run all tests within the esbuild test output (out-esbuild-test/
).
The project uses a layered architecture similar to VS Code's where the project is split into 3 modules:
-
common
: The lowest level module, it can run in either a browser or a node.js environment and does not depend on anything. -
browser
: Can run only in a browser environment and depends oncommon
, thepublic
directory contains the API forxterm
-
headless
: Depends oncommon
, thepublic
directory contains the API forxterm-headless
Any public
directory contains code that implements the public API, for example browser/public/Terminal.ts
implements an API façade by wrapping internal objects from browser
and common
the wraps the objects in browser
. It is not recommended for any xterm.js embedder to touch the internal objects (private API) as what they do and whether they even exist is not guaranteed and could change, even across patch versions.
Dependency injection (DI) in xterm.js is implemented using a simplified version of that used in VS Code. To use it decorations are used, here is an example of injecting IBufferService
into a constructor:
class Example {
constructor(
@IBufferService bufferService: IBufferService
) {
}
}
In order for DI to work this class must be created using the IInstantiationService
:
const example = instantiationService.createInstance(Example);
To implement a new service it must contain a serviceBrand
property and then be registered to the IInstantiationService
:
interface IExampleService {
serviceBrand: undefined;
}
class ExampleServiceImpl implements IExampleService {
public serviceBrand: undefined;
}
const exampleServiceImpl = new ExampleServiceImpl();
this._instantiationService.setService(IExampleService, exampleServiceImpl);
Several addons are built by the xterm.js team are located in this repository under the addons/
folder. They are in their own separate folders and are treated as individual npm modules, but during development they leverage the dependencies in the root-level package.json file.
Here is a diagram that shows the flow and depenendencies of the build system used in the Building section:
Xterm.js has a debug mode that allows you to view what's being evaluated by the terminal. To enable this mode, run the demo and execute the following in the console:
term.setOption('logLevel', 'debug');
Any data sent to the terminal should be output in the console.
We prefer to not include any non-dev third party dependencies in order to keep our code minimal, performant and secure. If you plan on adding a dependency on a third party library it's a good idea to discuss the need in an issue with the maintainers first.