diff --git a/docs/user-guide/usage/cli.md b/docs/user-guide/usage/cli.md index b4f4ebbfc8..75bdcb45fb 100644 --- a/docs/user-guide/usage/cli.md +++ b/docs/user-guide/usage/cli.md @@ -106,6 +106,14 @@ Using `bar/mySpecialConfig.json` as config to lint all `.css` files in the `foo` stylelint "foo/**/*.css" --config bar/mySpecialConfig.json ``` +### Example H - using a custom syntax + +Recursively linting all `.css` files in the `foo` directory using a custom syntax: + +```shell +stylelint "foo/**/*.css" --customSyntax path/to/my-custom-syntax.js +``` + ## Exit codes The CLI can exit the process with the following exit codes: diff --git a/docs/user-guide/usage/node-api.md b/docs/user-guide/usage/node-api.md index 4bd98e125c..635b998b0d 100644 --- a/docs/user-guide/usage/node-api.md +++ b/docs/user-guide/usage/node-api.md @@ -150,3 +150,28 @@ stylelint /* .. */ }); ``` + +### Example E + +Using a custom syntax: + +```js +stylelint + .lint({ + config: myConfig, + files: "all/my/stylesheets/*.css", + customSyntax: { + parse: (css, opts) => { + /* .. */ + }, + stringify: (root, builder) => { + /* .. */ + } + } + }) + .then(function () { + /* .. */ + }); +``` + +Note that the customSyntax option also accepts a string. [Refer to the options documentation for details](./options.md). diff --git a/docs/user-guide/usage/options.md b/docs/user-guide/usage/options.md index 8a2289e6e8..c4df930e30 100644 --- a/docs/user-guide/usage/options.md +++ b/docs/user-guide/usage/options.md @@ -101,7 +101,7 @@ Specify a syntax. Options: - `scss` - `sugarss` -If you do not specify a syntax, stylelint automatically infer the syntaxes. +If you do not specify a syntax, stylelint will automatically infer the syntaxes. Only use this option if you want to force a specific syntax. @@ -109,9 +109,13 @@ Only use this option if you want to force a specific syntax. CLI flag: `--custom-syntax` -Module name or path to a JS file exporting a [PostCSS-compatible syntax](https://github.com/postcss/postcss#syntaxes). +Specify a custom syntax to use on your code. Use this option if you want to force a specific syntax that's not already built into stylelint. -Note, however, that stylelint can provide no guarantee that core rules work with syntaxes other than the defaults listed for the `syntax` option above. +This option should be a string that resolves to a JS module that exports a [PostCSS-compatible syntax](https://github.com/postcss/postcss#syntaxes). The string can be a module name (like `my-module`) or a path to a JS file (like `path/to/my-module.js`). + +Using the Node.js API, the `customSyntax` option can also accept a [Syntax object](https://github.com/postcss/postcss/blob/abfaa7122a0f480bc5be0905df3c24a6a51a82d9/lib/postcss.d.ts#L223-L232). Stylelint treats the `parse` property as a required value. + +Note that stylelint can provide no guarantee that core rules work with syntaxes other than the defaults listed for the `syntax` option above. ## `disableDefaultIgnores` diff --git a/lib/__tests__/standalone.test.js b/lib/__tests__/standalone.test.js index 919a707c5c..523ff0b928 100644 --- a/lib/__tests__/standalone.test.js +++ b/lib/__tests__/standalone.test.js @@ -243,7 +243,9 @@ it('unknown custom syntax option', () => { throw new Error('should not have succeeded'); }) .catch((err) => { - expect(err.message).toBe('Cannot resolve custom syntax module unknown-module'); + expect(err.message).toBe( + 'Cannot resolve custom syntax module unknown-module. Check that module unknown-module is available and spelled correctly.', + ); }); }); diff --git a/lib/getPostcssResult.js b/lib/getPostcssResult.js index 5228f862bd..a38476b8b0 100644 --- a/lib/getPostcssResult.js +++ b/lib/getPostcssResult.js @@ -117,24 +117,42 @@ module.exports = function (stylelint, options = {}) { function getCustomSyntax(customSyntax) { let resolved; - try { - resolved = require(customSyntax); - } catch (error) { - throw new Error(`Cannot resolve custom syntax module ${customSyntax}`); + if (typeof customSyntax === 'string') { + try { + resolved = require(customSyntax); + } catch (error) { + throw new Error( + `Cannot resolve custom syntax module ${customSyntax}. Check that module ${customSyntax} is available and spelled correctly.`, + ); + } + + /* + * PostCSS allows for syntaxes that only contain a parser, however, + * it then expects the syntax to be set as the `parse` option. + */ + if (!resolved.parse) { + resolved = { + parse: resolved, + stringify: postcss.stringify, + }; + } + + return resolved; } - /* - * PostCSS allows for syntaxes that only contain a parser, however, - * it then expects the syntax to be set as the `parse` option. - */ - if (!resolved.parse) { - resolved = { - parse: resolved, - stringify: postcss.stringify, - }; + if (typeof customSyntax === 'object') { + if (typeof customSyntax.parse === 'function') { + resolved = { ...customSyntax }; + } else { + throw new Error( + `An object provided to the "customSyntax" option must have a "parse" property. Ensure the "parse" property exists and its value is a function.`, + ); + } + + return resolved; } - return resolved; + throw new Error(`Custom syntax must be a string or a Syntax object`); } /** diff --git a/types/stylelint/index.d.ts b/types/stylelint/index.d.ts index f3f68f9836..f3f8aecfa0 100644 --- a/types/stylelint/index.d.ts +++ b/types/stylelint/index.d.ts @@ -1,5 +1,5 @@ declare module 'stylelint' { - import { Result, ResultMessage, WarningOptions, Warning } from 'postcss'; + import { Result, ResultMessage, Syntax, WarningOptions, Warning } from 'postcss'; export type StylelintConfigExtends = string | Array; export type StylelintConfigPlugins = string | Array; @@ -90,7 +90,7 @@ declare module 'stylelint' { export type FormatterIdentifier = 'compact' | 'json' | 'string' | 'unix' | 'verbose' | Formatter; - export type CustomSyntax = string; + export type CustomSyntax = string | Syntax; export type StylelintOptions = { config?: StylelintConfig;