Configuration
Jess reads config from a styles.config.{ts,js} file, usually at your project root: a file uses every one in its own folder and the folders above it, up to its package root, so a project's config applies to its subfolders. Keep it small at first; grow it only when your build needs it.
// styles.config.js
export default {
options: {}
}
options
dynamic
Changes compilation mode so dynamic content is represented as CSS custom properties and patch-friendly output. Reach for this when you need runtime theme switching or app-level style updates.
module
Overrides whether Jess files compile as modules globally. By default, files named [filename].module.jess or [filename].m.jess are treated as modules and class names are hashed.
Compile settings
The compile settings (mathMode, unitMode, functionMode, the strict preset,
allowCallerScope, processImports, …) are worked out for each file, so a file
compiles the same way whichever file imports it. Math written in a file follows
that file's settings wherever it ends up: a variable's value, a mixin's body and
its guard answer the settings of the file they are written in, not the file that
reads or calls them. A file also keeps its own language's built-in functions.
A file's settings come from two places, merged:
-
Its
styles.configfiles: every one in the file's own folder and the folders above it, merged, the nearest winning setting by setting. A subfolder's config only needs the settings that differ: the rest come from the configs above it. The search stops at the file's package root (the first folder up with apackage.json, whose config is included), so one package never reads another's config. An imported file in another folder uses the configs above it, not the entry's. Nostyles.configis loaded for a file in an installed package (undernode_modules). -
The settings passed in: to the compiler, to a render, or on the command line. They are merged over the
styles.configfiles setting by setting: a value passed in wins over the same setting in a config file, and the config files supply everything left unset.compileand eachlanguage.<lang>block merge setting by setting. A singleinputoroutputobject does too; a list ofoutput(orinput) entries replaces the one above it. Any other key (lint, …) is replaced whole by the nearer config.new Compiler({ compile: { unitMode: 'preserve' } });
compiler.render('main.less', { compile: { unitMode: 'preserve' } });
On that merged config, each file's settings are worked out for its language, each step over the one before:
-
Its language's defaults, or the options its language's plugin was built with (
lessPlugin({ unitMode: 'loose' })). A.lessfile keeps math over units that do not convert ascalc()and warns (unitMode: 'preserve'); a.jessfile stops with an error (strict). A.jessfile imported by a.lessfile still errors, and a.lessfile imported by a.jessfile still writescalc(). -
compilesettings, which apply to every file, whatever its language. -
language.<lang>settings (language.less,language.jess,language.scss), which apply only to files of that language.// styles.config.js
export default {
compile: { unitMode: 'preserve' },
language: { jess: { unitMode: 'strict' } }
}
So a language setting wins over a compile setting wherever each is set:
language.less.unitMode: 'loose' in a styles.config applies to .less files
even when the render passes compile: { unitMode: 'strict' } or
compile: { strict: true }, and .jess files get the render's setting. A
deprecated spelling (strictUnits, math, strictMath, leakyScope) counts
where it is written: language.less.strictUnits wins over compile.unitMode as
language.less.unitMode would, and passed in, it wins over a
language.less.unitMode in the config file.
The strict preset is not a mode of its own. It can be set in compile or in
language.<lang>, and the more specific one decides: language.less.strict
wins over compile.strict for .less files, false included. When on, it fills
the modes left unset where it is written, so compile: { strict: true } gives
way to any mode a language sets, and language.less.strict: true makes .less
strict over a compile.unitMode while language.less.unitMode still wins over it.
compile.plugins
Add compile-time plugins used by the compiler (for language/runtime extensions). This is separate from bundler plugins such as rollup-plugin-jess.
lint
Configure jess lint and the @jesscss/lint API.
// styles.config.js
export default {
lint: {
files: ['src/**/*.{css,less,scss,jess}'],
ignoreFiles: ['dist/**'],
reportSyntax: true,
rules: {
'property-no-unknown': 'error',
'length-zero-no-unit': 'warn',
'vendor-prefix': 'warn',
'compatible-vendor-prefixes': 'off',
'unknown-vendor-specific-properties': 'off',
'float': 'off',
'jess/no-suspicious-map-key-access': 'warn',
'jess/unsupported-sass-form': 'warn'
}
}
}
files supplies the default glob set when jess lint is run without positional
patterns. ignoreFiles excludes generated or vendored stylesheets.
reportSyntax controls whether parser diagnostics are surfaced through lint.
Per-rule values are off, warn, and error; null also disables a rule.
Jess uses Stylelint rule names where the rule intent is familiar and Jess-owned
namespaces for Jess-only checks.
Those rule names are the lint configuration surface; shared diagnostic codes are
still emitted in JSON for editor and tool integrations.
Jess lint uses this policy on top of shared diagnostics. Detection itself lives below the lint package, so a diagnostic can be reused by the CLI and the language service instead of being implemented twice.