Mach is an ultra-fast transpiler and bundler for use with MSFS (Microsoft Flight Simulator 2020) instruments. Unlike other bundling tools such as rollup or webpack, Mach has been built from the ground up with the sole purpose of serving the MSFS development community's needs.
Mach currently supports bundling both JavaScript and TypeScript React instruments, along with any CSS or SCSS stylesheets and images that are included. Instruments built with the MSFS Avionics Framework are also supported, but require additional steps to ensure compatibility as described here.
Mach also allows you to create nested instruments, enabling you to bundle MSFS Avionics instruments separately and import them into your React instrument.
-c, --config <filename>
specify path to configuration file (default:./mach.config.js
)-d, --work-in-config-dir
use config directory as working directory-b, --bundles <dirname>
bundles output directory (default:./bundles
)-e, --werror
makes all warnings into errors-f, --filter <regex>
regex filter of included instrument names-m, --minify
minify bundle code-s, --skip-simulator-package
skips writing simulator package templates-t, --output-metafile
outputbuild_meta.json
file to bundles directory-u, --output-sourcemaps
append sourcemaps to the end of bundle files-v, --verbose
output additional build information
The build
command will simply go through each instrument defined in your configuration, then output the bundles and package source files to the configured directories.
The watch
command will first build each instrument in the configuration, and then watch the source files for changes in order to re-bundle the instrument. If there was an error while bundling the instrument in the beginning, the watcher will not run.
This function has the same behavior as the mach build [options]
CLI command.
This function has the same behavior as the mach watch [options]
CLI command.
Whether you supply the configuration with the mach.config.js
file to the CLI or with a JavaScript object to the API, the structure is identical.
interface PackageSettings {
/**
* Specifies type of instrument.
* - `React` instruments will be created with a `BaseInstrument` harness that exposes an `MSFS_REACT_MOUNT` element for mounting.
* - `BaseInstrument` instruments must specify the `instrumentId` and `mountElementId` to match the instrument configuration.
*/
type: string;
/** Final template filename. Defaults to `template` */
fileName?: string;
/** Simulator packages to import in the HTML template. */
imports?: string[];
}
interface ReactInstrumentPackageSettings extends PackageSettings {
type: 'react';
/** Optional parameter to specify template ID. Defaults to `Instrument.name`. */
templateId?: string;
/** Whether the instrument is interactive or not. Defaults to `true`. */
isInteractive?: boolean;
}
interface BaseInstrumentPackageSettings extends PackageSettings {
type: 'baseInstrument';
/**
* Required for `BaseInstrument` instruments.
* This value must match the return value from the `BaseInstrument.templateID()` function.
* */
templateId: string;
/**
* Required for `BaseInstrument` instruments.
* This value must match the ID in your call to `FSComponent.render()`..
*/
mountElementId: string;
}
interface Instrument {
/** Instrument name, used as directory name for bundles and packages. */
name: string;
/** Entrypoint filename for instrument. */
index: string;
/** When passed a configuration object, enables a simulator package export. */
simulatorPackage?: ReactInstrumentPackageSettings | BaseInstrumentPackageSettings;
/** Instruments to import as ESM modules. */
modules?: Instrument[];
/** (Required for instruments included as `modules`) Import name to resolve to the bundled module. */
resolve?: string;
/** esbuild plugins to include for only this instrument (<https://github.com/esbuild/community-plugins>) */
plugins?: Plugin[];
}
interface MachConfig {
/** Name of package, used for bundling simulator packages. */
packageName: string;
/** Path to directory containing `html_ui`. */
packageDir: string;
/** esbuild plugins to include for all instruments (<https://github.com/esbuild/community-plugins>) */
plugins?: Plugin[];
/** All instruments to be bundled by Mach. */
instruments: Instrument[];
}
const imageInline = require('esbuild-plugin-inline-image');
/** @type { import('@synaptic-simulations/mach').MachConfig } */
module.exports = {
packageName: 'a22x',
packageDir: 'PackageSources',
plugins: [imageInline({ limit: -1 })],
instruments: [
{
name: 'DisplayUnits',
index: 'src/instruments/src/DisplayUnits/index.tsx',
simulatorPackage: {
type: 'react',
imports: ['/JS/dataStorage.js'],
},
modules: [{
name: 'PFD',
resolve: '@instruments/PFD',
index: 'src/instruments/src/PFD/index.tsx',
}],
},
{
name: 'CTP',
index: 'src/instruments/src/CTP/index.tsx',
simulatorPackage: {
type: 'react',
imports: ['/JS/dataStorage.js'],
},
},
{
name: 'ISI',
index: 'src/instruments/src/ISI/index.tsx',
simulatorPackage: {
type: 'react',
imports: ['/JS/dataStorage.js'],
},
},
],
};
For compatibility with Mach, a modification must be made to the msfs-avionics
source code:
# src/sdk/components/FSComponent.ts
- [357] if (typeof type === 'function' && type.name === 'Fragment') {
+ [357] if (typeof type === 'function' && type.name === Fragment.name) {
These changes are also available through the @synaptic-simulations/msfssdk
npm package.