1"use strict";(self.webpackChunkstylelint_io=self.webpackChunkstylelint_io||[]).push([["2419"],{3937:function(s,e,t){t.r(e),t.d(e,{metadata:function(){return n},default:function(){return u},frontMatter:function(){return i},contentTitle:function(){return l},toc:function(){return c},assets:function(){return p}});var n=JSON.parse('{"id":"user-guide/postcss-plugin","title":"PostCSS plugin","description":"As with any other PostCSS plugin, you can use Stylelint\'s PostCSS plugin either with a PostCSS runner or with the PostCSS JS API directly.","source":"@site/docs/user-guide/postcss-plugin.md","sourceDirName":"user-guide","slug":"/user-guide/postcss-plugin","permalink":"/user-guide/postcss-plugin","draft":false,"unlisted":false,"editUrl":"https://github.com/stylelint/stylelint/edit/main/docs/user-guide/postcss-plugin.md","tags":[],"version":"current","frontMatter":{"title":"PostCSS plugin","sidebar_label":"PostCSS plugin"},"sidebar":"docs","previous":{"title":"Node.js API","permalink":"/user-guide/node-api"},"next":{"title":"Options","permalink":"/user-guide/options"}}'),r=t(4848),o=t(8453);let i={title:"PostCSS plugin",sidebar_label:"PostCSS plugin"},l="PostCSS plugin",p={},c=[{value:"Options",id:"options",level:2},{value:"Usage examples",id:"usage-examples",level:2},{value:"Example A",id:"example-a",level:3},{value:"Example B",id:"example-b",level:3}];function a(s){let e={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"postcss-plugin",children:"PostCSS plugin"})}),"\n",(0,r.jsxs)(e.p,{children:["As with any other ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss#plugins",children:"PostCSS plugin"}),", you can use Stylelint's PostCSS plugin either with a ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss#runners",children:"PostCSS runner"})," or with the PostCSS JS API directly."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.em,{children:"However, we recommend using the CLI or Node.js API (directly or via an integration) as they provide better reporting."})}),"\n",(0,r.jsx)(e.h2,{id:"options",children:"Options"}),"\n",(0,r.jsxs)(e.p,{children:["The PostCSS plugin uses the ",(0,r.jsx)(e.a,{href:"/user-guide/options",children:"standard options"}),", ",(0,r.jsxs)(e.em,{children:["except the ",(0,r.jsx)(e.code,{children:"customSyntax"})," option"]}),". Instead, the syntax must be set within the ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss#options",children:"PostCSS options"})," as there can only be one parser/syntax in a pipeline."]}),"\n",(0,r.jsx)(e.h2,{id:"usage-examples",children:"Usage examples"}),"\n",(0,r.jsx)(e.p,{children:"We recommend you lint your CSS before applying any transformations. You can do this by either:"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"creating a separate lint task that is independent of your build one."}),"\n",(0,r.jsxs)(e.li,{children:["using the ",(0,r.jsxs)(e.a,{href:"https://github.com/postcss/postcss-import#plugins",children:[(0,r.jsx)(e.code,{children:"plugins"})," option"]})," of ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss-import",children:(0,r.jsx)(e.code,{children:"postcss-import"})})," or ",(0,r.jsx)(e.a,{href:"https://github.com/TrySound/postcss-easy-import",children:(0,r.jsx)(e.code,{children:"postcss-easy-import"})})," to lint your files before any transformations."]}),"\n",(0,r.jsx)(e.li,{children:"placing Stylelint at the beginning of your plugin pipeline."}),"\n"]}),"\n",(0,r.jsxs)(e.p,{children:["You'll also need to use a reporter. ",(0,r.jsx)(e.em,{children:"The Stylelint plugin registers warnings via PostCSS"}),". Therefore, you'll want to use it with a PostCSS runner that prints warnings or another PostCSS plugin whose purpose is to format and print warnings (e.g. ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss-reporter",children:(0,r.jsx)(e.code,{children:"postcss-reporter"})}),")."]}),"\n",(0,r.jsx)(e.h3,{id:"example-a",children:"Example A"}),"\n",(0,r.jsxs)(e.p,{children:["A separate lint task that uses the plugin via the PostCSS JS API to lint SCSS using ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss-scss",children:(0,r.jsx)(e.code,{children:"postcss-scss"})}),"."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-js",children:'import fs from "node:fs";\nimport postcss from "postcss";\nimport scss from "postcss-scss";\nimport reporter from "postcss-reporter";\nimport stylelint from "stylelint";\n\n// Code to be processed\nconst code = fs.readFileSync("input.scss", "utf8");\n\npostcss([\n stylelint({/* your options */}),\n reporter({ clearReportedMessages: true })\n])\n .process(code, {\n from: "input.scss",\n syntax: scss\n })\n .then(() => {})\n .catch((err) => console.error(err.stack));\n'})}),"\n",(0,r.jsxs)(e.p,{children:["The same pattern can be used to lint other syntaxes, such as ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/sugarss",children:"SugarSS"}),"."]}),"\n",(0,r.jsx)(e.h3,{id:"example-b",children:"Example B"}),"\n",(0,r.jsxs)(e.p,{children:["A combined lint and build task where the plugin is used via the PostCSS JS API, but within ",(0,r.jsx)(e.a,{href:"https://github.com/postcss/postcss-import",children:(0,r.jsx)(e.code,{children:"postcss-import"})})," (using its ",(0,r.jsx)(e.code,{children:"plugins"})," option) so that the source files are linted before any transformations."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-js",children:'import fs from "node:fs";\nimport postcss from "postcss";\nimport atImport from "postcss-import";\nimport reporter from "postcss-reporter";\nimport stylelint from "stylelint";\n\n// CSS to be processed\nconst css = fs.readFileSync("lib/app.css", "utf8");\n\npostcss([\n atImport({\n plugins: [stylelint({/* your options */})]\n }),\n reporter({ clearReportedMessages: true })\n])\n .process(css, {\n from: "lib/app.css",\n to: "app.css"\n })\n .then((result) => {\n fs.writeFileSync("app.css", result.css);\n })\n .catch((err) => console.error(err.stack));\n'})})]})}function u(s={}){let{wrapper:e}={...(0,o.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(a,{...s})}):a(s)}},8453:function(s,e,t){t.d(e,{R:function(){return i},x:function(){return l}});var n=t(6540);let r={},o=n.createContext(r);function i(s){let e=n.useContext(o);return n.useMemo(function(){return"function"==typeof s?s(e):{...e,...s}},[e,s])}function l(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:i(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.