├── .editorconfig
├── .github
├── FUNDING.yml
└── workflows
│ ├── autofix.yml
│ ├── ci.yml
│ ├── pkg.pr.new.yml
│ └── release.yml
├── .gitignore
├── .node-version
├── .npmrc
├── .vscode
├── extensions.json
└── settings.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── README.zh-CN.md
├── biome.json
├── commitlint.config.mjs
├── docs
├── .vitepress
│ ├── config.ts
│ └── theme
│ │ ├── VAd.vue
│ │ ├── custom.css
│ │ └── index.ts
├── guide
│ ├── faq.md
│ ├── getting-started.md
│ ├── options.md
│ └── why.md
├── index.md
├── package.json
└── zh-Hans
│ ├── guide
│ ├── faq.md
│ ├── getting-started.md
│ ├── options.md
│ └── why.md
│ └── index.md
├── examples
└── react-ts
│ ├── .gitignore
│ ├── README.md
│ ├── index.html
│ ├── package.json
│ ├── public
│ └── vite.svg
│ ├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
│ ├── stylelint.config.mjs
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── lerna.json
├── lint-staged.config.mjs
├── package.json
├── packages
└── core
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── README.zh-CN.md
│ ├── build.config.ts
│ ├── package.json
│ └── src
│ ├── constants.ts
│ ├── index.ts
│ ├── types.ts
│ ├── utils.ts
│ └── worker.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── simple-git-hooks.cjs
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [ModyQyW]
2 | custom: ["https://github.com/ModyQyW/sponsors"]
3 |
--------------------------------------------------------------------------------
/.github/workflows/autofix.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/unocss/unocss/blob/fe83a90b59cf4599be57ea825166bb74d92b104c/.github/workflows/autofix.yml
2 | name: autofix.ci
3 |
4 | on:
5 | push:
6 | branches:
7 | - main
8 |
9 | pull_request:
10 | branches:
11 | - main
12 |
13 | jobs:
14 | autofix:
15 | runs-on: ubuntu-latest
16 | timeout-minutes: 10
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 |
22 | - name: Install pnpm
23 | uses: pnpm/action-setup@v4
24 |
25 | - name: Setup Node.js
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version-file: .node-version
29 | cache: pnpm
30 | registry-url: https://registry.npmjs.org
31 |
32 | - name: Setup corepack
33 | run: corepack enable
34 |
35 | - name: Install Dependencies
36 | run: pnpm install --frozen-lockfile
37 |
38 | - name: Check
39 | run: pnpm check
40 |
41 | - name: Autofix
42 | uses: autofix-ci/action@v1
43 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/unocss/unocss/blob/fe83a90b59cf4599be57ea825166bb74d92b104c/.github/workflows/ci.yml
2 | name: CI
3 |
4 | on:
5 | push:
6 | branches:
7 | - main
8 |
9 | pull_request:
10 | branches:
11 | - main
12 |
13 | merge_group: {}
14 |
15 | jobs:
16 | test:
17 | runs-on: ${{ matrix.os }}
18 |
19 | strategy:
20 | matrix:
21 | os: [ubuntu-latest, macos-latest, windows-latest]
22 | node_version: [18, 20, 22]
23 | fail-fast: false
24 |
25 | steps:
26 | - name: Set git to use LF
27 | run: |
28 | git config --global core.autocrlf false
29 | git config --global core.eol lf
30 |
31 | - name: Checkout
32 | uses: actions/checkout@v4
33 |
34 | - name: Install pnpm
35 | uses: pnpm/action-setup@v4
36 |
37 | - name: Setup Node.js ${{ matrix.node_version }}
38 | uses: actions/setup-node@v4
39 | with:
40 | node-version: ${{ matrix.node_version }}
41 | cache: pnpm
42 | registry-url: https://registry.npmjs.org
43 |
44 | - name: Setup corepack
45 | run: corepack enable
46 |
47 | - name: Install Dependencies
48 | run: pnpm install --frozen-lockfile
49 |
50 | - name: Build
51 | run: pnpm build
52 |
53 | - name: Test
54 | run: pnpm test
55 |
56 | - name: Type Check
57 | run: pnpm type-check
58 |
--------------------------------------------------------------------------------
/.github/workflows/pkg.pr.new.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/unocss/unocss/blob/fe83a90b59cf4599be57ea825166bb74d92b104c/.github/workflows/pkg.pr.new.yml
2 | name: Publish Any Commit
3 |
4 | on:
5 | pull_request:
6 | push:
7 | branches:
8 | - "**"
9 | tags:
10 | - "!**"
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v4
19 | with:
20 | fetch-depth: 0
21 |
22 | - name: Install pnpm
23 | uses: pnpm/action-setup@v4
24 |
25 | - name: Setup Node.js
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version-file: .node-version
29 | cache: pnpm
30 | registry-url: https://registry.npmjs.org
31 |
32 | - name: Setup corepack
33 | run: corepack enable
34 |
35 | - name: Install Dependencies
36 | run: pnpm install
37 |
38 | - name: Build
39 | run: pnpm build
40 |
41 | - name: Release
42 | run: pnpx pkg-pr-new publish --compact --pnpm './packages/*'
43 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/unocss/unocss/blob/fe83a90b59cf4599be57ea825166bb74d92b104c/.github/workflows/release.yml
2 | name: Release
3 |
4 | on:
5 | push:
6 | tags:
7 | - "v*"
8 |
9 | jobs:
10 | release:
11 | permissions:
12 | id-token: write
13 | contents: write
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | with:
19 | fetch-depth: 0
20 |
21 | - name: Install pnpm
22 | uses: pnpm/action-setup@v4
23 |
24 | - name: Setup Node.js
25 | uses: actions/setup-node@v4
26 | with:
27 | node-version-file: .node-version
28 | cache: pnpm
29 | registry-url: https://registry.npmjs.org
30 |
31 | - name: Setup corepack
32 | run: corepack enable
33 |
34 | - name: GitHub Release
35 | run: pnpx changelogithub
36 | env:
37 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
38 |
39 | - name: Install Dependencies
40 | run: pnpm install
41 |
42 | - name: Build
43 | run: pnpm build
44 |
45 | - name: Publish to NPM
46 | run: pnpm -r publish --access public --no-git-checks
47 | env:
48 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
49 | NPM_CONFIG_PROVENANCE: true
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | pnpm-debug.log*
9 | run
10 |
11 | # Diagnostic reports (https://nodejs.org/api/report.html)
12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
13 |
14 | # Runtime data
15 | pids
16 | *.pid
17 | *.seed
18 | *.pid.lock
19 |
20 | # Directory for instrumented libs generated by jscoverage/JSCover
21 | lib-cov
22 |
23 | # Coverage directory used by tools like istanbul
24 | coverage
25 | *.lcov
26 |
27 | # nyc test coverage
28 | .nyc_output
29 |
30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
31 | .grunt
32 |
33 | # Bower dependency directory (https://bower.io/)
34 | bower_components
35 |
36 | # node-waf configuration
37 | .lock-wscript
38 |
39 | # Compiled binary addons (https://nodejs.org/api/addons.html)
40 | build/Release
41 |
42 | # Dependency directories
43 | node_modules
44 | jspm_packages
45 |
46 | # Snowpack dependency directory (https://snowpack.dev/)
47 | web_modules
48 |
49 | # Temp directory
50 | .temp
51 | .tmp
52 |
53 | # TypeScript cache
54 | *.tsbuildinfo
55 |
56 | # Optional npm cache directory
57 | .npm
58 |
59 | # Optional eslint cache
60 | .eslintcache
61 |
62 | # Optional stylelint cache
63 | .stylelintcache
64 |
65 | # Microbundle cache
66 | .rpt2_cache
67 | .rts2_cache_cjs
68 | .rts2_cache_es
69 | .rts2_cache_umd
70 |
71 | # Optional REPL history
72 | .node_repl_history
73 |
74 | # Output of 'npm pack'
75 | *.tgz
76 |
77 | # Yarn Integrity file
78 | .yarn-integrity
79 |
80 | # dotenv environment variables file
81 | .env
82 | .env.test
83 | .env.*.test
84 | .env.local
85 | .env.*.local
86 | *.local
87 |
88 | # parcel-bundler cache (https://parceljs.org/)
89 | .cache
90 | .parcel-cache
91 |
92 | # Electron
93 | dist-electron
94 | dist_electron
95 |
96 | # Tauri
97 | dist-tauri
98 | dist_tauri
99 |
100 | # Cordova
101 | dist-cordova
102 | dist_cordova
103 |
104 | # Capacitor
105 | dist-capacitor
106 | dist_capacitor
107 |
108 | # Next.js build output
109 | .next
110 | out
111 |
112 | # Umi.js build output
113 | .umi
114 | .umi-production
115 | .umi-test
116 |
117 | # Nuxt.js build / generate output
118 | .nuxt
119 | dist
120 |
121 | # Rax.js build
122 | .rax
123 |
124 | # Vuepress build output
125 | .vuepress/dist
126 |
127 | # Vitepress build output
128 | **/.vitepress/cache
129 | **/.vitepress/dist
130 |
131 | # SSR
132 | dist-ssr
133 | dist_ssr
134 |
135 | # SSG
136 | dist-ssg
137 | dist_ssg
138 |
139 | # Serverless
140 | .serverless
141 | .dynamodb
142 | .s3
143 | .buckets
144 | .seeds
145 |
146 | # FuseBox cache
147 | .fusebox
148 |
149 | # TernJS port file
150 | .tern-port
151 |
152 | # Cypress
153 | /cypress/videos/
154 | /cypress/screenshots/
155 |
156 | # Editor
157 | .vscode-test
158 | .vscode/**
159 | !.vscode/extensions.json
160 | !.vscode/settings.json
161 | .idea
162 | .hbuilder
163 | .hbuilderx
164 | *.suo
165 | *.ntvs*
166 | *.njsproj
167 | *.sln
168 | *.sw?
169 |
170 | # yarn v2
171 | .yarn/cache
172 | .yarn/unplugged
173 | .yarn/build-state.yml
174 | .yarn/install-state.gz
175 | .pnp.*
176 |
177 | # Apple
178 | .DS_Store
179 | *.p12
180 | *.mobileprovision
181 |
182 | # Android
183 | *.keystore
184 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 22
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 | registry=https://registry.npmjs.org/
3 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["biomejs.biome"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "biomejs.biome",
3 | "editor.formatOnSave": true,
4 | "editor.codeActionsOnSave": {
5 | "quickfix.biome": "explicit",
6 | "source.organizeImports.biome": "explicit"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [6.0.0](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.2...v6.0.0) (2024-11-26)
7 |
8 | **Note:** Version bump only for package monorepo
9 |
10 | ## [6.0.0-beta.2](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.1...v6.0.0-beta.2) (2024-11-08)
11 |
12 | ### Bug Fixes
13 |
14 | * correct id & filePath params ([9c78976](https://github.com/ModyQyW/vite-plugin-stylelint/commit/9c7897659e63b4443569c72ca13b5ffe0b782a57)) - by @
15 |
16 | ## [6.0.0-beta.1](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.0...v6.0.0-beta.1) (2024-10-19)
17 |
18 | **Note:** Version bump only for package monorepo
19 |
20 | ## [6.0.0-beta.0](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v5.3.1...v6.0.0-beta.0) (2024-10-14)
21 |
22 | ### ⚠ BREAKING CHANGES
23 |
24 | * remove chokidar, introduce another way to handle imported style files
25 |
26 | ### Features
27 |
28 | * remove chokidar, introduce another way to handle imported style files ([17f3d5d](https://github.com/ModyQyW/vite-plugin-stylelint/commit/17f3d5d9955fd98e28ac36ac70b413b5225903af)) - by @ModyQyW
29 |
30 | ### Bug Fixes
31 |
32 | * fix wrong colorize ([55eb4c3](https://github.com/ModyQyW/vite-plugin-stylelint/commit/55eb4c36e8e439810e4cad9bc5186552cb41fbf1)) - by @ModyQyW
33 | * remove extra parsing ([68906c1](https://github.com/ModyQyW/vite-plugin-stylelint/commit/68906c1be6d4c679f69c16d43af99546f8cc8a8f)) - by @ModyQyW
34 | * stylelintInstance may not be initialized when calling lintFiles in the worker ([2caf01c](https://github.com/ModyQyW/vite-plugin-stylelint/commit/2caf01c21c16e365f5929f0fbf5523af7bf703ac)) - by @ModyQyW
35 | * terminate worker if possible ([acd43ca](https://github.com/ModyQyW/vite-plugin-stylelint/commit/acd43caa49e628468d318679633ca4f73158ac2e)) - by @ModyQyW
36 |
37 | ## 5.3.1 (2023-12-19)
38 |
39 | * fix: remove linterResult spread to avoid annoying warnings
40 |
41 | ## 5.3.0 (2023-12-09)
42 |
43 | * feat: support stylelint@16
44 |
45 | ## 5.2.1 (2023-11-17)
46 |
47 | * chore: update `peerDependencies`
48 |
49 | ## 5.2.0 (2023-10-23)
50 |
51 | * feat: support `rollup@4` and `vite@5`, **ATTENTION**: `rollup@4` is supported since `vite@5.0.0-beta.10`
52 |
53 | ## 5.1.1 (2023-08-23)
54 |
55 | * fix: fix wrong ignored when enable `chokidar`
56 |
57 | ## 5.1.0 (2023-08-21)
58 |
59 | ## 5.0.1 (2023-08-21)
60 |
61 | I want to publish `5.1.0` but sorry 😅
62 |
63 | * feat: add `test` option
64 |
65 | ## 5.0.0 (2023-08-16)
66 |
67 | I completely rewrote the plugin. It's still backward compatible, but there is still a possibility that the changes may affect some projects. So I bumped a major version.
68 |
69 | * feat: add `lintDirtyOnly` option
70 | * feat: add `debug`
71 | * types: add descriptions
72 | * docs: update README
73 | * feat!: update **internal functions**
74 |
75 | ## 4.3.0 (2023-03-09)
76 |
77 | * feat: export more types
78 |
79 | ## 4.2.0 (2023-02-10)
80 |
81 | * build: switch to `unbuild`
82 | * feat: support `stylelint@15`
83 | * feat: improve types
84 |
85 | ## 4.1.8 (2023-01-31)
86 |
87 | * fix: fix worker initial and close
88 |
89 | ## 4.1.7 (2023-01-30)
90 |
91 | * fix: use `__dirname` directly by accident
92 | * build: update minify and generate sourcemap
93 |
94 | ## 4.1.6 (2023-01-10)
95 |
96 | * perf: better emit handling
97 |
98 | ## 4.1.5 (2023-01-04)
99 |
100 | * build: switch to rollup
101 | * fix: lint some files twice or more
102 |
103 | ## 4.1.4 (2022-12-27)
104 |
105 | * fix: fix judge order
106 |
107 | ## 4.1.3 (2022-12-16)
108 |
109 | * perf: remove extra console
110 | * perf: worker message params
111 |
112 | ## 4.1.2 (2022-12-16)
113 |
114 | * fix: fix wrong customPrint color
115 |
116 | ## 4.1.1 (2022-12-16)
117 |
118 | * perf: internal function params
119 |
120 | ## 4.1.0 (2022-12-16)
121 |
122 | * feat: add `lintInWorker` option
123 | * perf: output syntax
124 | * perf: internal function params
125 | * perf: chokidar initial judgement
126 |
127 | ## 4.0.4 (2022-12-14)
128 |
129 | * perf: improve code
130 |
131 | ## 4.0.3 (2022-12-14)
132 |
133 | * fix: fix build
134 |
135 | ## 4.0.2 (2022-12-13)
136 |
137 | * fix: fix build
138 |
139 | ## 4.0.1 (2022-12-11)
140 |
141 | * fix: correct reading stylelint instance
142 |
143 | ## 4.0.0 (2022-12-09)
144 |
145 | * feat: support `vite@4`
146 | * feat!: require `node>=14.18`
147 | * feat!: `build` option defaults to `false`
148 | * feat!: `cacheLocation` option defaults to `.stylelintcache`
149 | * feat: esm by default
150 | * don't be afraid as commonjs is also supported
151 |
152 | ## 3.3.3 (2022-12-05)
153 |
154 | * perf: improve output syntax
155 |
156 | ## 3.3.2 (2022-12-04)
157 |
158 | * fix: fix Stylelint options lost
159 |
160 | ## 3.3.1 (2022-12-02)
161 |
162 | * fix: fix wrong behavior when enable `lintOnStart` and `chokidar`
163 | * perf: split `print`, `contextPrint` and `customPrint` functions
164 | * perf: split `pluginName` variable
165 | * perf: improve naming
166 |
167 | ## 3.3.0 (2022-11-29)
168 |
169 | * feat: add `chokidar` option
170 |
171 | ## 3.2.0 (2022-11-28)
172 |
173 | * feat: add `dev` and `build` options
174 |
175 | ## 3.1.1 (2022-11-26)
176 |
177 | * fix: fix build
178 |
179 | ## 3.1.0 (2022-11-25)
180 |
181 | * refactor
182 | * feat: add `formatter` option
183 |
184 | ## 3.0.10 (2022-11-25)
185 |
186 | * revert: revert `perf: reduce dependencies`, which breaks vite@2
187 |
188 | ## 3.0.9 (2022-11-24)
189 |
190 | * perf: reduce dependencies
191 |
192 | ## 3.0.8
193 |
194 | * fix: fix build
195 |
196 | ## 3.0.7
197 |
198 | * perf: use `config.cacheDir` to get default `cacheLocation`
199 |
200 | ## 3.0.6
201 |
202 | * fix: pass `ctx` to lintFiles method
203 |
204 | ## 3.0.5
205 |
206 | * fix: warning styles
207 |
208 | ## 3.0.4
209 |
210 | * perf: warn when `lintOnStart` is true
211 |
212 | ## 3.0.3
213 |
214 | * perf: import path from `node:path` instead of `path`
215 | * fix: fix `type: "module"` support
216 |
217 | ## 3.0.2
218 |
219 | Just update `peerDependencies` in `package.json`.
220 |
221 | ## 3.0.1
222 |
223 | * fix: fix type
224 |
225 | ## 3.0.0
226 |
227 | This version supports vite@2 and vite@3. The breaking changes are caused by aligning behaviors with `Stylelint` Node.js API.
228 |
229 | * feat!: remove `throwOnError` and `throwOnWarning` options (marked as `deprecated` before)
230 | * feat!: `include` and `exclude` options now accept `string | string[]` only to align with `stylelint.lint`
231 | * feat: add `lintOnStart` option
232 | * feat: exclude `virtual:` by default
233 |
234 | ## 2.3.1
235 |
236 | * fix: show error message when importing `stylelint` if possible
237 | * fix: include `shims` into `dist`
238 |
239 | ## 2.3.0
240 |
241 | * feat: support `vite@3`
242 | * feat: ignore virtual modules
243 | * perf: not to add `build.outDir` into `exclude`
244 | * fix: fix `then` handling
245 |
246 | ## 2.2.3
247 |
248 | * fix: revert [bee0a28](https://github.com/ModyQyW/vite-plugin-stylelint/commit/bee0a28b7691090e02d73e979bf62c27510a960d), closes [#8](https://github.com/ModyQyW/vite-plugin-stylelint/issues/8)
249 |
250 | ## 2.2.2
251 |
252 | * fix: remove `allowSyntheticDefaultImports` and `esModuleInterop` in `tsconfig.json`, closes [#5](https://github.com/ModyQyW/vite-plugin-stylelint/issues/5)
253 |
254 | ## 2.2.1
255 |
256 | * fix: try to fix `warning` output
257 | * fix: fix regressions
258 |
259 | ## 2.2.0
260 |
261 | * feat: include `.svelte` files by default
262 |
263 | ## 2.1.0
264 |
265 | * perf: better output format
266 | * feat: add `emitErrorAsWarning` and `emitWarningAsError` options
267 |
268 | ## 2.0.2
269 |
270 | * fix: fix `index.html` dealing
271 |
272 | ## 2.0.1
273 |
274 | * fix: fix `FilterPattern` type may be lost
275 |
276 | ## 2.0.0
277 |
278 | * feat: bring back `throwOnError` and `throwOnWarning`
279 |
280 | The plugin recommends `emitError` / `emitWarning` instead of `throwOnError` / `throwOnWarning` now. However, you can stay with `throwOnError` / `throwOnWarning` safely. This is actually a backward-compatible version update.
281 |
282 | ## 2.0.0-beta.0
283 |
284 | * feat: support Stylelint options
285 |
286 | ### Breaking Changes
287 |
288 | * `throwOnError` -> `emitError`
289 | * `throwOnWarning` -> `emitWarning`
290 |
291 | ## 1.3.0-beta.1
292 |
293 | * fix: `cacheLocation` use relative path
294 |
295 | ## 1.3.0-beta.0
296 |
297 | * feat: add `stylelintPath` option
298 |
299 | ## 1.2.0
300 |
301 | * feat: add `cacheLocation` option
302 | * fix: fix script
303 |
304 | ## 1.1.3
305 |
306 | * perf: minify dist by default
307 | * fix: stricter `include`
308 | * fix: ignore `index.html` `
38 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/custom.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ModyQyW/vite-plugin-stylelint/a10c6fff97c44f7fe17b72a69097f360a9c18195/docs/.vitepress/theme/custom.css
--------------------------------------------------------------------------------
/docs/.vitepress/theme/index.ts:
--------------------------------------------------------------------------------
1 | // https://vitepress.dev/guide/custom-theme
2 | import type { EnhanceAppContext, Theme } from "vitepress";
3 | import DefaultTheme from "vitepress/theme";
4 | import { h } from "vue";
5 | import VAd from "./VAd.vue";
6 | import "./custom.css";
7 |
8 | export default {
9 | extends: DefaultTheme,
10 |
11 | enhanceApp(ctx: EnhanceAppContext) {
12 | ctx.app.component("VAd", VAd);
13 | DefaultTheme.enhanceApp(ctx);
14 | },
15 |
16 | Layout() {
17 | return h(DefaultTheme.Layout, null, {
18 | // 添加广告
19 | "aside-bottom": () => [h(VAd)],
20 | });
21 | },
22 | } satisfies Theme;
23 |
--------------------------------------------------------------------------------
/docs/guide/faq.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | ## Should I use this plugin?
4 |
5 | Most of the time, you don't need this plugin.
6 |
7 | It is common to use [stylelint-webpack-plugin](https://github.com/webpack-contrib/stylelint-webpack-plugin) in Webpack. And this plugin does almost the same in Vite.
8 |
9 | However, our IDE is already probably giving all the info we need. We only need to add [Stylelint plugin](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) in VSCode. WebStorm already includes the functionality. We can also run Stylelint in CI or CLI.
10 |
11 | Since we have these ways to run Stylelint, it is unnecessary to run Stylelint in Vite, which means we don't need this plugin in most cases.
12 |
13 | If you really want to check errors and warnings, try enable `lintInWorker` option, which keeps Vite speed and prints in console. Or [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker).
14 |
15 | ## Cache is broken?
16 |
17 | Delete the cache file, fix the error manually and restart Vite.
18 |
19 | ## Plugin is running very slow?
20 |
21 | By default, the plugin is synchronous, which may cause blocking. Please try to enable `lintInWorker` option, which keeps Vite speed and prints in console. You can also try [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker), or run Stylelint directly besides Vite.
22 |
23 | ## Recommended configuration?
24 |
25 | ```ts
26 | import { defineConfig } from "vite";
27 | import stylelint from "vite-plugin-stylelint";
28 |
29 | export default defineConfig({
30 | plugins: [stylelint({
31 | lintInWorker: true,
32 | lintOnStart: true,
33 | })],
34 | });
35 |
36 | ```
37 |
38 | ## Error messages in full red?
39 |
40 | Vite's error mask layer does not support displaying `PluginContext.warn` information and full-color messages, and there are some limitations (see [#2076](https://github.com/vitejs/vite/issues/2076), [#6274](https://github.com/vitejs/vite/pull/6274) and [#8327](https://github.com/vitejs/vite/discussions/8327).
41 |
--------------------------------------------------------------------------------
/docs/guide/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ## Overview
4 |
5 | `vite-plugin-stylelint` is a project providing Stylelint plugin for Vite. Supports Vite v2 ~ v6 and Stylelint v13 ~ v16. Requires `node>=18`.
6 |
7 | > For Nuxt projects, please use [@nuxtjs/stylelint-module](https://github.com/nuxt-modules/stylelint).
8 |
9 | > You may also want [Vite ESLint plugin](https://github.com/ModyQyW/vite-plugin-eslint2).
10 |
11 | ## Install
12 |
13 | ```sh
14 | npm install vite-plugin-stylelint -D
15 | ```
16 |
17 | `vite-plugin-stylelint` does not install and config Stylelint for you. You should handle these yourself.
18 |
19 | ::: details Stylelint v16
20 |
21 | ```sh
22 | npm install stylelint@^16 -D
23 | ```
24 |
25 | :::
26 |
27 | ::: details Stylelint v15
28 |
29 | ```sh
30 | npm install stylelint@^15 -D
31 | ```
32 |
33 | :::
34 |
35 | ::: details Stylelint v14
36 |
37 | ```sh
38 | npm install stylelint@^14 -D
39 | ```
40 |
41 | :::
42 |
43 | ::: details Stylelint v13
44 |
45 | ```sh
46 | npm install stylelint@^13 @types/stylelint@^13 -D
47 | ```
48 |
49 | :::
50 |
51 | ## Usage
52 |
53 | ```typescript
54 | // vite.config.ts
55 | import { defineConfig } from "vite";
56 | import stylelint from "vite-plugin-stylelint";
57 |
58 | export default defineConfig({
59 | plugins: [stylelint()],
60 | });
61 |
62 | ```
63 |
64 | ## Acknowledge
65 |
66 | Initially forked from [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint).
67 |
68 | ## Contributors
69 |
70 | This project was created by [ModyQyW](https://github.com/ModyQyW).
71 |
72 | Thanks to [all contributors](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) for their contributions!
73 |
74 | ## Sponsors
75 |
76 | If this package is helpful to you, please consider [sponsoring](https://github.com/ModyQyW/sponsors), which will benefit the ongoing development and maintenance of the project.
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/docs/guide/options.md:
--------------------------------------------------------------------------------
1 | # Options
2 |
3 | You can pass Stylelint [shared options](https://stylelint.io/user-guide/options) to the plugin, or you can pass the extra options. The `files` option will always be overridden.
4 |
5 | ## Shared Options
6 |
7 | Common options and descriptions are listed below, complete links are provided above.
8 |
9 | ### `fix`
10 |
11 | - Type: `boolean`
12 | - Default: `false`
13 |
14 | Whether to automatically fix.
15 |
16 | ### `cache`
17 |
18 | - Type: `boolean`
19 | - Stylelint default: `false`
20 | - Plugin default: `true`
21 |
22 | Whether to enable the cache. This is disabled in Stylelint by default and enabled in plugin by default to improve speed.
23 |
24 | ### `cacheLocation`
25 |
26 | - Type: `string`
27 | - Default: `.stylelintcache`
28 |
29 | The path to the cache.
30 |
31 | ## Extra Options
32 |
33 | Extra options and explanations are listed below.
34 |
35 | ### `test`
36 |
37 | - Type: `boolean`
38 | - Default: `false`
39 |
40 | Whether to run Stylelint under `test` mode. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) and [Configuring Vitest](https://vitest.dev/guide/#configuring-vitest) for more.
41 |
42 | ### `dev`
43 |
44 | - Type: `boolean`
45 | - Default: `true`
46 |
47 | Whether to run Stylelint under `serve` command. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) for more.
48 |
49 | ### `build`
50 |
51 | - Type: `boolean`
52 | - Default: `false`
53 |
54 | Whether to run Stylelint under `build` command. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) for more.
55 |
56 | ### `include`
57 |
58 | - Type: `string | string[]`
59 | - Default: `["src/**/*.{css,scss,sass,less,styl,vue,svelte}"]`
60 |
61 | This option specifies the files you want to lint. You don't need to change it in most cases, unless the `include` and `exclude` ranges overlap.
62 |
63 | If you're using the plugin defaults, the plugin will only call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `transform` hook. The option value will be used to [create a filter](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) to determine if the call should be made and the parameter of the call, which means that the option value needs to fulfill the requirements of [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1).
64 |
65 | If you enable the `lintOnStart` option, the plugin will also call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `buildStart` hook. The option value will not be used to create a filter, but will be used directly as the call parameter, which means that the option value also needs to fulfill the [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) requirement.
66 |
67 | If you disable the `lintDirtyOnly` option, the plugin will use the option value as the call parameter every time it calls [stylelint.lint](https://stylelint.io/user-guide/node-api/), which means that the option value also needs to fulfill the requirements of [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0).
68 |
69 | ### `exclude`
70 |
71 | - Type: `string | string[]`
72 | - Default: `['node_modules', 'virtual:']`
73 |
74 | This option specifies the files you don't want to lint. You don't need to change it in most cases, unless the `include` and `exclude` ranges overlap.
75 |
76 | The plugin forces the virtual module to be ignored and you don't need to do any configuration related to it here.
77 |
78 | If you're using the plugin defaults, the plugin will only call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `transform` hook. The option value will be used to [create a filter](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) to determine if the call should be made and the parameter of the call, which means that the option value needs to fulfill the requirements of [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1).
79 |
80 | If you enable the `lintOnStart` option or disable the `lintDirtyOnly` option, the option value will not take effect. You need to change `include` value to include this option value.
81 |
82 | ### `stylelintPath`
83 |
84 | - Type: `string`
85 | - Default: `"stylelint"`
86 |
87 | Path to Stylelint that will be used for linting. Use [dynamic import](https://javascript.info/modules-dynamic-imports) under the hood. Read [Vite server.fs options](https://vitejs.dev/config/server-options.html#server-fs-strict) first.
88 |
89 | ### `formatter`
90 |
91 | - Type: `string`
92 | - Default: `"string"`
93 |
94 | The name, the path or the function implementation of a formatter. This is used to [set a formatter](https://stylelint.io/user-guide/usage/options#formatter) in order to convert lint results to a human- or machine-readable string.
95 |
96 | ### `lintInWorker`
97 |
98 | - Type: `boolean`
99 | - Default: `false`
100 |
101 | Lint in [worker](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-tran). This is disabled by default.
102 |
103 | When lint in worker, Vite build process will be faster. You will not see Vite error overlay, Vite build process will not be stopped, even with errors shown in terminal.
104 |
105 | It is similar with [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker), but vite-plugin-checker can show you errors and warnings in browsers.
106 |
107 | ### `lintOnStart`
108 |
109 | - Type: `boolean`
110 | - Default: `false`
111 |
112 | Lint `include` option specified files once in `buildStart` hook to find potential errors. This is disabled by default.
113 |
114 | This will significantly slow down Vite first starting if you have no caches and don't enable `lintInWorker`.
115 |
116 | ### `lintDirtyOnly`
117 |
118 | - Type: `boolean`
119 | - Default: `true`
120 |
121 | Whether or not to checkout only modified files that are not included in the `exclude` option value when running Stylelint outside of the `buildStart` lifecycle. Enabled by default.
122 |
123 | When disabled, files are checked against the `include` and `exclude` option values.
124 |
125 | ### `emitError`
126 |
127 | - Type: `boolean`
128 | - Default: `true`
129 |
130 | Emit found errors. This is enabled by default.
131 |
132 | ### `emitErrorAsWarning`
133 |
134 | - Type: `boolean`
135 | - Default: `false`
136 |
137 | Emit found errors as warnings. This is disabled by default but you may want it enabled when prototyping.
138 |
139 | ### `emitWarning`
140 |
141 | - Type: `boolean`
142 | - Default: `true`
143 |
144 | Emit found warnings. This is enabled by default.
145 |
146 | ### `emitWarningAsError`
147 |
148 | - Type: `boolean`
149 | - Default: `false`
150 |
151 | Emit found warnings as errors when enabled. This is disabled by default.
152 |
--------------------------------------------------------------------------------
/docs/guide/why.md:
--------------------------------------------------------------------------------
1 | # Why?
2 |
3 | ## Reason
4 |
5 | This project is forked from [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint) to run Stylelint in Vite.
6 |
7 | There are also [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) that provide similar functionality, please choose one to use according to your needs.
8 |
9 | ## Acknowledge
10 |
11 | Initially forked from [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint).
12 |
13 | ## Contributors
14 |
15 | This project was created by [ModyQyW](https://github.com/ModyQyW).
16 |
17 | Thanks to [all contributors](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) for their contributions!
18 |
19 | ## Sponsors
20 |
21 | If this package is helpful to you, please consider [sponsoring](https://github.com/ModyQyW/sponsors), which will benefit the ongoing development and maintenance of the project.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # https://vitepress.dev/reference/default-theme-home-page
3 | layout: home
4 |
5 | hero:
6 | name: "vite-plugin-stylelint"
7 | tagline: "Stylelint plugin for Vite"
8 | actions:
9 | - theme: brand
10 | text: Get Started →
11 | link: /guide/getting-started
12 | - theme: alt
13 | text: Why?
14 | link: /guide/why
15 | - theme: alt
16 | text: View on GitHub
17 | link: https://github.com/ModyQyW/vite-plugin-stylelint
18 | # image:
19 | # src: /logo.png
20 | # alt: _repo_
21 | # features:
22 | # - title: "_feature_"
23 | # details: _feature-details_
24 | # link: /guide/_feature_
25 | ---
26 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "version": "4.4.1",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "build": "vitepress build .",
8 | "dev": "vitepress dev .",
9 | "preview": "vitepress preview ."
10 | },
11 | "devDependencies": {
12 | "vitepress": "^1.5.0",
13 | "vue": "^3.5.13"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/docs/zh-Hans/guide/faq.md:
--------------------------------------------------------------------------------
1 | # 常见问题
2 |
3 | ## 我应该使用这个插件吗?
4 |
5 | 大多数情况下不需要。
6 |
7 | 在 Webpack 使用 [stylelint-webpack-plugin](https://github.com/webpack-contrib/stylelint-webpack-plugin) 是很常见的,而这个插件在 Vite 中做着几乎一样的事情。
8 |
9 | 但是,我们的 IDE 可以直接显示相对应的校验信息。对于 VS Code,我们只需要添加 [Stylelint 插件](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)。WebStorm 已经内置了这个功能。此外,我们也可以在命令行或者 CI 中运行 Stylelint 来获取反馈。
10 |
11 | 我们有这么多方法运行 Stylelint,没有太大必要再在 Vite 中运行 Stylelint,这也就意味着我们在大多数情况下不需要这个插件。
12 |
13 | 如果你真的很需要查看错误和警告,请尝试启用 `lintInWorker` 选项,它保持了 Vite 的速度,并在控制台中打印信息。你也可以尝试一下社区内的 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker)。
14 |
15 | ## 缓存失效了?
16 |
17 | 删除缓存文件,手动修复错误后重启 Vite 即可。
18 |
19 | ## 插件运行非常慢?
20 |
21 | 默认地,插件是同步运行的,这可能会造成阻塞。请尝试启用 `lintInWorker` 选项,它保持了 Vite 的速度,并在控制台中打印信息。你也可以尝试一下社区内的 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker),或者在 Vite 之外直接运行 Stylelint。
22 |
23 | ## 推荐配置?
24 |
25 | ```ts
26 | import { defineConfig } from "vite";
27 | import stylelint from "vite-plugin-stylelint";
28 |
29 | export default defineConfig({
30 | plugins: [stylelint({
31 | lintInWorker: true,
32 | lintOnStart: true,
33 | })],
34 | });
35 |
36 | ```
37 |
38 | ## 错误信息全红?
39 |
40 | Vite 的错误遮罩层不支持显示 `PluginContext.warn` 信息和全色消息,还有一些限制(参见 [#2076](https://github.com/vitejs/vite/issues/2076)、[#6274](https://github.com/vitejs/vite/pull/6274) 和 [#8327](https://github.com/vitejs/vite/discussions/8327))。
41 |
--------------------------------------------------------------------------------
/docs/zh-Hans/guide/getting-started.md:
--------------------------------------------------------------------------------
1 | # 起步
2 |
3 | ## 总览
4 |
5 | `vite-plugin-stylelint` 是 Vite Stylelint 插件。支持 Vite v2 ~ v6 和 Stylelint v13 ~ v16。要求 `node>=18`。
6 |
7 | > 对于 Nuxt 项目,请使用[@nuxtjs/stylelint-module](https://github.com/nuxt-modules/stylelint)。
8 |
9 | > 你也可能想要 [Vite ESlint 插件](https://github.com/ModyQyW/vite-plugin-eslint2)。
10 |
11 | ## 安装
12 |
13 | ```sh
14 | npm install vite-plugin-stylelint -D
15 | ```
16 |
17 | `vite-plugin-stylelint` 不会为你安装和配置 Stylelint。你应该自己处理这些。
18 |
19 | ::: details Stylelint v16
20 |
21 | ```sh
22 | npm install stylelint@^16 -D
23 | ```
24 |
25 | :::
26 |
27 | ::: details Stylelint v15
28 |
29 | ```sh
30 | npm install stylelint@^15 -D
31 | ```
32 |
33 | :::
34 |
35 | ::: details Stylelint v14
36 |
37 | ```sh
38 | npm install stylelint@^14 -D
39 | ```
40 |
41 | :::
42 |
43 | ::: details Stylelint v13
44 |
45 | ```sh
46 | npm install stylelint@^13 @types/stylelint@^13 -D
47 | ```
48 |
49 | :::
50 |
51 | ## 使用
52 |
53 | ```typescript
54 | // vite.config.ts
55 | import { defineConfig } from "vite";
56 | import stylelint from "vite-plugin-stylelint";
57 |
58 | export default defineConfig({
59 | plugins: [stylelint()],
60 | });
61 |
62 | ```
63 |
64 | ## 致谢
65 |
66 | 最初从 [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint) 分叉出来。
67 |
68 | ## 贡献者们
69 |
70 | 该项目由 [ModyQyW](https://github.com/ModyQyW) 创建。
71 |
72 | 感谢 [所有贡献者](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) 的付出!
73 |
74 | ## 赞助
75 |
76 | 如果这个包对你有所帮助,请考虑 [赞助](https://github.com/ModyQyW/sponsors) 支持,这将有利于项目持续开发和维护。
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/docs/zh-Hans/guide/options.md:
--------------------------------------------------------------------------------
1 | # 选项配置
2 |
3 | 你可以给这个插件传递 Stylelint [shared options](https://stylelint.io/user-guide/options),也可以传递这个插件特有的额外选项。`files` 选项总是会被覆盖。
4 |
5 | ## 构造器选项
6 |
7 | 常见的自带选项和说明如下,完整内容请查看上方链接。
8 |
9 | ### `fix`
10 |
11 | - 类型:`boolean`
12 | - 默认值:`false`
13 |
14 | 是否自动修复。
15 |
16 | ### `cache`
17 |
18 | - 类型:`boolean`
19 | - Stylelint 默认值:`false`
20 | - 插件默认值:`true`
21 |
22 | 是否启用缓存。Stylelint 默认禁用,插件默认启用以提高速度。
23 |
24 | ### `cacheLocation`
25 |
26 | - 类型:`string`
27 | - 默认值:`.stylelintcache`
28 |
29 | 缓存位置。
30 |
31 | ## 额外选项
32 |
33 | 额外的选项和说明如下。
34 |
35 | ### `test`
36 |
37 | - 类型:`boolean`
38 | - 默认值:`false`
39 |
40 | 是否在 `test` 模式下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 和 [配置 Vitest](https://cn.vitest.dev/guide/) 了解更多。
41 |
42 | ### `dev`
43 |
44 | - 类型:`boolean`
45 | - 默认值:`true`
46 |
47 | 是否在 `serve` 命令下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 了解更多。
48 |
49 | ### `build`
50 |
51 | - 类型:`boolean`
52 | - 默认值:`false`
53 |
54 | 是否在 `build` 命令下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 了解更多。
55 |
56 | ### `include`
57 |
58 | - 类型:`string | string[]`
59 | - 默认值:`["src/**/*.{css,scss,sass,less,styl,vue,svelte}"]`
60 |
61 | 这个选项指定你想要校验的文件模式。在绝大部分情况下,你并不需要调整它,除非 `include` 和 `exclude` 范围有重合。
62 |
63 | 如果你正在使用插件默认设置,插件只会在 `transform` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值会被用于 [创建一个过滤器](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) 来确定是否该调用以及调用参数。这意味着选项值需要满足 [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1) 的要求。
64 |
65 | 如果你启用了 `lintOnStart` 选项,插件还会在 `buildStart` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值不会用于创建过滤器,而是直接用作调用参数。这意味着这个选项值还需要满足 [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) 的要求。
66 |
67 | 如果你禁用了 `lintDirtyOnly` 选项,插件每次调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/) 时都会将该选项值作为调用参数。这意味着这个选项值也需要满足 [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) 的要求。
68 |
69 | ### `exclude`
70 |
71 | - 类型:`string | string[]`
72 | - 默认值:`['node_modules', 'virtual:']`
73 |
74 | 这个选项指定你不想要校验的文件模式。在绝大部分情况下,你并不需要调整它,除非 `include` 和 `exclude` 范围有重合。
75 |
76 | 插件强制忽略虚拟模块,你不需要在这里进行任何相关配置。
77 |
78 | 如果你正在使用插件默认设置,插件只会在 `transform` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值会被用于 [创建一个过滤器](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) 来确定是否该调用以及调用参数。这意味着选项值需要满足 [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1) 的要求。
79 |
80 | 如果你启用了 `lintOnStart` 选项或者禁用了 `lintDirtyOnly` 选项,这个选项值不会生效。你需要调整 `include` 值以包含该选项值。
81 |
82 | ### `stylelintPath`
83 |
84 | - 类型:`string`
85 | - 默认值:`"stylelint"`
86 |
87 | Stylelint 路径,用于校验文件。底层使用使用 [dynamic import](https://javascript.info/modules-dynamic-imports)。请先阅读 [Vite server.fs 选项](https://cn.vitejs.dev/config/server-options.html#server-fs-strict)。
88 |
89 | ### `formatter`
90 |
91 | - 类型:`string`
92 | - 默认值:`"string"`
93 |
94 | 格式化器的名称、路径或函数实现。用于 [设置格式化器](https://stylelint.io/user-guide/usage/options#formatter),以便将校验结果转换为人类或机器可读的字符串。
95 |
96 | ### `lintInWorker`
97 |
98 | - 类型:`boolean`
99 | - 默认值:`false`
100 |
101 | 在 [worker](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-tran) 校验。默认禁用。
102 |
103 | 在 worker 中校验时,Vite 的构建过程会更快。即使终端显示了 Stylelint 校验错误,你也不会看到 Vite 错误遮罩层,Vite 构建也不会停止。
104 |
105 | 这与 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) 类似,但 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) 可以在浏览器中显示错误。
106 |
107 | ### `lintOnStart`
108 |
109 | - 类型:`boolean`
110 | - 默认值:`false`
111 |
112 | 在 `buildStart` 生命周期中校验 `include` 选项指定的文件一次以发现潜在的错误。默认禁用。
113 |
114 | 如果你没有缓存而且没有启用 `lintInWorker`,这将大大降低 Vite 的初次启动速度。
115 |
116 | ### `lintDirtyOnly`
117 |
118 | - 类型:`boolean`
119 | - 默认值:`true`
120 |
121 | 在 `buildStart` 生命周期之外运行 Stylelint 时,是否只校验修改过且没有包含在 `exclude` 选项值内的文件。默认启用。
122 |
123 | 禁用时,会根据 `include` 和 `exclude` 选项值确定需要校验文件。
124 |
125 | ### `emitError`
126 |
127 | - 类型:`boolean`
128 | - 默认值:`true`
129 |
130 | 输出发现的错误。默认启用。
131 |
132 | ### `emitErrorAsWarning`
133 |
134 | - 类型:`boolean`
135 | - 默认值:`false`
136 |
137 | 将发现的错误作为警告输出。默认禁用,但你可能会在开发原型时启用这个。
138 |
139 | ### `emitWarning`
140 |
141 | - 类型:`boolean`
142 | - 默认值:`true`
143 |
144 | 输出发现的警告。默认启用。
145 |
146 | ### `emitWarningAsError`
147 |
148 | - 类型:`boolean`
149 | - 默认值:`false`
150 |
151 | 将发现的警告作为错误输出。默认禁用。
152 |
--------------------------------------------------------------------------------
/docs/zh-Hans/guide/why.md:
--------------------------------------------------------------------------------
1 | # 为什么?
2 |
3 | ## 起因
4 |
5 | 这个项目最初从 [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint) 分叉出来以在 Vite 中运行 Stylelint。
6 |
7 | 社区还有 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) 提供了类似的功能,请根据你的意愿选择一个来使用。
8 |
9 | ## 致谢
10 |
11 | 最初从 [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint) 分叉出来。
12 |
13 | ## 贡献者们
14 |
15 | 该项目由 [ModyQyW](https://github.com/ModyQyW) 创建。
16 |
17 | 感谢 [所有贡献者](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) 的付出!
18 |
19 | ## 赞助
20 |
21 | 如果这个包对你有所帮助,请考虑 [赞助](https://github.com/ModyQyW/sponsors) 支持,这将有利于项目持续开发和维护。
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/zh-Hans/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # https://vitepress.dev/reference/default-theme-home-page
3 | layout: home
4 |
5 | hero:
6 | name: "vite-plugin-stylelint"
7 | tagline: "Vite Stylelint 插件"
8 | actions:
9 | - theme: brand
10 | text: 起步 →
11 | link: /zh-Hans/guide/getting-started
12 | - theme: alt
13 | text: 为什么?
14 | link: /zh-Hans/guide/why
15 | - theme: alt
16 | text: 在 GitHub 查看
17 | link: https://github.com/ModyQyW/vite-plugin-stylelint
18 | # image:
19 | # src: /logo.png
20 | # alt: _repo_
21 | # features:
22 | # - title: "_特性_"
23 | # details: _特性细节_
24 | # link: /zh-Hans/guide/_feature_
25 | ---
26 |
--------------------------------------------------------------------------------
/examples/react-ts/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/react-ts/README.md:
--------------------------------------------------------------------------------
1 | # React + TypeScript + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
10 | ## Expanding the ESLint configuration
11 |
12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13 |
14 | - Configure the top-level `parserOptions` property like this:
15 |
16 | ```js
17 | export default tseslint.config({
18 | languageOptions: {
19 | // other options...
20 | parserOptions: {
21 | project: ['./tsconfig.node.json', './tsconfig.app.json'],
22 | tsconfigRootDir: import.meta.dirname,
23 | },
24 | },
25 | })
26 | ```
27 |
28 | - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29 | - Optionally add `...tseslint.configs.stylisticTypeChecked`
30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
31 |
32 | ```js
33 | // eslint.config.js
34 | import react from 'eslint-plugin-react'
35 |
36 | export default tseslint.config({
37 | // Set the react version
38 | settings: { react: { version: '18.3' } },
39 | plugins: {
40 | // Add the react plugin
41 | react,
42 | },
43 | rules: {
44 | // other rules...
45 | // Enable its recommended rules
46 | ...react.configs.recommended.rules,
47 | ...react.configs['jsx-runtime'].rules,
48 | },
49 | })
50 | ```
51 |
--------------------------------------------------------------------------------
/examples/react-ts/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/react-ts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-ts",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc -b && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "react": "^18.3.1",
13 | "react-dom": "^18.3.1"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^18.3.12",
17 | "@types/react-dom": "^18.3.1",
18 | "@vitejs/plugin-react-swc": "^3.7.2",
19 | "less": "^4.2.1",
20 | "sass-embedded": "^1.81.0",
21 | "stylelint": "^16.10.0",
22 | "stylelint-config-recommended": "^14.0.1",
23 | "stylelint-config-recommended-scss": "^14.1.0",
24 | "stylus": "^0.64.0",
25 | "typescript": "^5.7.2",
26 | "vite": "^6.0.0",
27 | "vite-plugin-stylelint": "workspace: *"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/react-ts/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/react-ts/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/examples/react-ts/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import viteLogo from '/vite.svg'
4 | import './App.css'
5 |
6 | function App() {
7 | const [count, setCount] = useState(0)
8 |
9 | return (
10 | <>
11 |
19 | Vite + React
20 |
21 |
setCount((count) => count + 1)}>
22 | count is {count}
23 |
24 |
25 | Edit src/App.tsx
and save to test HMR
26 |
27 |
28 |
29 | Click on the Vite and React logos to learn more
30 |
31 | >
32 | )
33 | }
34 |
35 | export default App
36 |
--------------------------------------------------------------------------------
/examples/react-ts/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/react-ts/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | body {
26 | margin: 0;
27 | display: flex;
28 | place-items: center;
29 | min-width: 320px;
30 | min-height: 100vh;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | button {
39 | border-radius: 8px;
40 | border: 1px solid transparent;
41 | padding: 0.6em 1.2em;
42 | font-size: 1em;
43 | font-weight: 500;
44 | font-family: inherit;
45 | background-color: #1a1a1a;
46 | cursor: pointer;
47 | transition: border-color 0.25s;
48 | }
49 | button:hover {
50 | border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 | outline: 4px auto -webkit-focus-ring-color;
55 | }
56 |
57 | @media (prefers-color-scheme: light) {
58 | :root {
59 | color: #213547;
60 | background-color: #ffffff;
61 | }
62 | a:hover {
63 | color: #747bff;
64 | }
65 | button {
66 | background-color: #f9f9f9;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/examples/react-ts/src/main.tsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from "react";
2 | import { createRoot } from "react-dom/client";
3 | import App from "./App.tsx";
4 | import "./index.css";
5 |
6 | createRoot(document.getElementById("root")!).render(
7 |
8 |
9 | ,
10 | );
11 |
--------------------------------------------------------------------------------
/examples/react-ts/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/react-ts/stylelint.config.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | extends: ["stylelint-config-recommended-scss"],
3 | };
4 |
--------------------------------------------------------------------------------
/examples/react-ts/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"]
24 | }
25 |
--------------------------------------------------------------------------------
/examples/react-ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/examples/react-ts/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "lib": ["ES2023"],
5 | "module": "ESNext",
6 | "skipLibCheck": true,
7 |
8 | /* Bundler mode */
9 | "moduleResolution": "bundler",
10 | "allowImportingTsExtensions": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | "noEmit": true,
14 |
15 | /* Linting */
16 | "strict": true,
17 | "noUnusedLocals": true,
18 | "noUnusedParameters": true,
19 | "noFallthroughCasesInSwitch": true
20 | },
21 | "include": ["vite.config.ts"]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/react-ts/vite.config.ts:
--------------------------------------------------------------------------------
1 | import react from "@vitejs/plugin-react-swc";
2 | import { defineConfig } from "vite";
3 | import stylelint from "vite-plugin-stylelint";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), stylelint()],
8 | });
9 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/@lerna-lite/cli/schemas/lerna-schema.json",
3 | "version": "6.0.0",
4 | "npmClient": "pnpm",
5 | "packages": [
6 | "packages/*"
7 | ],
8 | "command": {
9 | "version": {
10 | "allowBranch": "main",
11 | "conventionalCommits": true,
12 | "changelogIncludeCommitsClientLogin": " - by @%l",
13 | "message": "chore: release %s",
14 | "remoteClient": "github"
15 | }
16 | },
17 | "changelogPreset": "conventional-changelog-conventionalcommits",
18 | "ignoreChanges": [
19 | "**/test/**",
20 | "**/tests/**",
21 | "**/__test__/**",
22 | "**/__tests__/**",
23 | "**/*.md"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/lint-staged.config.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | "*": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true",
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "monorepo",
3 | "version": "0.0.0",
4 | "private": true,
5 | "homepage": "https://github.com/ModyQyW/vite-plugin-stylelint",
6 | "bugs": {
7 | "url": "https://github.com/ModyQyW/vite-plugin-stylelint/issues"
8 | },
9 | "repository": "git+https://github.com/ModyQyW/vite-plugin-stylelint.git",
10 | "license": "MIT",
11 | "author": {
12 | "name": "ModyQyW",
13 | "email": "wurui.dev@gmail.com",
14 | "url": "https://modyqyw.top"
15 | },
16 | "sideEffects": false,
17 | "type": "module",
18 | "scripts": {
19 | "build": "rimraf packages/*/dist --glob && pnpm -r --filter=./packages/* run build && pnpm -r run build-post",
20 | "check": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true",
21 | "dep-update": "taze -fw",
22 | "dev": "pnpm stub",
23 | "docs:build": "pnpm -C docs run build",
24 | "docs:dev": "pnpm -C docs run dev",
25 | "docs:preview": "pnpm -C docs run preview",
26 | "preinstall": "npx only-allow pnpm",
27 | "prepare": "is-ci || simple-git-hooks",
28 | "prepublishOnly": "pnpm run build",
29 | "release": "lerna version",
30 | "stub": "pnpm -r --filter=./packages/* --parallel run stub",
31 | "test": "vitest run --passWithNoTests",
32 | "test:coverage": "vitest run --passWithNoTests --coverage",
33 | "type-check": "tsc --noEmit",
34 | "preversion": "git-branch-is main && conc \"pnpm:check\" \"pnpm:type-check\" \"pnpm:test\""
35 | },
36 | "dependencies": {
37 | "@rollup/pluginutils": "^5.1.3",
38 | "debug": "^4.3.7"
39 | },
40 | "devDependencies": {
41 | "@biomejs/biome": "^1.9.4",
42 | "@commitlint/cli": "^19.6.0",
43 | "@commitlint/config-conventional": "^19.6.0",
44 | "@commitlint/config-pnpm-scopes": "^19.5.0",
45 | "@lerna-lite/cli": "^3.10.0",
46 | "@lerna-lite/version": "^3.10.0",
47 | "@types/node": "^22.10.0",
48 | "@vitest/coverage-v8": "^2.1.6",
49 | "concurrently": "^9.1.0",
50 | "conventional-changelog-conventionalcommits": "^7.0.2",
51 | "git-branch-is": "^4.0.0",
52 | "is-ci": "^3.0.1",
53 | "lint-staged": "^15.2.10",
54 | "rimraf": "^6.0.1",
55 | "simple-git-hooks": "^2.11.1",
56 | "taze": "^0.18.0",
57 | "typescript": "^5.7.2",
58 | "unbuild": "^3.0.0-rc.11",
59 | "vitest": "^2.1.6"
60 | },
61 | "packageManager": "pnpm@9.14.2",
62 | "engines": {
63 | "node": ">=20.11.0 || >=21.2.0"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/packages/core/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [6.0.0](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.2...v6.0.0) (2024-11-26)
7 |
8 | **Note:** Version bump only for package vite-plugin-stylelint
9 |
10 | ## [6.0.0-beta.2](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.1...v6.0.0-beta.2) (2024-11-08)
11 |
12 | ### Bug Fixes
13 |
14 | * correct id & filePath params ([9c78976](https://github.com/ModyQyW/vite-plugin-stylelint/commit/9c7897659e63b4443569c72ca13b5ffe0b782a57)) - by @
15 |
16 | ## [6.0.0-beta.1](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v6.0.0-beta.0...v6.0.0-beta.1) (2024-10-19)
17 |
18 | **Note:** Version bump only for package vite-plugin-stylelint
19 |
20 | ## [6.0.0-beta.0](https://github.com/ModyQyW/vite-plugin-stylelint/compare/v5.3.1...v6.0.0-beta.0) (2024-10-14)
21 |
22 | ### ⚠ BREAKING CHANGES
23 |
24 | * remove chokidar, introduce another way to handle imported style files
25 |
26 | ### Features
27 |
28 | * remove chokidar, introduce another way to handle imported style files ([17f3d5d](https://github.com/ModyQyW/vite-plugin-stylelint/commit/17f3d5d9955fd98e28ac36ac70b413b5225903af)) - by @ModyQyW
29 |
30 | ### Bug Fixes
31 |
32 | * fix wrong colorize ([55eb4c3](https://github.com/ModyQyW/vite-plugin-stylelint/commit/55eb4c36e8e439810e4cad9bc5186552cb41fbf1)) - by @ModyQyW
33 | * remove extra parsing ([68906c1](https://github.com/ModyQyW/vite-plugin-stylelint/commit/68906c1be6d4c679f69c16d43af99546f8cc8a8f)) - by @ModyQyW
34 | * stylelintInstance may not be initialized when calling lintFiles in the worker ([2caf01c](https://github.com/ModyQyW/vite-plugin-stylelint/commit/2caf01c21c16e365f5929f0fbf5523af7bf703ac)) - by @ModyQyW
35 | * terminate worker if possible ([acd43ca](https://github.com/ModyQyW/vite-plugin-stylelint/commit/acd43caa49e628468d318679633ca4f73158ac2e)) - by @ModyQyW
36 |
--------------------------------------------------------------------------------
/packages/core/README.md:
--------------------------------------------------------------------------------
1 | # vite-plugin-stylelint
2 |
3 | English | [简体中文](./README.zh-CN.md)
4 |
5 |
16 |
17 | ## Introduction
18 |
19 | Stylelint plugin for Vite. Supports Vite v2 ~ v6 and Stylelint v13 ~ v16. Requires `node>=18`.
20 |
21 | 👇 See the documentation for specific usage and examples.
22 |
23 | [Cloudflare Pages](https://vite-plugin-stylelint.modyqyw.top/)
24 |
25 | > You may also want [ESLint plugin for Vite](https://github.com/ModyQyW/vite-plugin-eslint2).
26 |
27 | ## Install
28 |
29 | ```sh
30 | npm install vite-plugin-stylelint -D
31 | ```
32 |
33 | `vite-plugin-stylelint` does not install and config Stylelint for you. You should handle these yourself.
34 |
35 |
36 |
37 | Stylelint v16
38 |
39 | ```sh
40 | npm install stylelint@^16 -D
41 | ```
42 |
43 |
44 |
45 |
46 |
47 | Stylelint v15
48 |
49 | ```sh
50 | npm install stylelint@^15 -D
51 | ```
52 |
53 |
54 |
55 |
56 |
57 | Stylelint v14
58 |
59 | ```sh
60 | npm install stylelint@^14 -D
61 | ```
62 |
63 |
64 |
65 |
66 |
67 | Stylelint v13
68 |
69 | ```sh
70 | npm install stylelint@^13 @types/stylelint@^13 -D
71 | ```
72 |
73 |
74 |
75 | ## Usage
76 |
77 | ```typescript
78 | // vite.config.ts
79 | import { defineConfig } from "vite";
80 | import stylelint from "vite-plugin-stylelint";
81 |
82 | export default defineConfig({
83 | plugins: [stylelint()],
84 | });
85 | ```
86 |
87 | 👇 See the documentation for specific usage and examples.
88 |
89 | [Cloudflare Pages](https://vite-plugin-stylelint.modyqyw.top/)
90 |
91 | ## Acknowledge
92 |
93 | Initially forked from [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint).
94 |
95 | ## Contributors
96 |
97 | This project was created by [ModyQyW](https://github.com/ModyQyW).
98 |
99 | Thanks to [all contributors](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) for their contributions!
100 |
101 | ## Sponsors
102 |
103 | If this package is helpful to you, please consider [sponsoring](https://github.com/ModyQyW/sponsors), which will benefit the ongoing development and maintenance of the project.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/packages/core/README.zh-CN.md:
--------------------------------------------------------------------------------
1 | # vite-plugin-stylelint
2 |
3 | [English](./README.md) | 简体中文
4 |
5 |
16 |
17 | ## 介绍
18 |
19 | Vite Stylelint 插件。支持 Vite v2 ~ v6 和 Stylelint v13 ~ v16。要求 `node>=18`。
20 |
21 | 👇 请查看文档了解具体用法和示例。
22 |
23 | [Cloudflare Pages](https://vite-plugin-stylelint.modyqyw.top/)
24 |
25 | > 你也可能想要 [Vite ESLint 插件](https://github.com/ModyQyW/vite-plugin-eslint2)。
26 |
27 | ## 安装
28 |
29 | ```sh
30 | npm install vite-plugin-stylelint -D
31 | ```
32 |
33 | `vite-plugin-stylelint` 不会为你安装和配置 Stylelint。你应该自己处理这些。
34 |
35 |
36 |
37 | Stylelint v16
38 |
39 | ```sh
40 | npm install stylelint@^16 -D
41 | ```
42 |
43 |
44 |
45 |
46 |
47 | Stylelint v15
48 |
49 | ```sh
50 | npm install stylelint@^15 -D
51 | ```
52 |
53 |
54 |
55 |
56 |
57 | Stylelint v14
58 |
59 | ```sh
60 | npm install stylelint@^14 -D
61 | ```
62 |
63 |
64 |
65 |
66 |
67 | Stylelint v13
68 |
69 | ```sh
70 | npm install stylelint@^13 @types/stylelint@^13 -D
71 | ```
72 |
73 |
74 |
75 | ## 使用
76 |
77 | ```typescript
78 | // vite.config.ts
79 | import { defineConfig } from "vite";
80 | import stylelint from "vite-plugin-stylelint";
81 |
82 | export default defineConfig({
83 | plugins: [stylelint()],
84 | });
85 | ```
86 |
87 | 👇 请查看文档了解具体用法和示例。
88 |
89 | [Cloudflare Pages](https://vite-plugin-stylelint.modyqyw.top/)
90 |
91 | ## 致谢
92 |
93 | 最初从 [gxmari007/vite-plugin-eslint](https://github.com/gxmari007/vite-plugin-eslint) 分叉出来。
94 |
95 | ## 贡献者们
96 |
97 | 该项目由 [ModyQyW](https://github.com/ModyQyW) 创建。
98 |
99 | 感谢 [所有贡献者](https://github.com/ModyQyW/vite-plugin-stylelint/graphs/contributors) 的付出!
100 |
101 | ## 赞助
102 |
103 | 如果这个包对你有所帮助,请考虑 [赞助](https://github.com/ModyQyW/sponsors) 支持,这将有利于项目持续开发和维护。
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/packages/core/build.config.ts:
--------------------------------------------------------------------------------
1 | import { unlinkSync } from "node:fs";
2 | import { resolve } from "node:path";
3 | import { defineBuildConfig } from "unbuild";
4 |
5 | export default defineBuildConfig({
6 | entries: ["src/index", "src/worker"],
7 | clean: true,
8 | declaration: true,
9 | rollup: {
10 | emitCJS: true,
11 | inlineDependencies: true,
12 | esbuild: {
13 | target: "node18",
14 | },
15 | },
16 | hooks: {
17 | "build:done": (ctx) => {
18 | unlinkSync(resolve(ctx.options.outDir, "worker.d.ts"));
19 | },
20 | },
21 | });
22 |
--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vite-plugin-stylelint",
3 | "version": "6.0.0",
4 | "description": "Stylelint plugin for Vite.",
5 | "keywords": [
6 | "stylelint",
7 | "vite-plugin"
8 | ],
9 | "homepage": "https://github.com/ModyQyW/vite-plugin-stylelint",
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/ModyQyW/vite-plugin-stylelint.git",
13 | "directory": "packages/core"
14 | },
15 | "license": "MIT",
16 | "author": {
17 | "name": "ModyQyW",
18 | "email": "wurui.dev@gmail.com",
19 | "url": "https://modyqyw.top"
20 | },
21 | "type": "module",
22 | "exports": {
23 | ".": {
24 | "types": {
25 | "import": "./dist/index.d.mts",
26 | "require": "./dist/index.d.cts"
27 | },
28 | "import": "./dist/index.mjs",
29 | "require": "./dist/index.cjs"
30 | }
31 | },
32 | "main": "./dist/index.cjs",
33 | "module": "./dist/index.mjs",
34 | "types": "./dist/index.d.ts",
35 | "typesVersions": {
36 | "*": {
37 | "*": [
38 | "./dist/*",
39 | "./dist/index.d.ts"
40 | ]
41 | }
42 | },
43 | "files": [
44 | "dist"
45 | ],
46 | "scripts": {
47 | "build": "unbuild",
48 | "prepublishOnly": "pnpm build",
49 | "stub": "unbuild --stub"
50 | },
51 | "dependencies": {
52 | "@rollup/pluginutils": "^5.1.3",
53 | "debug": "^4.3.7"
54 | },
55 | "devDependencies": {
56 | "@types/debug": "^4.1.12",
57 | "picocolors": "^1.1.1",
58 | "postcss": "^8.4.49",
59 | "rollup": "^4.27.4",
60 | "typescript": "^5.7.2",
61 | "vite": "^6.0.0"
62 | },
63 | "peerDependencies": {
64 | "@types/stylelint": "^13.0.0",
65 | "postcss": "^7.0.0 || ^8.0.0",
66 | "rollup": "^2.0.0 || ^3.0.0 || ^4.0.0",
67 | "stylelint": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
68 | "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
69 | },
70 | "peerDependenciesMeta": {
71 | "@types/stylelint": {
72 | "optional": true
73 | },
74 | "postcss": {
75 | "optional": true
76 | },
77 | "rollup": {
78 | "optional": true
79 | }
80 | },
81 | "packageManager": "pnpm@9.14.2",
82 | "engines": {
83 | "node": ">=18"
84 | },
85 | "publishConfig": {
86 | "access": "public",
87 | "registry": "https://registry.npmjs.org/"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/packages/core/src/constants.ts:
--------------------------------------------------------------------------------
1 | import type { Colors } from "picocolors/types";
2 | import type { TextType } from "./types";
3 |
4 | export const STYLELINT_SEVERITY = {
5 | ERROR: "error",
6 | WARNING: "warning",
7 | } as const;
8 |
9 | export const PLUGIN_NAME = "vite:stylelint";
10 |
11 | export const COLOR_MAPPING: Record<
12 | TextType,
13 | keyof Omit
14 | > = {
15 | error: "red",
16 | warning: "yellow",
17 | plugin: "magenta",
18 | };
19 |
--------------------------------------------------------------------------------
/packages/core/src/index.ts:
--------------------------------------------------------------------------------
1 | import { dirname, extname, resolve } from "node:path";
2 | import { fileURLToPath } from "node:url";
3 | import { Worker } from "node:worker_threads";
4 | import debugWrap from "debug";
5 | import type * as Vite from "vite";
6 | import { PLUGIN_NAME } from "./constants";
7 | import type {
8 | StylelintFormatter,
9 | StylelintInstance,
10 | StylelintPluginUserOptions,
11 | } from "./types";
12 | import {
13 | getFilePath,
14 | getFilter,
15 | getOptions,
16 | initializeStylelint,
17 | lintFiles,
18 | shouldIgnoreModule,
19 | } from "./utils";
20 |
21 | const debug = debugWrap(PLUGIN_NAME);
22 | const __filename = fileURLToPath(import.meta.url);
23 | const __dirname = dirname(__filename);
24 | const ext = extname(__filename);
25 |
26 | export default function StylelintPlugin(
27 | userOptions: StylelintPluginUserOptions = {},
28 | ): Vite.Plugin {
29 | const options = getOptions(userOptions);
30 |
31 | let worker: Worker;
32 |
33 | const filter = getFilter(options);
34 | let stylelintInstance: StylelintInstance;
35 | let formatter: StylelintFormatter;
36 |
37 | return {
38 | name: PLUGIN_NAME,
39 | apply(config, { command }) {
40 | debug("==== apply hook ====");
41 | if (config.mode === "test" || process.env.VITEST) return options.test;
42 | const shouldApply =
43 | (command === "serve" && options.dev) ||
44 | (command === "build" && options.build);
45 | debug(`should apply this plugin: ${shouldApply}`);
46 | return shouldApply;
47 | },
48 | async buildStart() {
49 | debug("==== buildStart hook ====");
50 | // initialize worker
51 | if (options.lintInWorker) {
52 | if (worker) return;
53 | debug("Initialize worker");
54 | worker = new Worker(resolve(__dirname, `worker${ext}`), {
55 | workerData: { options },
56 | });
57 | return;
58 | }
59 | // initialize Stylelint
60 | debug("Initial Stylelint");
61 | const result = await initializeStylelint(options);
62 | stylelintInstance = result.stylelintInstance;
63 | formatter = result.formatter;
64 | // lint on start if needed
65 | if (options.lintOnStart) {
66 | debug("Lint on start");
67 | await lintFiles(
68 | {
69 | files: options.include,
70 | stylelintInstance,
71 | formatter,
72 | options,
73 | },
74 | this, // use buildStart hook context
75 | );
76 | }
77 | },
78 | async transform(_, id) {
79 | debug("==== transform hook ====");
80 | debug(`id: ${id}`);
81 | const watchIds = this.getWatchFiles();
82 | debug(`watchIds: ${watchIds}`);
83 | const ids = [id, ...watchIds];
84 | debug(`ids: ${ids}`);
85 | // worker
86 | if (worker) {
87 | for (const id of ids) {
88 | worker.postMessage(id);
89 | }
90 | return;
91 | }
92 | // no worker
93 | // filtered
94 | const filteredIds = ids.filter((id) => !shouldIgnoreModule(id, filter));
95 | debug(`filteredIds: ${filteredIds}`);
96 | const shouldIgnore = filteredIds.length === 0;
97 | debug(`should ignore: ${shouldIgnore}`);
98 | if (shouldIgnore) return;
99 | const filePaths = filteredIds.map((id) => getFilePath(id));
100 | return await lintFiles(
101 | {
102 | files: options.lintDirtyOnly ? filePaths : options.include,
103 | stylelintInstance,
104 | formatter,
105 | options,
106 | },
107 | this, // use transform hook context
108 | );
109 | },
110 | async buildEnd() {
111 | debug("==== buildEnd hook ====");
112 | if (worker) await worker.terminate();
113 | },
114 | };
115 | }
116 |
117 | export type {
118 | StylelintPluginOptions,
119 | StylelintPluginUserOptions,
120 | } from "./types";
121 |
--------------------------------------------------------------------------------
/packages/core/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { CreateFilter } from "@rollup/pluginutils";
2 | import type * as Rollup from "rollup";
3 | import type * as Stylelint from "stylelint";
4 | import type stylelint from "stylelint";
5 |
6 | export type FilterPattern = string | string[];
7 | export type Filter = ReturnType;
8 |
9 | export type StylelintLinterOptions = Partial;
10 | export type StylelintInstance = typeof stylelint;
11 | export type StylelintFormatter = Exclude<
12 | StylelintLinterOptions["formatter"],
13 | string | undefined
14 | >;
15 | export type StylelintFormatterType = Exclude<
16 | StylelintLinterOptions["formatter"],
17 | StylelintFormatter | undefined
18 | >;
19 | export type StylelintLinterResult = Stylelint.LinterResult;
20 |
21 | export interface StylelintPluginOptions extends StylelintLinterOptions {
22 | /**
23 | * Whether to enable the cache. This is disabled in Stylelint by default and enabled in plugin by default to improve speed.
24 | *
25 | * 是否启用缓存。Stylelint 默认禁用,插件默认启用以提高速度。
26 | *
27 | * @default true
28 | */
29 | cache: boolean;
30 |
31 | /**
32 | * Run Stylelint under `test` mode. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) and [Configuring Vitest](https://vitest.dev/guide/#configuring-vitest) for more.
33 | *
34 | * 在 `test` 模式下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 和 [配置 Vitest](https://cn.vitest.dev/guide/) 了解更多。
35 | *
36 | * @default false
37 | */
38 | test: boolean;
39 | /**
40 | * Run Stylelint under `serve` command. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) for more.
41 | *
42 | * 在 `serve` 命令下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 了解更多。
43 | *
44 | * @default true
45 | */
46 | dev: boolean;
47 | /**
48 | * Run Stylelint under `build` command. See [Command Line Interface](https://vitejs.dev/guide/#command-line-interface) for more.
49 | *
50 | * 在 `build` 命令下运行 Stylelint。查看 [命令行界面](https://cn.vitejs.dev/guide/#command-line-interface) 了解更多。
51 | *
52 | * @default false
53 | */
54 | build: boolean;
55 | /**
56 | * This option specifies the files you want to lint. You don't need to change it in most cases, unless the `include` and `exclude` ranges overlap.
57 | *
58 | * If you're using the plugin defaults, the plugin will only call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `transform` hook. The option value will be used to [create a filter](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) to determine if the call should be made and the parameter of the call, which means that the option value needs to fulfill the requirements of [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1).
59 | *
60 | * If you enable the `lintOnStart` option, the plugin will also call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `buildStart` hook. The option value will not be used to create a filter, but will be used directly as the call parameter, which means that the option value also needs to fulfill the [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) requirement.
61 | *
62 | * If you disable the `lintDirtyOnly` option, the plugin will use the option value as the call parameter every time it calls [stylelint.lint](https://stylelint.io/user-guide/node-api/), which means that the option value also needs to fulfill the requirements of [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0).
63 | *
64 | * 这个选项指定你想要校验的文件模式。在绝大部分情况下,你并不需要调整它,除非 `include` 和 `exclude` 范围有重合。
65 | *
66 | * 如果你正在使用插件默认设置,插件只会在 `transform` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值会被用于 [创建一个过滤器](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) 来确定是否该调用以及调用参数。这意味着选项值需要满足 [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1) 的要求。
67 | *
68 | * 如果你启用了 `lintOnStart` 选项,插件还会在 `buildStart` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值不会用于创建过滤器,而是直接用作调用参数。这意味着这个选项值还需要满足 [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) 的要求。
69 | *
70 | * 如果你禁用了 `lintDirtyOnly` 选项,插件每次调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/) 时都会将该选项值作为调用参数。这意味着这个选项值也需要满足 [globby@11.1.0](https://github.com/sindresorhus/globby/tree/v11.1.0) 的要求。
71 | */
72 | include: FilterPattern;
73 | /**
74 | * This option specifies the files you don't want to lint. You don't need to change it in most cases, unless the `include` and `exclude` ranges overlap.
75 | *
76 | * The plugin forces the virtual module to be ignored and you don't need to do any configuration related to it here.
77 | *
78 | * If you're using the plugin defaults, the plugin will only call [stylelint.lint](https://stylelint.io/user-guide/node-api/) in the `transform` hook. The option value will be used to [create a filter](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) to determine if the call should be made and the parameter of the call, which means that the option value needs to fulfill the requirements of [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1).
79 | *
80 | * If you enable the `lintOnStart` option or disable the `lintDirtyOnly` option, the option value will not take effect. You need to change `include` value to include this option value.
81 | *
82 | * 这个选项指定你不想要校验的文件模式。在绝大部分情况下,你并不需要调整它,除非 `include` 和 `exclude` 范围有重合。
83 | *
84 | * 插件强制忽略虚拟模块,你不需要在这里进行任何相关配置。
85 | *
86 | * 如果你正在使用插件默认设置,插件只会在 `transform` 生命周期中调用 [stylelint.lint](https://stylelint.io/user-guide/node-api/)。这个选项值会被用于 [创建一个过滤器](https://github.com/rollup/plugins/blob/master/packages/pluginutils/README.md#createfilter) 来确定是否该调用以及调用参数。这意味着选项值需要满足 [picomatch@2.3.1](https://github.com/micromatch/picomatch/tree/2.3.1) 的要求。
87 | *
88 | * 如果你启用了 `lintOnStart` 选项或者禁用了 `lintDirtyOnly` 选项,这个选项值不会生效。你需要调整 `include` 值以包含该选项值。
89 | */
90 | exclude: FilterPattern;
91 | /**
92 | * Path to Stylelint that will be used for linting. Use [dynamic import](https://javascript.info/modules-dynamic-imports) under the hood. Read [Vite server.fs options](https://vitejs.dev/config/server-options.html#server-fs-strict) first.
93 | *
94 | * Stylelint 路径,用于校验文件。底层使用使用 [dynamic import](https://javascript.info/modules-dynamic-imports)。请先阅读 [Vite server.fs 选项](https://cn.vitejs.dev/config/server-options.html#server-fs-strict)。
95 | *
96 | * @default "stylelint"
97 | */
98 | stylelintPath: string;
99 | /**
100 | * The name, the path or the function implementation of a formatter. This is used to [set a formatter](https://stylelint.io/user-guide/usage/options#formatter) in order to convert lint results to a human- or machine-readable string.
101 | *
102 | * 格式化器的名称、路径或函数实现。用于 [设置格式化器](https://stylelint.io/user-guide/usage/options#formatter),以便将校验结果转换为人类或机器可读的字符串。
103 | *
104 | * @default "string"
105 | */
106 | formatter: StylelintFormatterType | StylelintFormatter;
107 | /**
108 | * Lint in [worker](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-tran). This is disabled by default.
109 | *
110 | * When lint in worker, Vite build process will be faster. You will not see Vite error overlay, Vite build process will not be stopped, even with errors shown in terminal.
111 | *
112 | * It is similar with [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker), but vite-plugin-checker can show you errors and warnings in browsers.
113 | *
114 | * 在 [worker](https://nodejs.org/api/worker_threads.html#portpostmessagevalue-tran) 校验。默认禁用。
115 | *
116 | * 在 worker 中校验时,Vite 的构建过程会更快。即使终端显示了 Stylelint 校验错误,你也不会看到 Vite 错误遮罩层,Vite 构建也不会停止。
117 | *
118 | * 这与 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) 类似,但 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker) 可以在浏览器中显示错误。
119 | *
120 | * @default false
121 | */
122 | lintInWorker: boolean;
123 | /**
124 | * Lint `include` option specified files once in `buildStart` hook to find potential errors. This is disabled by default.
125 | *
126 | * This will significantly slow down Vite first starting if you have no caches and don't enable `lintInWorker`.
127 | *
128 | * 在 `buildStart` 生命周期中校验 `include` 选项指定的文件一次以发现潜在的错误。默认禁用。
129 | *
130 | * 如果你没有缓存而且没有启用 `lintInWorker`,这将大大降低 Vite 的初次启动速度。
131 | *
132 | * @default false
133 | */
134 | lintOnStart: boolean;
135 | /**
136 | * Whether or not to checkout only modified files that are not included in the `exclude` option value when running Stylelint outside of the `buildStart` lifecycle. Enabled by default.
137 | *
138 | * When disabled, files are checked against the `include` and `exclude` option values.
139 | *
140 | * 在 `buildStart` 生命周期之外运行 Stylelint 时,是否只校验修改过且没有包含在 `exclude` 选项值内的文件。默认启用。
141 | *
142 | * 禁用时,会根据 `include` 和 `exclude` 选项值确定需要校验文件。
143 | *
144 | * @default true
145 | */
146 | lintDirtyOnly: boolean;
147 | /**
148 | * Emit found errors. This is enabled by default.
149 | *
150 | * 输出发现的错误。默认启用。
151 | *
152 | * @default true
153 | */
154 | emitError: boolean;
155 | /**
156 | * Emit found errors as warnings. This is disabled by default but you may want it enabled when
157 | * prototyping.
158 | *
159 | * 将发现的错误作为警告输出。默认禁用,但你可能会在开发原型时启用这个。
160 | *
161 | * @default false
162 | */
163 | emitErrorAsWarning: boolean;
164 | /**
165 | * Emit found warnings. This is enabled by default.
166 | *
167 | * 输出发现的警告。默认启用。
168 | *
169 | * @default true
170 | */
171 | emitWarning: boolean;
172 | /**
173 | * Emit found warnings as errors when enabled. This is disabled by default.
174 | *
175 | * 将发现的警告作为错误输出。默认禁用。
176 | *
177 | * @default false
178 | */
179 | emitWarningAsError: boolean;
180 | }
181 | export type StylelintPluginUserOptions = Partial;
182 |
183 | export type LintFiles = (
184 | config: {
185 | files: FilterPattern;
186 | stylelintInstance: StylelintInstance;
187 | formatter: StylelintFormatter;
188 | options: StylelintPluginOptions;
189 | },
190 | context?: Rollup.PluginContext,
191 | ) => Promise;
192 |
193 | export type TextType = "error" | "warning" | "plugin";
194 |
--------------------------------------------------------------------------------
/packages/core/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { createFilter, normalizePath } from "@rollup/pluginutils";
2 | import pico from "picocolors";
3 | import type * as Rollup from "rollup";
4 | import { COLOR_MAPPING, PLUGIN_NAME, STYLELINT_SEVERITY } from "./constants";
5 | import type {
6 | Filter,
7 | LintFiles,
8 | StylelintFormatter,
9 | StylelintInstance,
10 | StylelintLinterOptions,
11 | StylelintLinterResult,
12 | StylelintPluginOptions,
13 | StylelintPluginUserOptions,
14 | TextType,
15 | } from "./types";
16 |
17 | export const getOptions = ({
18 | test,
19 | dev,
20 | build,
21 | cache,
22 | include,
23 | exclude,
24 | stylelintPath,
25 | formatter,
26 | lintInWorker,
27 | lintOnStart,
28 | lintDirtyOnly,
29 | emitError,
30 | emitErrorAsWarning,
31 | emitWarning,
32 | emitWarningAsError,
33 | ...stylelintOptions
34 | }: StylelintPluginUserOptions): StylelintPluginOptions => ({
35 | test: test ?? false,
36 | dev: dev ?? true,
37 | build: build ?? false,
38 | cache: cache ?? true,
39 | include: include ?? ["src/**/*.{css,scss,sass,less,styl,vue,svelte}"],
40 | exclude: exclude ?? ["node_modules", "virtual:"],
41 | stylelintPath: stylelintPath ?? "stylelint",
42 | formatter: formatter ?? "string",
43 | lintInWorker: lintInWorker ?? false,
44 | lintOnStart: lintOnStart ?? false,
45 | lintDirtyOnly: lintDirtyOnly ?? true,
46 | emitError: emitError ?? true,
47 | emitErrorAsWarning: emitErrorAsWarning ?? false,
48 | emitWarning: emitWarning ?? true,
49 | emitWarningAsError: emitWarningAsError ?? false,
50 | ...stylelintOptions,
51 | });
52 |
53 | export const getFilter = (options: StylelintPluginOptions) =>
54 | createFilter(options.include, options.exclude);
55 |
56 | export const initializeStylelint = async (options: StylelintPluginOptions) => {
57 | const { stylelintPath, formatter } = options;
58 | try {
59 | const module = await import(stylelintPath);
60 | const stylelintInstance = (module?.default ?? module) as StylelintInstance;
61 | const loadedFormatter: StylelintFormatter =
62 | typeof formatter === "string"
63 | ? await stylelintInstance.formatters[formatter]
64 | : formatter;
65 | // use as here to avoid typescript error
66 | // src/utils.ts(58,14): error TS2742: The inferred type of 'initializeStylelint' cannot be named without a reference to '.pnpm/postcss@8.4.27/node_modules/postcss'. This is likely not portable. A type annotation is necessary.
67 | return { stylelintInstance, formatter: loadedFormatter } as {
68 | stylelintInstance: StylelintInstance;
69 | formatter: StylelintFormatter;
70 | };
71 | } catch (error) {
72 | throw new Error(
73 | `Failed to initialize Stylelint. Have you installed and configured correctly? ${error}`,
74 | );
75 | }
76 | };
77 |
78 | export const getStylelintLinterOptions = (
79 | options: StylelintPluginOptions,
80 | ): StylelintLinterOptions => ({
81 | ...options,
82 | allowEmptyInput: true,
83 | });
84 |
85 | // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/importMetaGlob.ts
86 | // https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention
87 | export const isVirtualModule = (id: string) =>
88 | id.startsWith("virtual:") || id[0] === "\0" || !id.includes("/");
89 |
90 | export const getFilePath = (id: string) => normalizePath(id).split("?")[0];
91 |
92 | export const shouldIgnoreModule = (id: string, filter: Filter) => {
93 | // virtual module
94 | if (isVirtualModule(id)) return true;
95 | // not included
96 | if (!filter(id)) return true;
97 | // // xxx.vue?type=style or yyy.svelte?type=style style modules
98 | const filePath = getFilePath(id);
99 | if ([".vue", ".svelte"].some((extname) => filePath.endsWith(extname))) {
100 | return !(id.includes("?") && id.includes("type=style"));
101 | }
102 | return false;
103 | };
104 |
105 | export const colorize = (text: string, textType: TextType) =>
106 | pico[COLOR_MAPPING[textType]](text);
107 |
108 | export const log = (
109 | text: string,
110 | textType: TextType,
111 | context?: Rollup.PluginContext,
112 | ) => {
113 | console.log("");
114 | if (context) {
115 | if (textType === "error") context.error(text);
116 | else if (textType === "warning") context.warn(text);
117 | } else {
118 | console.log(`${text} Plugin: ${colorize(PLUGIN_NAME, "plugin")}\r\n`);
119 | }
120 | };
121 |
122 | export const lintFiles: LintFiles = async (
123 | { files, stylelintInstance, formatter, options },
124 | context,
125 | ) =>
126 | await stylelintInstance
127 | .lint({ ...getStylelintLinterOptions(options), files })
128 | .then(async (linterResult: StylelintLinterResult) => {
129 | // do nothing when there are no results
130 | if (!linterResult || linterResult.results.length === 0) return;
131 | let results = linterResult.results.filter((item) => !item.ignored);
132 | if (!options.emitError) {
133 | results = results.map((item) => ({
134 | ...item,
135 | warnings: item.warnings.filter(
136 | (warning) => warning.severity !== STYLELINT_SEVERITY.ERROR,
137 | ),
138 | }));
139 | linterResult.errored = false;
140 | }
141 | if (!options.emitWarning) {
142 | results = results.map((item) => ({
143 | ...item,
144 | warnings: item.warnings.filter(
145 | (warning) => warning.severity !== STYLELINT_SEVERITY.WARNING,
146 | ),
147 | }));
148 | }
149 | results = results.filter((item) => item.warnings.length > 0);
150 | if (results.length === 0) return;
151 |
152 | linterResult.results = results;
153 | const formattedText = formatter(results, linterResult);
154 | const formattedTextType: TextType = linterResult.errored
155 | ? options.emitErrorAsWarning
156 | ? "warning"
157 | : "error"
158 | : options.emitWarningAsError
159 | ? "error"
160 | : "warning";
161 | return log(formattedText, formattedTextType, context);
162 | });
163 |
--------------------------------------------------------------------------------
/packages/core/src/worker.ts:
--------------------------------------------------------------------------------
1 | import { parentPort, workerData } from "node:worker_threads";
2 | import debugWrap from "debug";
3 | import { PLUGIN_NAME } from "./constants";
4 | import type {
5 | StylelintFormatter,
6 | StylelintInstance,
7 | StylelintPluginOptions,
8 | } from "./types";
9 | import {
10 | getFilePath,
11 | getFilter,
12 | initializeStylelint,
13 | lintFiles,
14 | shouldIgnoreModule,
15 | } from "./utils";
16 |
17 | const debug = debugWrap(`${PLUGIN_NAME}:worker`);
18 |
19 | const options = workerData.options as StylelintPluginOptions;
20 | const filter = getFilter(options);
21 | let stylelintInstance: StylelintInstance;
22 | let formatter: StylelintFormatter;
23 |
24 | const initPromise = initializeStylelint(options).then((result) => {
25 | stylelintInstance = result.stylelintInstance;
26 | formatter = result.formatter;
27 | return result;
28 | });
29 |
30 | // this file needs to be compiled into cjs, which doesn't support top-level await
31 | // so we use iife here
32 | (async () => {
33 | debug("==== worker start ====");
34 | debug("Initialize Stylelint");
35 | // remove this line will cause ts2454
36 | const { stylelintInstance, formatter } = await initPromise;
37 | if (options.lintOnStart) {
38 | debug("Lint on start");
39 | lintFiles({
40 | files: options.include,
41 | stylelintInstance,
42 | formatter,
43 | options,
44 | }); // don't use context
45 | }
46 | })();
47 |
48 | parentPort?.on("message", async (id) => {
49 | // make sure stylelintInstance is initialized
50 | if (!stylelintInstance) await initPromise;
51 | debug("==== message event ====");
52 | debug(`id: ${id}`);
53 | const shouldIgnore = shouldIgnoreModule(id, filter);
54 | debug(`should ignore: ${shouldIgnore}`);
55 | if (shouldIgnore) return;
56 | const filePath = getFilePath(id);
57 | debug(`filePath: ${filePath}`);
58 | lintFiles({
59 | files: options.lintDirtyOnly ? filePath : options.include,
60 | stylelintInstance,
61 | formatter,
62 | options,
63 | }); // don't use context
64 | });
65 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - playground
3 | - docs
4 | - packages/*
5 | - examples/*
6 |
--------------------------------------------------------------------------------
/simple-git-hooks.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "pre-commit": "npx lint-staged",
3 | "commit-msg": "npx commitlint --edit ${1}",
4 | };
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
5 | "module": "ESNext",
6 | "moduleResolution": "Bundler",
7 | "target": "ESNext",
8 | "resolveJsonModule": true,
9 | "paths": {
10 | "core": ["./packages/core/src/index.ts"]
11 | },
12 | "strict": true,
13 | "esModuleInterop": true,
14 | "skipLibCheck": true,
15 | "skipDefaultLibCheck": true,
16 | "types": ["node"]
17 | },
18 | "exclude": [
19 | "**/dist/**",
20 | "**/node_modules/**",
21 | "**/client/**",
22 | "**/playground/**",
23 | "**/examples/**",
24 | "**/fixtures/**",
25 | "**/interactive/**",
26 | "**/test/dts/**"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------