├── example
├── umijs
│ ├── mock
│ │ └── .gitkeep
│ ├── src
│ │ ├── global.css
│ │ ├── app.ts
│ │ └── pages
│ │ │ ├── index.css
│ │ │ └── index.tsx
│ ├── .prettierignore
│ ├── README.md
│ ├── .prettierrc
│ ├── typings.d.ts
│ ├── .editorconfig
│ ├── .gitignore
│ ├── .umirc.ts
│ ├── windi.config.ts
│ ├── tsconfig.json
│ └── package.json
├── next
│ ├── pnpm-workspace.yaml
│ ├── .npmrc
│ ├── public
│ │ ├── favicon.ico
│ │ └── vercel.svg
│ ├── styles
│ │ ├── test.css
│ │ ├── main.sass
│ │ ├── main.scss
│ │ ├── plain.css
│ │ └── Home.module.css
│ ├── pages
│ │ ├── api
│ │ │ └── hello.js
│ │ ├── test.jsx
│ │ ├── _app.js
│ │ ├── layout.jsx
│ │ └── index.jsx
│ ├── next.config.js
│ ├── windi.config.ts
│ ├── package.json
│ ├── .gitignore
│ └── README.md
├── nuxt
│ ├── assets
│ │ ├── styles
│ │ │ ├── windi.css
│ │ │ ├── layout.sass
│ │ │ └── global.css
│ │ └── css
│ │ │ ├── test.css
│ │ │ └── main.scss
│ ├── components
│ │ ├── Foo.vue
│ │ ├── StylusScoped.vue
│ │ ├── SassScoped.vue
│ │ ├── CssScoped.vue
│ │ ├── ScssScoped.vue
│ │ ├── PostcssScoped.vue
│ │ ├── LessScoped.vue
│ │ ├── Animation.vue
│ │ └── HelloWorld.vue
│ ├── plugins
│ │ └── windicss.js
│ ├── nuxt.config.js
│ ├── windi.config.ts
│ ├── package.json
│ └── pages
│ │ └── index.vue
├── icejs
│ ├── src
│ │ ├── global.css
│ │ ├── app.tsx
│ │ ├── routes.ts
│ │ ├── typings.d.ts
│ │ └── pages
│ │ │ └── Home
│ │ │ └── index.tsx
│ ├── .stylelintignore
│ ├── .prettierrc.js
│ ├── .prettierignore
│ ├── .stylelintrc.js
│ ├── .eslintignore
│ ├── build.json
│ ├── .editorconfig
│ ├── .eslintrc.js
│ ├── public
│ │ ├── index.html
│ │ └── favicon.png
│ ├── .gitignore
│ ├── windi.config.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── craco
│ ├── public
│ │ ├── robots.txt
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── index.html
│ ├── windi.config.ts
│ ├── src
│ │ ├── setupTests.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── reportWebVitals.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── App.js
│ │ └── logo.svg
│ ├── .gitignore
│ ├── craco.config.js
│ ├── package.json
│ └── README.md
├── vue2
│ ├── babel.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── assets
│ │ │ ├── logo.png
│ │ │ └── test.css
│ │ ├── main.js
│ │ ├── components
│ │ │ ├── StylusScoped.vue
│ │ │ ├── SassScoped.vue
│ │ │ ├── CssScoped.vue
│ │ │ ├── ScssScoped.vue
│ │ │ ├── PostcssScoped.vue
│ │ │ └── LessScoped.vue
│ │ └── App.vue
│ ├── .gitignore
│ ├── README.md
│ ├── vue.config.js
│ ├── windi.config.ts
│ └── package.json
├── vue3
│ ├── babel.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── assets
│ │ │ ├── logo.png
│ │ │ └── test.css
│ │ ├── main.js
│ │ ├── components
│ │ │ ├── StylusScoped.vue
│ │ │ ├── SassScoped.vue
│ │ │ ├── CssScoped.vue
│ │ │ ├── ScssScoped.vue
│ │ │ ├── PostcssScoped.vue
│ │ │ ├── LessScoped.vue
│ │ │ └── HelloWorld.vue
│ │ └── App.vue
│ ├── vue.config.js
│ ├── .gitignore
│ ├── README.md
│ ├── windi.config.ts
│ └── package.json
├── vue-cli-next
│ ├── babel.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── assets
│ │ │ ├── logo.png
│ │ │ └── test.css
│ │ ├── components
│ │ │ ├── Foo.vue
│ │ │ ├── SassScoped.vue
│ │ │ ├── StylusScoped.vue
│ │ │ ├── CssScoped.vue
│ │ │ ├── ScssScoped.vue
│ │ │ ├── PostcssScoped.vue
│ │ │ └── LessScoped.vue
│ │ ├── main.js
│ │ └── App.vue
│ ├── vue.config.js
│ ├── .gitignore
│ ├── README.md
│ ├── windi.config.ts
│ └── package.json
└── vue3-storybook
│ ├── babel.config.js
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── src
│ ├── assets
│ │ ├── logo.png
│ │ └── test.css
│ ├── main.js
│ ├── components
│ │ ├── StylusScoped.vue
│ │ ├── SassScoped.vue
│ │ ├── CssScoped.vue
│ │ ├── ScssScoped.vue
│ │ ├── LessScoped.vue
│ │ ├── PostcssScoped.vue
│ │ ├── CssLang.stories.js
│ │ └── HelloWorld.vue
│ ├── stories
│ │ ├── header.css
│ │ ├── button.css
│ │ ├── Header.stories.js
│ │ ├── Page.stories.js
│ │ ├── Button.stories.js
│ │ ├── assets
│ │ │ ├── direction.svg
│ │ │ ├── flow.svg
│ │ │ ├── code-brackets.svg
│ │ │ ├── comments.svg
│ │ │ ├── repo.svg
│ │ │ ├── plugin.svg
│ │ │ └── stackalt.svg
│ │ ├── Button.vue
│ │ ├── page.css
│ │ ├── Header.vue
│ │ ├── Page.vue
│ │ └── Introduction.stories.mdx
│ └── App.vue
│ ├── vue.config.js
│ ├── .storybook
│ ├── preview.js
│ └── main.js
│ ├── .gitignore
│ ├── README.md
│ ├── windi.config.ts
│ └── package.json
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── test.yml
│ └── release.yml
├── test
├── fixtures
│ ├── import-css-with-apply
│ │ ├── styles
│ │ │ ├── windi.css
│ │ │ └── global.css
│ │ ├── index.js
│ │ ├── templates
│ │ │ └── App.vue
│ │ └── windi.config.ts
│ ├── react-layers
│ │ ├── index.js
│ │ ├── windi.config.ts
│ │ └── templates
│ │ │ └── layout-layer.jsx
│ ├── react
│ │ ├── index.js
│ │ ├── windi.config.ts
│ │ └── templates
│ │ │ ├── layout2.jsx
│ │ │ └── layout.jsx
│ ├── vue
│ │ ├── stylesheets
│ │ │ ├── main.sass
│ │ │ ├── main.scss
│ │ │ ├── main.less
│ │ │ └── plain.css
│ │ ├── index.js
│ │ ├── windi.config.ts
│ │ └── templates
│ │ │ └── App.vue
│ ├── vue-layers
│ │ ├── stylesheets
│ │ │ ├── main.sass
│ │ │ ├── main.scss
│ │ │ ├── main.less
│ │ │ └── plain.css
│ │ ├── windi.config.ts
│ │ ├── index.js
│ │ └── templates
│ │ │ └── App.vue
│ ├── vue-directives
│ │ ├── stylesheets
│ │ │ └── plain.css
│ │ ├── index.js
│ │ ├── windi.config.ts
│ │ └── templates
│ │ │ └── App.vue
│ └── excluded-transform
│ │ ├── windi.config.ts
│ │ ├── index.js
│ │ ├── node_modules_demo
│ │ ├── my-package
│ │ │ └── should-transform.css
│ │ └── some-other-package
│ │ │ └── should-not-transform.css
│ │ └── templates
│ │ └── App.vue
├── helpers
│ ├── index.ts
│ ├── getModuleSource.ts
│ ├── reactWebpackCompiler.ts
│ └── vueWebpackCompiler.ts
├── directives.test.ts
├── import-from-css-apply.test.ts
├── excluded-transform.test.ts
├── layers.test.ts
├── regex.test.ts
└── tranform-template.test.ts
├── .eslintignore
├── src
├── core
│ ├── dev-tools-update.ts
│ ├── debug.ts
│ ├── constants.ts
│ ├── utils.ts
│ └── server.ts
├── loaders
│ ├── windicss-css.ts
│ ├── dev-tools.ts
│ ├── windicss-style-pitcher.ts
│ ├── windicss-template.ts
│ └── virtual-module.ts
├── types.ts
└── runtime
│ └── client.ts
├── .eslintrc.json
├── .editorconfig
├── .gitignore
├── vitest.config.ts
├── tsconfig.json
├── package.json
└── README.md
/example/umijs/mock/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/umijs/src/global.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/next/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [harlan-zw]
2 |
--------------------------------------------------------------------------------
/example/nuxt/assets/styles/windi.css:
--------------------------------------------------------------------------------
1 | @import './global.css';
2 |
--------------------------------------------------------------------------------
/example/umijs/src/app.ts:
--------------------------------------------------------------------------------
1 | import 'windi.css';
2 | import 'windi-devtools'
3 |
--------------------------------------------------------------------------------
/example/next/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-workspace-root-check=true
2 | shamefully-hoist=true
3 |
--------------------------------------------------------------------------------
/test/fixtures/import-css-with-apply/styles/windi.css:
--------------------------------------------------------------------------------
1 | @import './global.css';
2 |
--------------------------------------------------------------------------------
/test/fixtures/react-layers/index.js:
--------------------------------------------------------------------------------
1 | require ('./templates/layout-layer.jsx')
2 |
--------------------------------------------------------------------------------
/example/icejs/src/global.css:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
--------------------------------------------------------------------------------
/example/nuxt/assets/styles/layout.sass:
--------------------------------------------------------------------------------
1 | #__layout
2 | background-color: #F6F6CE
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | *.snap
4 | test
5 | coverage
6 | example
7 | __snapshots__
8 |
--------------------------------------------------------------------------------
/test/fixtures/react/index.js:
--------------------------------------------------------------------------------
1 | require ('./templates/layout.jsx')
2 | require ('./templates/layout2.jsx')
3 |
--------------------------------------------------------------------------------
/example/craco/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/example/icejs/.stylelintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | build/
3 | tests/
4 | demo/
5 |
6 | # node 覆盖率文件
7 | coverage/
8 |
--------------------------------------------------------------------------------
/example/umijs/src/pages/index.css:
--------------------------------------------------------------------------------
1 |
2 | .title {
3 | @apply bg-purple-500 text-5xl p-5 text-white;
4 | }
5 |
--------------------------------------------------------------------------------
/example/vue2/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/example/vue3/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/example/craco/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/craco/public/favicon.ico
--------------------------------------------------------------------------------
/example/craco/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/craco/public/logo192.png
--------------------------------------------------------------------------------
/example/craco/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/craco/public/logo512.png
--------------------------------------------------------------------------------
/example/next/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/next/public/favicon.ico
--------------------------------------------------------------------------------
/example/vue-cli-next/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/example/vue2/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue2/public/favicon.ico
--------------------------------------------------------------------------------
/example/vue2/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue2/src/assets/logo.png
--------------------------------------------------------------------------------
/example/vue3-storybook/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ],
5 | }
6 |
--------------------------------------------------------------------------------
/example/vue3/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue3/public/favicon.ico
--------------------------------------------------------------------------------
/example/vue3/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue3/src/assets/logo.png
--------------------------------------------------------------------------------
/src/core/dev-tools-update.ts:
--------------------------------------------------------------------------------
1 | // This file is used to trigger the regeneration of the css for devtools, as it can be an empty file
2 |
--------------------------------------------------------------------------------
/example/icejs/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const { getPrettierConfig } = require('@iceworks/spec');
2 |
3 | module.exports = getPrettierConfig('react');
4 |
--------------------------------------------------------------------------------
/example/umijs/.prettierignore:
--------------------------------------------------------------------------------
1 | **/*.md
2 | **/*.svg
3 | **/*.ejs
4 | **/*.html
5 | package.json
6 | .umi
7 | .umi-production
8 | .umi-test
9 |
--------------------------------------------------------------------------------
/test/helpers/index.ts:
--------------------------------------------------------------------------------
1 | export * from './getModuleSource'
2 | export * from './vueWebpackCompiler'
3 | export * from './reactWebpackCompiler'
4 |
--------------------------------------------------------------------------------
/example/icejs/.prettierignore:
--------------------------------------------------------------------------------
1 | build/
2 | tests/
3 | demo/
4 | .ice/
5 | coverage/
6 | **/*-min.js
7 | **/*.min.js
8 | package-lock.json
9 | yarn.lock
--------------------------------------------------------------------------------
/example/icejs/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | const { getStylelintConfig } = require('@iceworks/spec');;
2 |
3 | module.exports = getStylelintConfig('react');
4 |
--------------------------------------------------------------------------------
/example/nuxt/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Yellow via unsupported sass
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/vue-cli-next/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue-cli-next/public/favicon.ico
--------------------------------------------------------------------------------
/example/vue-cli-next/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue-cli-next/src/assets/logo.png
--------------------------------------------------------------------------------
/test/fixtures/import-css-with-apply/index.js:
--------------------------------------------------------------------------------
1 | require ('./templates/App.vue')
2 | require ('./styles/windi.css')
3 |
4 | require('windi.css')
5 |
--------------------------------------------------------------------------------
/example/vue3-storybook/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue3-storybook/public/favicon.ico
--------------------------------------------------------------------------------
/example/vue3-storybook/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/windicss/windicss-webpack-plugin/HEAD/example/vue3-storybook/src/assets/logo.png
--------------------------------------------------------------------------------
/example/vue3/src/main.js:
--------------------------------------------------------------------------------
1 | import {createApp} from 'vue'
2 | import App from './App.vue'
3 | import 'windi.css'
4 |
5 | createApp(App).mount('#app')
6 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Should be Yellow
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/main.js:
--------------------------------------------------------------------------------
1 | import {createApp} from 'vue'
2 | import App from './App.vue'
3 | import 'windi.css'
4 |
5 | createApp(App).mount('#app')
6 |
--------------------------------------------------------------------------------
/example/icejs/.eslintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | build/
3 | tests/
4 | demo/
5 | .ice/
6 |
7 | # node 覆盖率文件
8 | coverage/
9 |
10 | # 忽略文件
11 | **/*-min.js
12 | **/*.min.js
13 |
--------------------------------------------------------------------------------
/example/next/styles/test.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | @apply fixed top-0 left-0 right-0 bg-white shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply p-10 bg-blue-200;
8 | }
9 |
--------------------------------------------------------------------------------
/example/nuxt/assets/css/test.css:
--------------------------------------------------------------------------------
1 | nav {
2 | @apply fixed top-0 left-0 right-0 bg-white shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply pt-10 bg-blue-250;
8 | }
9 |
--------------------------------------------------------------------------------
/example/nuxt/plugins/windicss.js:
--------------------------------------------------------------------------------
1 | import 'virtual:windi-base.css'
2 | import 'virtual:windi-components.css'
3 | import 'virtual:windi-utilities.css'
4 | import 'virtual:windi-devtools'
5 |
--------------------------------------------------------------------------------
/example/next/styles/main.sass:
--------------------------------------------------------------------------------
1 | .sass-global
2 | @apply "bg-orange-400 text-white p-4 w-1/4 transition hover:(bg-orange-900 text-orange-100)"
3 | h2
4 | @apply "font-bold text-sm"
5 |
--------------------------------------------------------------------------------
/example/vue2/src/assets/test.css:
--------------------------------------------------------------------------------
1 | nav {
2 | @apply fixed top-0 left-0 right-0 bg-red-200 shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply pt-10 bg-blue-250;
8 | }
9 |
--------------------------------------------------------------------------------
/example/vue3/src/assets/test.css:
--------------------------------------------------------------------------------
1 | nav {
2 | @apply fixed top-0 left-0 right-0 bg-red-200 shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply pt-10 bg-blue-250;
8 | }
9 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/assets/test.css:
--------------------------------------------------------------------------------
1 | nav {
2 | @apply fixed top-0 left-0 right-0 bg-red-200 shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply pt-10 bg-blue-250;
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixtures/vue/stylesheets/main.sass:
--------------------------------------------------------------------------------
1 | .sass-global
2 | @apply bg-orange-400 text-white p-4 w-1/4 transition hover:(bg-orange-900 text-orange-100)
3 | h2
4 | @apply font-bold text-sm
5 |
--------------------------------------------------------------------------------
/example/next/styles/main.scss:
--------------------------------------------------------------------------------
1 | .scss-global {
2 | @apply bg-blue-400 text-white p-4 w-1/4 transition hover:(bg-blue-900 text-blue-100);
3 | h2 {
4 | @apply font-bold text-sm;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | new Vue({
7 | render: h => h(App),
8 | }).$mount('#app')
9 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/assets/test.css:
--------------------------------------------------------------------------------
1 | nav {
2 | @apply fixed top-0 left-0 right-0 bg-red-200 shadow shadow-2xl;
3 | padding: 10px;
4 | }
5 |
6 | html {
7 | @apply pt-10 bg-blue-250;
8 | }
9 |
--------------------------------------------------------------------------------
/src/core/debug.ts:
--------------------------------------------------------------------------------
1 | import _debug from 'debug'
2 | import { NAME } from './constants'
3 |
4 | export default {
5 | plugin: _debug(`${NAME}:plugin`),
6 | loader: _debug(`${NAME}:loader`),
7 | }
8 |
--------------------------------------------------------------------------------
/test/fixtures/vue-layers/stylesheets/main.sass:
--------------------------------------------------------------------------------
1 | .sass-global
2 | @apply bg-orange-400 text-white p-4 w-1/4 transition hover:(bg-orange-900 text-orange-100)
3 | h2
4 | @apply font-bold text-sm
5 |
--------------------------------------------------------------------------------
/example/icejs/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "webpackPlugins": {
3 | "windicss-webpack-plugin": {}
4 | },
5 | "eslint": {
6 | "exclude": ["**/node_modules/**", "**/virtual:windi-devtools*"]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/example/nuxt/assets/css/main.scss:
--------------------------------------------------------------------------------
1 | .scss-global {
2 | @apply bg-green-400 text-white p-4 w-1/4 transition hover:(bg-green-900 text-blue-100);
3 | h2 {
4 | @apply font-bold text-sm;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/next/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default (request, res) => {
4 | res.status(200).json({name: 'John Doe'})
5 | }
6 |
--------------------------------------------------------------------------------
/example/next/styles/plain.css:
--------------------------------------------------------------------------------
1 | .css-global {
2 | @apply bg-yellow-400 text-white p-4 w-1/4 transition hover:(bg-yellow-900 text-yellow-100);
3 | }
4 | .css-global h2 {
5 | @apply font-bold text-sm;
6 | }
7 |
--------------------------------------------------------------------------------
/test/fixtures/vue/stylesheets/main.scss:
--------------------------------------------------------------------------------
1 | .scss-global {
2 | @apply bg-blue-400 text-white p-4 w-1/4 transition hover:(bg-blue-900 text-blue-100);
3 | h2 {
4 | @apply font-bold text-sm;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/fixtures/vue-layers/stylesheets/main.scss:
--------------------------------------------------------------------------------
1 | .scss-global {
2 | @apply bg-blue-400 text-white p-4 w-1/4 transition hover:(bg-blue-900 text-blue-100);
3 | h2 {
4 | @apply font-bold text-sm;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/fixtures/vue/stylesheets/main.less:
--------------------------------------------------------------------------------
1 | .less-global {
2 | @apply " bg-purple-400 text-white p-4 w-1/4 transition hover:(bg-purple-900 text-purple-100)";
3 | h2 {
4 | @apply font-bold text-sm;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true
4 | },
5 | "extends": "@antfu",
6 | "rules": {
7 | "@typescript-eslint/no-var-requires": "off",
8 | "no-cond-assign": "off"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/fixtures/vue/stylesheets/plain.css:
--------------------------------------------------------------------------------
1 | .global-css {
2 | @apply bg-yellow-400 text-white p-4 w-1/4 transition hover:(bg-yellow-900 text-yellow-100);
3 | }
4 | .global-css h2 {
5 | @apply font-bold text-sm;
6 | }
7 |
--------------------------------------------------------------------------------
/example/next/pages/test.jsx:
--------------------------------------------------------------------------------
1 | export default function Test() {
2 | return (
3 |
,
7 | ): React.ReactElement;
8 | const url: string;
9 | export default url;
10 | }
11 |
--------------------------------------------------------------------------------
/example/icejs/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const { getESLintConfig } = require('@iceworks/spec');
2 |
3 | // https://www.npmjs.com/package/@iceworks/spec
4 | module.exports = getESLintConfig('react-ts', {
5 | rules: {
6 | 'react/jsx-filename-extension': 0,
7 | '@typescript-eslint/explicit-function-return-type': 0,
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/example/next/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/test.css'
2 | import '../styles/plain.css'
3 | import '../styles/main.sass'
4 | import '../styles/main.scss'
5 | import 'windi.css'
6 | import 'windi-devtools'
7 |
8 | function MyApp({Component, pageProps}) {
9 | return
10 | }
11 |
12 | export default MyApp
13 |
--------------------------------------------------------------------------------
/example/umijs/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
17 |
--------------------------------------------------------------------------------
/test/fixtures/excluded-transform/index.js:
--------------------------------------------------------------------------------
1 | require ('./templates/App.vue')
2 | require ('./node_modules_demo/my-package/should-transform.css')
3 | require ('./node_modules_demo/some-other-package/should-not-transform.css')
4 |
5 | require('virtual:windi-base.css')
6 | require('virtual:windi-components.css')
7 | require('virtual:windi-utilities.css')
8 |
--------------------------------------------------------------------------------
/example/nuxt/components/StylusScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Stylus scoped
4 | red-400 -> red-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue2/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/example/vue3/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/test/fixtures/vue-layers/index.js:
--------------------------------------------------------------------------------
1 | require ('./templates/App.vue')
2 | require ('./stylesheets/main.less')
3 | require ('./stylesheets/main.scss')
4 | require ('./stylesheets/main.sass')
5 | require ('./stylesheets/plain.css')
6 |
7 | require('virtual:windi-base.css')
8 | require('virtual:windi-components.css')
9 | require('virtual:windi-utilities.css')
10 |
--------------------------------------------------------------------------------
/example/nuxt/components/SassScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SASS scoped
4 | orange-400 -> orange-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue-cli-next/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/example/vue2/src/components/StylusScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Stylus scoped
4 | red-400 -> red-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue3/src/components/StylusScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Stylus scoped
4 | red-400 -> red-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue2/src/components/SassScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SASS scoped
4 | orange-400 -> orange-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue3-storybook/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/example/vue3/src/components/SassScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SASS scoped
4 | orange-400 -> orange-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/nuxt/components/CssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
CSS scoped
4 | yellow-400 -> yellow-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/SassScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SASS scoped
4 | orange-400 -> orange-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/StylusScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Stylus scoped
4 | red-400 -> red-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/StylusScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Stylus scoped
4 | red-400 -> red-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/nuxt/components/ScssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SCSS scoped hmr
4 | blue-400 -> blue-500
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue2/src/components/CssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
CSS scoped
4 | yellow-400 -> yellow-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue2/src/components/ScssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SCSS scoped
4 | blue-400 -> blue-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/SassScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SASS scoped
4 | orange-400 -> orange-900
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/example/vue3/src/components/CssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
CSS scoped
4 | yellow-400 -> yellow-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3/src/components/ScssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SCSS scoped
4 | blue-400 -> blue-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/icejs/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | icejs simple app
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/nuxt/components/PostcssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
PostCSS scoped
4 | pink-400 -> pink-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/CssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
CSS scoped
4 | yellow-400 -> yellow-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/nuxt/components/LessScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
LESS scoped
4 | purple-400 -> purple-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/ScssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SCSS scoped
4 | blue-400 -> blue-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue2/src/components/PostcssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
PostCSS scoped
4 | pink-400 -> pink-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/CssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
CSS scoped
4 | yellow-400 -> yellow-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/ScssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
SCSS scoped
4 | blue-400 -> blue-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3/src/components/PostcssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
PostCSS scoped
4 | pink-400 -> pink-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/umijs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /npm-debug.log*
6 | /yarn-error.log
7 | /yarn.lock
8 | /package-lock.json
9 |
10 | # production
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 |
16 | # umi
17 | /src/.umi
18 | /src/.umi-production
19 | /src/.umi-test
20 | /.env.local
21 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/PostcssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
PostCSS scoped
4 | pink-400 -> pink-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue2/src/components/LessScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
LESS scoped
4 | purple-400 -> purple-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/LessScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
LESS scoped
4 | purple-400 -> purple-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3/src/components/LessScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
LESS scoped
4 | purple-400 -> purple-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/components/LessScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
LESS scoped
4 | purple-400 -> purple-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/PostcssScoped.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
PostCSS scoped
4 | pink-400 -> pink-900
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/example/icejs/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.module.scss' {
2 | const classes: { [key: string]: string };
3 | export default classes;
4 | }
5 |
6 | declare module '*.module.less' {
7 | const classes: { [key: string]: string };
8 | export default classes;
9 | }
10 |
11 | declare module '*.module.css' {
12 | const classes: { [key: string]: string };
13 | export default classes;
14 | }
15 |
--------------------------------------------------------------------------------
/example/icejs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules/
5 |
6 | # production
7 | build/
8 | dist/
9 | tmp/
10 | lib/
11 |
12 | # misc
13 | .idea/
14 | .happypack
15 | .DS_Store
16 | *.swp
17 | *.dia~
18 | .ice
19 | .vscode
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | index.module.scss.d.ts
25 |
--------------------------------------------------------------------------------
/example/next/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['**/*.{jsx,css}'],
6 | exclude: ['node_modules', '.git', '.next/**/*'],
7 | },
8 | attributify: true,
9 | shortcuts: {
10 | btn: 'rounded-lg border border-gray-300 text-gray-100 bg-blue-500 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | })
13 |
--------------------------------------------------------------------------------
/example/craco/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/example/vue3-storybook/.storybook/main.js:
--------------------------------------------------------------------------------
1 | const WindiCSS = require('../../..')
2 |
3 | module.exports = {
4 | "stories": [
5 | "../src/**/*.stories.mdx",
6 | "../src/**/*.stories.@(js|jsx|ts|tsx)"
7 | ],
8 | "addons": [
9 | "@storybook/addon-links",
10 | "@storybook/addon-essentials"
11 | ],
12 | webpackFinal: (config) => {
13 | config.plugins.push(new WindiCSS());
14 | return config;
15 | },
16 | }
17 |
--------------------------------------------------------------------------------
/example/vue3/README.md:
--------------------------------------------------------------------------------
1 | # vue3
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/example/vue2/README.md:
--------------------------------------------------------------------------------
1 | # vue-cli
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/example/craco/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/example/vue-cli-next/README.md:
--------------------------------------------------------------------------------
1 | # vue-cli
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/example/vue2/vue.config.js:
--------------------------------------------------------------------------------
1 | const WindiCSSWebpackPlugin = require('windicss-webpack-plugin')
2 |
3 | module.exports = {
4 |
5 | pluginOptions: {
6 | i18n: {
7 | locale: 'en',
8 | fallbackLocale: 'en',
9 | localeDir: 'locales',
10 | enableInSFC: true,
11 | enableBridge: false
12 | }
13 | },
14 | configureWebpack: {
15 | plugins: [
16 | new WindiCSSWebpackPlugin,
17 | ],
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/example/vue3-storybook/README.md:
--------------------------------------------------------------------------------
1 | # vue3
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | yarn lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/example/craco/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X
2 | .DS_Store
3 |
4 | .idea
5 |
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 |
11 | # Dependency directories
12 | node_modules/
13 |
14 | # Optional npm cache directory
15 | .npm
16 |
17 | # Optional REPL history
18 | .node_repl_history
19 |
20 | # Output of 'npm pack'
21 | *.tgz
22 |
23 | # Jest coverage data
24 | coverage
25 |
26 | # Distribution files
27 | dist
28 |
29 | .nuxt
30 | .next
31 | .env
32 |
33 | .umi
34 |
--------------------------------------------------------------------------------
/example/icejs/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers';
2 |
3 | export default defineConfig({
4 | preflight: false,
5 | extract: {
6 | include: ['**/*.{html,jsx,tsx}'],
7 | exclude: ['.git', '.ice', 'node_modules', 'build'],
8 | },
9 | attributify: true,
10 | shortcuts: {
11 | btn: 'rounded-lg border border-gray-300 text-gray-100 bg-blue-500 px-4 py-2 m-2 inline-block hover:shadow cursor-pointer',
12 | },
13 | });
14 |
--------------------------------------------------------------------------------
/example/nuxt/nuxt.config.js:
--------------------------------------------------------------------------------
1 | import WindiCSSWebpackPlugin from 'windicss-webpack-plugin'
2 |
3 | module.exports = {
4 | css: [
5 | '@/assets/css/test.css',
6 | '@/assets/css/main.scss',
7 | '@/assets/styles/windi.css',
8 | '@/assets/styles/layout.sass',
9 | ],
10 | plugins: [
11 | '@/plugins/windicss.js',
12 | ],
13 | components: true,
14 | build: {
15 | plugins: [
16 | new WindiCSSWebpackPlugin,
17 | ],
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/test/helpers/getModuleSource.ts:
--------------------------------------------------------------------------------
1 | export function getModuleSource (id, stats) {
2 | const { modules } = stats.toJson({ source: true });
3 | const module = modules.find((m) => m.name.indexOf(id) > -1);
4 |
5 | if (!module) {
6 | throw new Error('Failed to find module ' + id)
7 | }
8 |
9 | let { source } = module;
10 |
11 | // Todo remove after drop webpack@4 support
12 | source = source.replace(/\?\?.*!/g, "??[ident]!");
13 |
14 | return source;
15 | };
16 |
--------------------------------------------------------------------------------
/example/next/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "@zeit/next-less": "^1.0.1",
12 | "less": "^4.1.1",
13 | "next": "12.1.6",
14 | "react": "18.1.0",
15 | "react-dom": "18.1.0",
16 | "sass": "^1.35.1",
17 | "windicss-webpack-plugin": "link:../../"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { resolve } from 'path'
3 | import { defineConfig, AliasOptions } from 'vite'
4 |
5 | const r = (p: string) => resolve(__dirname, p)
6 |
7 | export const alias: AliasOptions = {
8 | 'windicss-webpack-plugin': r('./src/'),
9 | }
10 |
11 | export default defineConfig({
12 | test: {
13 | testTimeout: 1200000,
14 | include: ['test/**.test.ts']
15 | },
16 | resolve: {
17 | alias,
18 | },
19 | })
20 |
--------------------------------------------------------------------------------
/src/loaders/windicss-css.ts:
--------------------------------------------------------------------------------
1 | import type { loader } from 'webpack'
2 | import { transformCSS } from '../core/utils'
3 |
4 | function WindicssCss(
5 | this: loader.LoaderContext,
6 | source: string,
7 | ): string {
8 | if (!this._compiler)
9 | return source
10 |
11 | this.cacheable(true)
12 | // @ts-expect-error untyped
13 | const service = this._compiler.$windi
14 |
15 | if (!service)
16 | return source
17 |
18 | return transformCSS(service, source, this.resource)
19 | }
20 |
21 | export default WindicssCss
22 |
--------------------------------------------------------------------------------
/example/next/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/example/umijs/.umirc.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'umi';
2 | import WindiCSSWebpackPlugin from 'windicss-webpack-plugin'
3 |
4 | export default defineConfig({
5 | nodeModulesTransform: {
6 | type: 'none',
7 | },
8 | routes: [
9 | { path: '/', component: '@/pages/index' },
10 | ],
11 | // must be disabled
12 | // see: https://github.com/umijs/umi/issues/7303
13 | mfsu: false,
14 | fastRefresh: {},
15 | chainWebpack(config : any) {
16 | config
17 | .plugin('windicss')
18 | .use(WindiCSSWebpackPlugin);
19 | },
20 | });
21 |
--------------------------------------------------------------------------------
/example/vue2/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['src/**/*.{vue,css}', 'public/**/*.html']
6 | },
7 | attributify: true,
8 | darkMode: 'class',
9 | shortcuts: {
10 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | theme: {
13 | extend: {
14 | colors: {
15 | teal: {
16 | 100: '#453',
17 | 900: '#216b6b',
18 | },
19 | },
20 | },
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/example/vue3/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['src/**/*.{vue,css}', 'public/**/*.html']
6 | },
7 | attributify: true,
8 | darkMode: 'class',
9 | shortcuts: {
10 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | theme: {
13 | extend: {
14 | colors: {
15 | teal: {
16 | 100: '#453',
17 | 900: '#216b6b',
18 | },
19 | },
20 | },
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/test/fixtures/excluded-transform/node_modules_demo/my-package/should-transform.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --header-height: theme('spacing.14');
3 | --docs-scroll-margin-block: calc(var(--header-height) + 4rem);
4 | --blogpost-scroll-margin-block: calc(var(--header-height));
5 | }
6 |
7 | @screen md {
8 | :root {
9 | --header-height: theme('spacing.18');
10 | --blogpost-scroll-margin-block: calc(var(--header-height) - 0.5rem);
11 | }
12 | }
13 |
14 | @screen xl {
15 | :root {
16 | --docs-scroll-margin-block: calc(var(--header-height) + 1rem);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/umijs/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | exclude: ['node_modules', '.git', 'dist', 'mock', '.umi'],
6 | },
7 | attributify: true,
8 | darkMode: 'class',
9 | shortcuts: {
10 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | theme: {
13 | extend: {
14 | colors: {
15 | teal: {
16 | 100: '#453',
17 | 900: '#216b6b',
18 | },
19 | },
20 | },
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/example/vue-cli-next/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['src/**/*.{vue,css}', 'public/**/*.html']
6 | },
7 | attributify: true,
8 | darkMode: 'class',
9 | shortcuts: {
10 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | theme: {
13 | extend: {
14 | colors: {
15 | teal: {
16 | 100: '#453',
17 | 900: '#216b6b',
18 | },
19 | },
20 | },
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/example/vue3-storybook/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['src/**/*.{vue,css}', 'public/**/*.html']
6 | },
7 | attributify: true,
8 | darkMode: 'class',
9 | shortcuts: {
10 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
11 | },
12 | theme: {
13 | extend: {
14 | colors: {
15 | teal: {
16 | 100: '#453',
17 | 900: '#216b6b',
18 | },
19 | },
20 | },
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/example/craco/craco.config.js:
--------------------------------------------------------------------------------
1 | const WindiCSSWebpackPlugin = require('../../')
2 |
3 | module.exports = {
4 | eslint: {
5 | pluginOptions: config => {
6 | config.exclude = ['**/node_modules/**', '**/virtual:windi-devtools*']
7 | return config;
8 | },
9 | },
10 | webpack: {
11 | plugins: {
12 | add: [
13 | new WindiCSSWebpackPlugin({
14 | virtualModulePath: 'src',
15 | server: {
16 | port: 9999,
17 | host: 'localhost'
18 | }
19 | })
20 | ],
21 | },
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/fixtures/excluded-transform/node_modules_demo/some-other-package/should-not-transform.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --header-height: theme('spacing.14');
3 | --docs-scroll-margin-block: calc(var(--header-height) + 4rem);
4 | --blogpost-scroll-margin-block: calc(var(--header-height));
5 | }
6 |
7 | @screen md {
8 | :root {
9 | --header-height: theme('spacing.18');
10 | --blogpost-scroll-margin-block: calc(var(--header-height) - 0.5rem);
11 | }
12 | }
13 |
14 | @screen xl {
15 | :root {
16 | --docs-scroll-margin-block: calc(var(--header-height) + 1rem);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/nuxt/windi.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'windicss/helpers'
2 |
3 | export default defineConfig({
4 | extract: {
5 | include: ['**/*.{vue,js,ts}'],
6 | exclude: ['node_modules', '.git', 'dist', 'mock', '.umi'],
7 | },
8 | attributify: true,
9 | darkMode: 'class',
10 | shortcuts: {
11 | btn: 'rounded border border-gray-300 text-gray-600 px-4 py-2 m-2 inline-block hover:shadow',
12 | },
13 | theme: {
14 | extend: {
15 | colors: {
16 | teal: {
17 | 100: '#453',
18 | 900: '#216b6b',
19 | },
20 | },
21 | },
22 | },
23 | })
24 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/header.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | border-bottom: 1px solid rgba(0, 0, 0, 0.1);
4 | padding: 15px 20px;
5 | display: flex;
6 | align-items: center;
7 | justify-content: space-between;
8 | }
9 |
10 | svg {
11 | display: inline-block;
12 | vertical-align: top;
13 | }
14 |
15 | h1 {
16 | font-weight: 900;
17 | font-size: 20px;
18 | line-height: 1;
19 | margin: 6px 0 6px 10px;
20 | display: inline-block;
21 | vertical-align: top;
22 | }
23 |
24 | button + button {
25 | margin-left: 10px;
26 | }
27 |
--------------------------------------------------------------------------------
/example/craco/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Clone repository '...'
16 | 2. Run '....'
17 | 3. See error
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **Additional context**
26 | Add any other context about the problem here.
27 |
--------------------------------------------------------------------------------
/example/umijs/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styles from './index.css';
3 |
4 | export default function Page() {
5 | return (
6 |
7 |
WindiCSS Umi example
8 |
9 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi culpa dicta in laboriosam molestiae nesciunt pariatur perferendis perspiciatis placeat, porro quaerat qui quis rem similique sint veniam veritatis. Accusamus, sequi?
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/test/directives.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 | import { getModuleSource, vueWebpackCompiler } from './helpers'
3 |
4 | describe("Directives test", function() {
5 |
6 | it('should render vue', done => {
7 | const compiler = vueWebpackCompiler('vue-directives')
8 | compiler.run((err, stats) => {
9 | expect(stats.compilation.errors).toStrictEqual([])
10 | const windiComponents = getModuleSource('virtual:windi-components.css', stats)
11 | expect(windiComponents).toContain('.bar')
12 | expect(windiComponents).toMatchSnapshot('windi components')
13 |
14 | done(err)
15 | });
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/example/craco/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 | import './virtual:windi.css'
7 | import './virtual:windi-devtools'
8 |
9 | ReactDOM.render(
10 |
11 |
12 | ,
13 | document.getElementById('root')
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/CssLang.stories.js:
--------------------------------------------------------------------------------
1 | import CssScoped from './CssScoped.vue';
2 |
3 | export default {
4 | title: 'Example/CSS Variants',
5 | };
6 |
7 | export const ScopedCSS = () => ({
8 | components: { CssScoped },
9 | template: ' ',
10 | });
11 |
12 | export const ScopedPostCSS = () => ({
13 | template: '\n' +
20 | ' Attributify Mode\n' +
21 | ' ',
22 | });
23 |
--------------------------------------------------------------------------------
/test/import-from-css-apply.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 | import { getModuleSource, vueWebpackCompiler } from './helpers'
3 |
4 | describe("@import css with @apply", function() {
5 |
6 | it('should render vue', done => {
7 | const compiler = vueWebpackCompiler('import-css-with-apply', )
8 | compiler.run((err, stats) => {
9 | expect(stats.compilation.errors).toStrictEqual([])
10 |
11 | const toNotTransformCss = getModuleSource('global.css', stats)
12 | expect(toNotTransformCss).not.toContain('@apply')
13 | expect(toNotTransformCss).toMatchSnapshot('@apply')
14 |
15 | done(err)
16 | });
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/example/vue3/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/nuxt/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nuxt",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "nuxt": "^2.15.8",
8 | "pug": "^3.0.2",
9 | "pug-loader": "^2.4.0",
10 | "sass": "^1.32.12",
11 | "sass-loader": "^10"
12 | },
13 | "scripts": {
14 | "dev": "nuxt",
15 | "analysis": "windicss-analysis"
16 | },
17 | "devDependencies": {
18 | "fibers": "^5.0.0",
19 | "less": "^4.1.1",
20 | "less-loader": "^7",
21 | "pug-plain-loader": "^1.1.0",
22 | "stylus": "^0.54.8",
23 | "stylus-loader": "^3",
24 | "windicss-analysis": "^0.0.17",
25 | "windicss-webpack-plugin": "file:../../"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/example/vue-cli-next/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/vue3-storybook/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: feature request
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/example/vue2/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/next/pages/layout.jsx:
--------------------------------------------------------------------------------
1 | export default function Layout({ title, children }) {
2 | return (
3 |
4 | {children}
5 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "lib": [
6 | "ES2019",
7 | "dom"
8 | ],
9 | "module": "commonjs",
10 | "target": "ES2019",
11 | "strict": true,
12 | "esModuleInterop": true,
13 | "skipLibCheck": true,
14 | "moduleResolution": "node",
15 | "resolveJsonModule": true,
16 | "noUnusedLocals": true,
17 | "strictNullChecks": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "paths": {
20 | "windicss-webpack-plugin": ["./src/plugin.ts"]
21 | }
22 | },
23 | "include": [
24 | "src"
25 | ],
26 | "exclude": [
27 | "example/**",
28 | "**/dist/**",
29 | "**/node_modules/**"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/example/craco/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/example/craco/src/App.js:
--------------------------------------------------------------------------------
1 | import logo from './logo.svg';
2 | import './App.css';
3 |
4 | function App() {
5 | return (
6 |
22 | );
23 | }
24 |
25 | export default App;
26 |
--------------------------------------------------------------------------------
/example/umijs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "importHelpers": true,
7 | "jsx": "react-jsx",
8 | "esModuleInterop": true,
9 | "sourceMap": true,
10 | "baseUrl": "./",
11 | "strict": true,
12 | "paths": {
13 | "@/*": ["src/*"],
14 | "@@/*": ["src/.umi/*"]
15 | },
16 | "allowSyntheticDefaultImports": true
17 | },
18 | "include": [
19 | "mock/**/*",
20 | "src/**/*",
21 | "config/**/*",
22 | ".umirc.ts",
23 | "typings.d.ts"
24 | ],
25 | "exclude": [
26 | "node_modules",
27 | "lib",
28 | "es",
29 | "dist",
30 | "typings",
31 | "**/__test__",
32 | "test",
33 | "docs",
34 | "tests"
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/button.css:
--------------------------------------------------------------------------------
1 | .storybook-button {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | font-weight: 700;
4 | border: 0;
5 | border-radius: 3em;
6 | cursor: pointer;
7 | display: inline-block;
8 | line-height: 1;
9 | }
10 | .storybook-button--primary {
11 | color: white;
12 | background-color: #1ea7fd;
13 | }
14 | .storybook-button--secondary {
15 | color: #333;
16 | background-color: transparent;
17 | box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
18 | }
19 | .storybook-button--small {
20 | font-size: 12px;
21 | padding: 10px 16px;
22 | }
23 | .storybook-button--medium {
24 | font-size: 14px;
25 | padding: 11px 20px;
26 | }
27 | .storybook-button--large {
28 | font-size: 16px;
29 | padding: 12px 24px;
30 | }
31 |
--------------------------------------------------------------------------------
/test/fixtures/react/templates/layout2.jsx:
--------------------------------------------------------------------------------
1 | import 'virtual:windi.css'
2 |
3 | export default function Layout({ title, children }) {
4 | return (
5 |
6 |
7 |
{title}
8 |
9 | {children}
10 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/test/fixtures/react/templates/layout.jsx:
--------------------------------------------------------------------------------
1 | import 'virtual:windi.css'
2 |
3 | export default function Layout({ title, children }) {
4 | return (
5 |
6 |
7 |
{title}
8 |
9 | {children}
10 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/Header.stories.js:
--------------------------------------------------------------------------------
1 | import MyHeader from './Header.vue';
2 |
3 | export default {
4 | title: 'Example/Header',
5 | component: MyHeader,
6 | };
7 |
8 | const Template = (args) => ({
9 | // Components used in your story `template` are defined in the `components` object
10 | components: { MyHeader },
11 | // The story's `args` need to be mapped into the template through the `setup()` method
12 | setup() {
13 | // Story args can be spread into the returned object
14 | return { ...args };
15 | },
16 | // Then, the spread values can be accessed directly in the template
17 | template: ' ',
18 | });
19 |
20 | export const LoggedIn = Template.bind({});
21 | LoggedIn.args = {
22 | user: {},
23 | };
24 |
25 | export const LoggedOut = Template.bind({});
26 | LoggedOut.args = {
27 | user: null,
28 | };
29 |
--------------------------------------------------------------------------------
/test/fixtures/react-layers/templates/layout-layer.jsx:
--------------------------------------------------------------------------------
1 | import 'virtual:windi-base.css'
2 | import 'virtual:windi-components.css'
3 | import 'virtual:windi-utilities.css'
4 |
5 | export default function Layout({ title, children }) {
6 | return (
7 |
8 |
9 |
{title}
10 |
11 | {children}
12 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/Page.stories.js:
--------------------------------------------------------------------------------
1 | import MyPage from './Page.vue';
2 | import * as HeaderStories from './Header.stories';
3 |
4 | export default {
5 | title: 'Example/Page',
6 | component: MyPage,
7 | };
8 |
9 | const Template = (args) => ({
10 | // Components used in your story `template` are defined in the `components` object
11 | components: { MyPage },
12 | // The story's `args` need to be mapped into the template through the `setup()` method
13 | setup() {
14 | // Story args can be mapped to keys in the returned object
15 | return { user: args.user };
16 | },
17 | // Then, those values can be accessed directly in the template
18 | template: ' ',
19 | });
20 |
21 | export const LoggedIn = Template.bind({});
22 | LoggedIn.args = {
23 | ...HeaderStories.LoggedIn.args,
24 | };
25 |
26 | export const LoggedOut = Template.bind({});
27 | LoggedOut.args = {
28 | ...HeaderStories.LoggedOut.args,
29 | };
30 |
--------------------------------------------------------------------------------
/src/core/constants.ts:
--------------------------------------------------------------------------------
1 | export const NAME = 'windicss-webpack-plugin'
2 | export const MODULE_ID = 'windi.css'
3 | export const MODULE_ID_VIRTUAL_TEST = /virtual:windi-?(.*?)\.css/
4 | export const MODULE_ID_VIRTUAL_PREFIX = 'virtual:windi'
5 | export const MODULE_ID_VIRTUAL_MODULES = [
6 | `${MODULE_ID_VIRTUAL_PREFIX}.css`,
7 | `${MODULE_ID_VIRTUAL_PREFIX}-base.css`,
8 | `${MODULE_ID_VIRTUAL_PREFIX}-utilities.css`,
9 | `${MODULE_ID_VIRTUAL_PREFIX}-components.css`,
10 | ]
11 |
12 | export const HAS_DIRECTIVE_TEST = /@(apply|variants|screen|layer)\s/
13 | export const HAS_THEME_FUNCTION_TEST = /theme\(.*?\)/
14 | export const DEVTOOLS_MODULE_ID = 'windi-devtools'
15 | export const DEVTOOLS_VIRTUAL_MODULE_ID = 'virtual:windi-devtools'
16 | export const DEVTOOLS_VIRTUAL_MODULE = 'virtual:windi-devtools.js'
17 | export const DEVTOOLS_POST_PATH = '/@windicss-devtools-update'
18 | export const DEFAULT_SERVER_HOST = '127.0.0.1'
19 | export const DEFAULT_SERVER_PORT = 8888
20 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | pull_request:
9 | branches:
10 | - main
11 |
12 | jobs:
13 | build:
14 | runs-on: ${{ matrix.os }}
15 |
16 | strategy:
17 | matrix:
18 | node-version: [16.x]
19 | # os: [ubuntu-latest, windows-latest, macos-latest]
20 | os: [ubuntu-latest]
21 | fail-fast: false
22 |
23 | steps:
24 | - uses: actions/checkout@v2
25 |
26 | - name: Install pnpm
27 | uses: pnpm/action-setup@v2.2.1
28 |
29 | - name: Use Node.js ${{ matrix.node-version }}
30 | uses: actions/setup-node@v2
31 | with:
32 | node-version: ${{ matrix.node-version }}
33 | registry-url: https://registry.npmjs.org/
34 | cache: "pnpm"
35 |
36 | - run: pnpm install
37 |
38 | - name: Build
39 | run: pnpm run build
40 |
41 | - name: Test
42 | run: pnpm run test
43 |
--------------------------------------------------------------------------------
/example/icejs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "buildOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "outDir": "build",
7 | "module": "esnext",
8 | "target": "es6",
9 | "jsx": "react-jsx",
10 | "moduleResolution": "node",
11 | "allowSyntheticDefaultImports": true,
12 | "lib": ["es6", "dom"],
13 | "sourceMap": true,
14 | "allowJs": true,
15 | "rootDir": "./",
16 | "forceConsistentCasingInFileNames": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noImplicitAny": false,
20 | "importHelpers": true,
21 | "strictNullChecks": true,
22 | "suppressImplicitAnyIndexErrors": true,
23 | "noUnusedLocals": true,
24 | "skipLibCheck": true,
25 | "types": ["node"],
26 | "paths": {
27 | "@/*": ["./src/*"],
28 | "ice": [".ice/index.ts"]
29 | }
30 | },
31 | "include": ["src", ".ice"],
32 | "exclude": ["node_modules", "build", "public"]
33 | }
--------------------------------------------------------------------------------
/example/nuxt/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi CSS 4
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
19 | @import from a css file
20 |
21 |
28 | Attributify Button
29 |
30 |
31 |
SCSS global
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/example/icejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@alifd/scaffold-simple",
3 | "version": "0.1.0",
4 | "description": "使用 TypeScript,未使用任何 UI 库。",
5 | "dependencies": {
6 | "react": "^17.0.2",
7 | "react-dom": "^17.0.2"
8 | },
9 | "devDependencies": {
10 | "@iceworks/spec": "^1.0.0",
11 | "@types/react": "^17.0.2",
12 | "@types/react-dom": "^17.0.2",
13 | "eslint": "^7.30.0",
14 | "ice.js": "^2.0.0",
15 | "stylelint": "^13.7.2",
16 | "windicss-webpack-plugin": "file:../../"
17 | },
18 | "scripts": {
19 | "start": "icejs start",
20 | "build": "icejs build",
21 | "lint": "npm run eslint && npm run stylelint",
22 | "eslint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./",
23 | "eslint:fix": "npm run eslint -- --fix",
24 | "stylelint": "stylelint \"**/*.{css,scss,less}\""
25 | },
26 | "repository": {
27 | "type": "git",
28 | "url": "https://github.com/ice-lab/react-materials/tree/master/scaffolds/simple"
29 | },
30 | "private": true,
31 | "originTemplate": "@alifd/scaffold-simple"
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | with:
14 | fetch-depth: 0
15 |
16 | - name: Install pnpm
17 | uses: pnpm/action-setup@v2.2.1
18 |
19 | - name: Use Node.js v16
20 | uses: actions/setup-node@v2
21 | with:
22 | node-version: v16
23 | registry-url: https://registry.npmjs.org/
24 | cache: "pnpm"
25 |
26 | - run: npx conventional-github-releaser -p angular
27 | continue-on-error: true
28 | env:
29 | CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{secrets.GITHUB_TOKEN}}
30 |
31 | - name: Install Dependencies
32 | run: pnpm install
33 |
34 | - name: PNPM build
35 | run: pnpm run build
36 |
37 | - name: Publish to NPM
38 | run: pnpm -r publish --access public --no-git-checks
39 | env:
40 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
41 |
--------------------------------------------------------------------------------
/example/nuxt/components/Animation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
class="pulse-class-2"
6 |
7 |
8 |
9 |
class="pulse-class" (defined with @apply)
10 |
11 |
12 |
15 |
16 | class="relative w-40 h-40 rounded-full bg-teal-600 opacity-80
17 | animate-pulse"
18 |
19 |
20 |
21 |
22 |
23 |
33 |
--------------------------------------------------------------------------------
/example/craco/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-react-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@craco/craco": "^6.2.0",
7 | "@testing-library/jest-dom": "^5.11.4",
8 | "@testing-library/react": "^11.1.0",
9 | "@testing-library/user-event": "^12.1.10",
10 | "babel-loader": "8.1.0",
11 | "react": "^17.0.2",
12 | "react-dom": "^17.0.2",
13 | "react-scripts": "^4.0.3",
14 | "web-vitals": "^1.0.1",
15 | "windicss-webpack-plugin": "file:../../"
16 | },
17 | "scripts": {
18 | "start": "craco start",
19 | "build": "craco build",
20 | "test": "craco test",
21 | "eject": "craco eject"
22 | },
23 | "eslintConfig": {
24 | "extends": [
25 | "react-app",
26 | "react-app/jest"
27 | ]
28 | },
29 | "browserslist": {
30 | "production": [
31 | ">0.2%",
32 | "not dead",
33 | "not op_mini all"
34 | ],
35 | "development": [
36 | "last 1 chrome version",
37 | "last 1 firefox version",
38 | "last 1 safari version"
39 | ]
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/excluded-transform.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 | import { getModuleSource, vueWebpackCompiler } from './helpers'
3 |
4 | describe("Excluded transform", function() {
5 |
6 | it('should render vue', done => {
7 | const compiler = vueWebpackCompiler('excluded-transform', {
8 | scan: {
9 | extraTransformTargets: {
10 | detect: [],
11 | css: [
12 | (resource) => {
13 | return resource.indexOf('should-transform.css') >= 0
14 | }
15 |
16 | ]
17 | }
18 | }
19 | })
20 | compiler.run((err, stats) => {
21 | expect(stats.compilation.errors).toStrictEqual([])
22 |
23 | const toNotTransformCss = getModuleSource('should-not-transform', stats)
24 | expect(toNotTransformCss).toContain('theme(')
25 |
26 | // check the windi file has generated the right classes
27 | const toTransformCss = getModuleSource('should-transform', stats)
28 | expect(toTransformCss).not.toContain('theme(')
29 |
30 | done(err)
31 | });
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/example/next/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/example/umijs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "start": "umi dev",
5 | "build": "umi build",
6 | "postinstall": "umi generate tmp",
7 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
8 | "test": "umi-test",
9 | "test:coverage": "umi-test --coverage"
10 | },
11 | "gitHooks": {
12 | "pre-commit": "lint-staged"
13 | },
14 | "lint-staged": {
15 | "*.{js,jsx,less,md,json}": [
16 | "prettier --write"
17 | ],
18 | "*.ts?(x)": [
19 | "prettier --parser=typescript --write"
20 | ]
21 | },
22 | "dependencies": {
23 | "@ant-design/pro-layout": "^6.5.0",
24 | "@umijs/preset-react": "^1.8.6",
25 | "umi": "^3.4.14"
26 | },
27 | "devDependencies": {
28 | "@types/react": "^17.0.0",
29 | "@types/react-dom": "^17.0.0",
30 | "@umijs/test": "^3.4.14",
31 | "windicss-webpack-plugin": "file:../../",
32 | "lint-staged": "^10.0.7",
33 | "prettier": "^2.2.0",
34 | "react": "17.x",
35 | "react-dom": "17.x",
36 | "typescript": "^4.1.2",
37 | "yorkie": "^2.0.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/example/icejs/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Simple
3 |
4 | > A TypeScript simple template
5 |
6 | ## 使用
7 |
8 | ```bash
9 | # 安装依赖
10 | $ npm install
11 |
12 | # 启动服务
13 | $ npm start # visit http://localhost:3333
14 | ```
15 |
16 | [More docs](https://ice.work/docs/guide/about).
17 |
18 | ## 目录
19 |
20 | ```md
21 | ├── build/ # 构建产物
22 | ├── mock/ # 本地模拟数据
23 | │ ├── index.[j,t]s
24 | ├── public/
25 | │ ├── index.html # 应用入口 HTML
26 | │ └── favicon.png # Favicon
27 | ├── src/ # 源码路径
28 | │ ├── components/ # 自定义业务组件
29 | │ │ └── Guide/
30 | │ │ ├── index.[j,t]sx
31 | │ │ └── index.module.scss
32 | │ ├── pages/ # 页面
33 | │ │ └── index.tsx/
34 | │ ├── global.scss # 全局样式
35 | │ └── app.[j,t]s[x] # 应用入口脚本
36 | ├── README.md
37 | ├── package.json
38 | ├── .editorconfig
39 | ├── .eslintignore
40 | ├── .eslintrc.[j,t]s
41 | ├── .gitignore
42 | ├── .stylelintignore
43 | ├── .stylelintrc.[j,t]s
44 | ├── .gitignore
45 | └── [j,t]sconfig.json
46 | ```
47 |
--------------------------------------------------------------------------------
/test/helpers/reactWebpackCompiler.ts:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import webpack from 'webpack'
3 | import WebpackWindiCSSPlugin from '../../dist/plugin.mjs'
4 |
5 | export function reactWebpackCompiler (type = 'react', config = {}) {
6 | const root = path.dirname(__dirname)
7 | const context = path.join(root, 'fixtures', type)
8 | return webpack({
9 | entry: `./index.js`,
10 | context,
11 | mode: 'development',
12 | devtool: false,
13 | output: {
14 | path: path.join(root, '/dist'),
15 | },
16 | module: {
17 | rules: [
18 | {
19 | test: /\.css$/,
20 | use: [
21 | 'css-loader'
22 | ]
23 | },
24 | {
25 | test: /\.jsx?$/,
26 | exclude: /node_modules/,
27 | use: {
28 | loader: 'babel-loader',
29 | options: {
30 | presets: [
31 | ['@babel/preset-react']
32 | ]
33 | }
34 | }
35 | },
36 | ]
37 | },
38 | plugins: [
39 | new WebpackWindiCSSPlugin({
40 | root: context,
41 | ...config,
42 | }),
43 | ],
44 | });
45 | }
46 |
--------------------------------------------------------------------------------
/example/vue-cli-next/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Windi test CSS
6 |
7 |
11 | Hello World
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
46 |
--------------------------------------------------------------------------------
/example/vue-cli-next/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-cli",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "vue": "^2.6.11"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "5.0.0-alpha.8",
16 | "@vue/cli-service": "5.0.0-alpha.8",
17 | "babel-eslint": "^10.1.0",
18 | "eslint-plugin-vue": "^6.2.2",
19 | "less": "^4.1.1",
20 | "less-loader": "^8.1.1",
21 | "sass": "^1.32.12",
22 | "sass-loader": "^11.0.1",
23 | "stylus": "^0.54.8",
24 | "stylus-loader": "^5.0.0",
25 | "vue-template-compiler": "^2.6.11",
26 | "windicss-webpack-plugin": "file:../../"
27 | },
28 | "eslintConfig": {
29 | "root": true,
30 | "env": {
31 | "node": true
32 | },
33 | "extends": [
34 | "plugin:vue/essential",
35 | "eslint:recommended"
36 | ],
37 | "parserOptions": {
38 | "parser": "babel-eslint"
39 | },
40 | "rules": {}
41 | },
42 | "browserslist": [
43 | "> 1%",
44 | "last 2 versions",
45 | "not dead"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/Button.stories.js:
--------------------------------------------------------------------------------
1 | import MyButton from './Button.vue';
2 |
3 | export default {
4 | title: 'Example/Button',
5 | component: MyButton,
6 | argTypes: {
7 | backgroundColor: { control: 'color' },
8 | size: { control: { type: 'select', options: ['small', 'medium', 'large'] } },
9 | onClick: {},
10 | },
11 | };
12 |
13 | const Template = (args) => ({
14 | // Components used in your story `template` are defined in the `components` object
15 | components: { MyButton },
16 | // The story's `args` need to be mapped into the template through the `setup()` method
17 | setup() {
18 | return { args };
19 | },
20 | // And then the `args` are bound to your component with `v-bind="args"`
21 | template: ' ',
22 | });
23 |
24 | export const Primary = Template.bind({});
25 | Primary.args = {
26 | primary: true,
27 | label: 'Button',
28 | };
29 |
30 | export const Secondary = Template.bind({});
31 | Secondary.args = {
32 | label: 'Button',
33 | };
34 |
35 | export const Large = Template.bind({});
36 | Large.args = {
37 | size: 'large',
38 | label: 'Button',
39 | };
40 |
41 | export const Small = Template.bind({});
42 | Small.args = {
43 | size: 'small',
44 | label: 'Button',
45 | };
46 |
--------------------------------------------------------------------------------
/example/vue3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "vue": "^3.0.0"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "~4.5.0",
16 | "@vue/cli-plugin-eslint": "~4.5.0",
17 | "@vue/cli-service": "~4.5.0",
18 | "@vue/compiler-sfc": "^3.0.0",
19 | "babel-eslint": "^10.1.0",
20 | "eslint": "^6.7.2",
21 | "eslint-plugin-vue": "^7.0.0-0",
22 | "less": "^4.1.1",
23 | "less-loader": "^7",
24 | "sass": "^1.32.12",
25 | "sass-loader": "^10",
26 | "stylus": "^0.54.8",
27 | "stylus-loader": "^3",
28 | "windicss-webpack-plugin": "file:../../"
29 | },
30 | "eslintConfig": {
31 | "root": true,
32 | "env": {
33 | "node": true
34 | },
35 | "extends": [
36 | "plugin:vue/vue3-essential",
37 | "eslint:recommended"
38 | ],
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | },
42 | "rules": {}
43 | },
44 | "browserslist": [
45 | "> 1%",
46 | "last 2 versions",
47 | "not dead"
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/direction.svg:
--------------------------------------------------------------------------------
1 | illustration/direction
--------------------------------------------------------------------------------
/test/fixtures/vue-layers/templates/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
19 |
20 | Without ! (red)
21 |
22 |
23 | With ! (blue)
24 |
25 |
26 |
Less global
27 |
28 |
29 |
SCSS global
30 |
31 |
32 |
SASS global
33 |
34 |
35 |
CSS global
36 |
37 |
44 | Button
45 |
46 |
47 |
48 |
49 |
54 |
--------------------------------------------------------------------------------
/test/fixtures/excluded-transform/templates/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
19 |
20 | Without ! (red)
21 |
22 |
23 | With ! (blue)
24 |
25 |
26 |
Less global
27 |
28 |
29 |
SCSS global
30 |
31 |
32 |
SASS global
33 |
34 |
35 |
CSS global
36 |
37 |
44 | Button
45 |
46 |
47 |
48 |
49 |
54 |
--------------------------------------------------------------------------------
/test/fixtures/vue-directives/templates/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
19 |
20 | Without ! (red)
21 |
22 |
23 | With ! (blue)
24 |
25 |
26 |
Less global
27 |
28 |
29 |
SCSS global
30 |
31 |
32 |
SASS global
33 |
34 |
35 |
CSS global
36 |
37 |
44 | Button
45 |
46 |
47 |
48 |
49 |
54 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/Button.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ label }}
3 |
4 |
5 |
53 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/page.css:
--------------------------------------------------------------------------------
1 | section {
2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | font-size: 14px;
4 | line-height: 24px;
5 | padding: 48px 20px;
6 | margin: 0 auto;
7 | max-width: 600px;
8 | color: #333;
9 | }
10 |
11 | h2 {
12 | font-weight: 900;
13 | font-size: 32px;
14 | line-height: 1;
15 | margin: 0 0 4px;
16 | display: inline-block;
17 | vertical-align: top;
18 | }
19 |
20 | p {
21 | margin: 1em 0;
22 | }
23 |
24 | a {
25 | text-decoration: none;
26 | color: #1ea7fd;
27 | }
28 |
29 | ul {
30 | padding-left: 30px;
31 | margin: 1em 0;
32 | }
33 |
34 | li {
35 | margin-bottom: 8px;
36 | }
37 |
38 | .tip {
39 | display: inline-block;
40 | border-radius: 1em;
41 | font-size: 11px;
42 | line-height: 12px;
43 | font-weight: 700;
44 | background: #e7fdd8;
45 | color: #66bf3c;
46 | padding: 4px 12px;
47 | margin-right: 10px;
48 | vertical-align: top;
49 | }
50 |
51 | .tip-wrapper {
52 | font-size: 13px;
53 | line-height: 20px;
54 | margin-top: 40px;
55 | margin-bottom: 40px;
56 | }
57 |
58 | .tip-wrapper svg {
59 | display: inline-block;
60 | height: 12px;
61 | width: 12px;
62 | margin-right: 4px;
63 | vertical-align: top;
64 | margin-top: 3px;
65 | }
66 |
67 | .tip-wrapper svg path {
68 | fill: #1ea7fd;
69 | }
70 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/flow.svg:
--------------------------------------------------------------------------------
1 | illustration/flow
--------------------------------------------------------------------------------
/example/vue2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-cli",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\""
10 | },
11 | "dependencies": {
12 | "core-js": "^3.19.3",
13 | "video.js": "^7.17.0",
14 | "vue": "^2.6.14",
15 | "vue-i18n": "^8.26.3"
16 | },
17 | "devDependencies": {
18 | "@intlify/vue-i18n-loader": "^4.0.1",
19 | "@vue/cli-plugin-babel": "~4.5.15",
20 | "@vue/cli-plugin-eslint": "~4.5.15",
21 | "@vue/cli-service": "~4.5.15",
22 | "babel-eslint": "^10.1.0",
23 | "eslint": "^6.7.2",
24 | "eslint-plugin-vue": "^6.2.2",
25 | "less": "^4.1.2",
26 | "less-loader": "^7.3.0",
27 | "sass": "^1.32.12",
28 | "sass-loader": "^10",
29 | "stylus": "^0.54.8",
30 | "stylus-loader": "^3",
31 | "vue-cli-plugin-i18n": "~2.3.1"
32 | },
33 | "eslintConfig": {
34 | "root": true,
35 | "env": {
36 | "node": true
37 | },
38 | "extends": [
39 | "plugin:vue/essential",
40 | "eslint:recommended"
41 | ],
42 | "parserOptions": {
43 | "parser": "babel-eslint"
44 | },
45 | "rules": {}
46 | },
47 | "browserslist": [
48 | "> 1%",
49 | "last 2 versions",
50 | "not dead"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/code-brackets.svg:
--------------------------------------------------------------------------------
1 | illustration/code-brackets
--------------------------------------------------------------------------------
/test/fixtures/vue/templates/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 | {{ $t('hello') }}
6 |
7 |
11 | Hello World
12 |
13 |
14 | Button
15 |
16 |
17 | Bar
18 |
19 |
20 |
21 | Without ! (red)
22 |
23 |
24 | With ! (blue)
25 |
26 |
27 |
Less global
28 |
29 |
30 |
SCSS global
31 |
32 |
33 |
SASS global
34 |
35 |
36 |
CSS global
37 |
38 |
45 | Button
46 |
47 |
48 |
49 |
50 |
51 |
52 | {
53 | "en": {
54 | "hello": "hello world!"
55 | },
56 | "ja": {
57 | "hello": "こんにちは、世界!"
58 | }
59 | }
60 |
61 |
62 |
67 |
--------------------------------------------------------------------------------
/example/icejs/src/pages/Home/index.tsx:
--------------------------------------------------------------------------------
1 | const Home = () => {
2 | return (
3 |
4 |
Welcome to icejs!
5 |
6 | This is an awesome project powered by
7 |
8 | WindiCSS
9 |
10 | , enjoy it!
11 |
12 |
27 |
28 |
{
31 | location.href = 'https://ice.work/docs/guide/about';
32 | }}
33 | >
34 | Get Started with icejs
35 |
36 |
{
39 | location.href = 'https://windicss.org';
40 | }}
41 | >
42 | Get Started with WindiCSS
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default Home;
50 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/comments.svg:
--------------------------------------------------------------------------------
1 | illustration/comments
--------------------------------------------------------------------------------
/example/vue2/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "en": {
4 | "hello": "hello world!"
5 | },
6 | "ja": {
7 | "hello": "JAPAN こんにちは、世界!"
8 | }
9 | }
10 |
11 |
12 |
13 |
14 |
15 |
16 | Windi test CSS
17 |
18 |
19 |
23 |
{{ $t('hello') }}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
64 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
15 |
19 |
20 |
21 |
Acme
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
50 |
--------------------------------------------------------------------------------
/example/vue3-storybook/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "storybook": "start-storybook -p 6006",
10 | "build-storybook": "build-storybook"
11 | },
12 | "dependencies": {
13 | "core-js": "^3.6.5",
14 | "vue": "^3.0.0"
15 | },
16 | "devDependencies": {
17 | "@babel/core": "^7.14.6",
18 | "@storybook/addon-actions": "^6.3.0",
19 | "@storybook/addon-essentials": "^6.3.0",
20 | "@storybook/addon-links": "^6.3.0",
21 | "@storybook/vue3": "^6.3.0",
22 | "@vue/cli-plugin-babel": "~4.5.0",
23 | "@vue/cli-plugin-eslint": "~4.5.0",
24 | "@vue/cli-service": "~4.5.0",
25 | "@vue/compiler-sfc": "^3.0.0",
26 | "babel-eslint": "^10.1.0",
27 | "babel-loader": "^8.2.2",
28 | "eslint": "^6.7.2",
29 | "eslint-plugin-vue": "^7.0.0-0",
30 | "less": "^4.1.1",
31 | "less-loader": "^7",
32 | "sass": "^1.32.12",
33 | "sass-loader": "^10",
34 | "stylus": "^0.54.8",
35 | "stylus-loader": "^3",
36 | "vue-loader": "^16.2.0"
37 | },
38 | "eslintConfig": {
39 | "root": true,
40 | "env": {
41 | "node": true
42 | },
43 | "extends": [
44 | "plugin:vue/vue3-essential",
45 | "eslint:recommended"
46 | ],
47 | "parserOptions": {
48 | "parser": "babel-eslint"
49 | },
50 | "rules": {}
51 | },
52 | "browserslist": [
53 | "> 1%",
54 | "last 2 versions",
55 | "not dead"
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/repo.svg:
--------------------------------------------------------------------------------
1 | illustration/repo
--------------------------------------------------------------------------------
/example/vue3-storybook/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
25 | Attributify Mode
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
57 |
58 |
69 |
--------------------------------------------------------------------------------
/example/vue3/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Windi test CSS
5 |
6 |
10 | Hello World
11 |
12 |
13 | Button
14 |
15 |
16 | Bar
17 |
18 |
25 | Attributify Mode
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
57 |
58 |
69 |
--------------------------------------------------------------------------------
/example/next/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/src/loaders/dev-tools.ts:
--------------------------------------------------------------------------------
1 | import { readFileSync } from 'node:fs'
2 | import { resolve } from 'pathe'
3 | import type { Compiler, loader } from 'webpack'
4 | import { isDev, isWebCompilerTarget } from '../core/utils'
5 | import { DEVTOOLS_POST_PATH } from '../core/constants'
6 |
7 | const DEVTOOLS_CLIENT_PATH = resolve(__dirname, '../runtime/client.cjs')
8 |
9 | function getMockClassesInjector(compiler: Compiler) {
10 | const completions = compiler.$windi.getCompletions()
11 | const comment = '/* Windi CSS mock class names for devtools auto-completion */\n'
12 | const css = [
13 | ...completions.color,
14 | ...completions.static,
15 | ].map((name: string) => `.${compiler.$windi.processor.e(name)}{}`).join('')
16 | return `
17 | const style = document.createElement('style')
18 | style.setAttribute('type', 'text/css')
19 | style.innerHTML = ${JSON.stringify(comment + css)}
20 | document.head.prepend(style)
21 | `
22 | }
23 | async function devtoolsLoader(this: loader.LoaderContext, source: string): Promise {
24 | const callback = this.async()!
25 |
26 | if (!this._compiler) {
27 | callback(null, source)
28 | return
29 | }
30 |
31 | this.cacheable(true)
32 |
33 | const { port, host } = await this._compiler.$windi.server.ensureStart()
34 |
35 | if (isWebCompilerTarget(this._compiler.options.target) && isDev()) {
36 | const clientContent = readFileSync(DEVTOOLS_CLIENT_PATH, 'utf-8')
37 | .replace('__POST_PATH__', `http://${host}:${port}${DEVTOOLS_POST_PATH}`)
38 |
39 | const mockClasses = getMockClassesInjector(this._compiler)
40 |
41 | callback(null, `${clientContent}\n${mockClasses}`)
42 | }
43 | else {
44 | // returns the empty string if it is not in dev environment or if the compile target is not web, e.g. SSR.
45 | callback(null, '')
46 | }
47 | }
48 |
49 | export default devtoolsLoader
50 |
--------------------------------------------------------------------------------
/example/craco/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { UserOptions, WindiPluginUtils } from '@windicss/plugin-utils'
2 | import type Server from './core/server'
3 |
4 | // virtual module prefix
5 | // @ts-expect-error virtual module
6 | declare module 'virtual:windi.css' {}
7 | // @ts-expect-error virtual module
8 | declare module 'virtual:windi-base.css' {}
9 | // @ts-expect-error virtual module
10 | declare module 'virtual:windi-components.css' {}
11 | // @ts-expect-error virtual module
12 | declare module 'virtual:windi-utilities.css' {}
13 |
14 | // no prefix
15 | // @ts-expect-error virtual module
16 | declare module 'windi.css' {}
17 | // @ts-expect-error virtual module
18 | declare module 'windi-base.css' {}
19 | // @ts-expect-error virtual module
20 | declare module 'windi-components.css' {}
21 | // @ts-expect-error virtual module
22 | declare module 'windi-utilities.css' {}
23 |
24 | declare module 'webpack' {
25 | interface Compiler {
26 | $windi: WindiPluginUtils & {
27 | dirty: Set
28 | root: string
29 | virtualModules: Map
30 | initException?: Error
31 | invalidateCssModules: (resource: string, modules: string[]) => void
32 | server: Server
33 | }
34 | }
35 | }
36 |
37 | export type WindiCSSWebpackPluginOptions = UserOptions & {
38 | /**
39 | * Reuse existing utils if exists
40 | */
41 | utils?: WindiPluginUtils
42 | /**
43 | * The path where the virtual module should be injected. By default this is the project root but for
44 | * some projects (such as craco), specifying the directory is needed.
45 | *
46 | * @default ''
47 | */
48 | virtualModulePath: string
49 | /**
50 | * Options for devtools backend server.
51 | */
52 | server?: {
53 | /**
54 | * Port for devtools backend server.
55 | *
56 | * @default 8888
57 | */
58 | port?: number
59 | /**
60 | * Host for devtools backend server.
61 | *
62 | * @default '127.0.0.1'
63 | */
64 | host?: string
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/layers.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 | import { getModuleSource, vueWebpackCompiler, reactWebpackCompiler } from './helpers'
3 |
4 | describe("Layers test", function() {
5 |
6 | it('should render vue', done => {
7 | const compiler = vueWebpackCompiler('vue-layers')
8 | compiler.run((err, stats) => {
9 | expect(stats.compilation.errors).toStrictEqual([])
10 | // check the windi file has generated the right classes
11 | const windiBase = getModuleSource('virtual:windi-base.css', stats)
12 | expect(windiBase).toContain('body {')
13 | expect(windiBase).toMatchSnapshot('windi base')
14 |
15 | const windiComponents = getModuleSource('virtual:windi-components.css', stats)
16 | expect(windiComponents).toContain('windicss layer components')
17 | expect(windiComponents).toMatchSnapshot('windi components')
18 |
19 | const windiUtils = getModuleSource('virtual:windi-utilities.css', stats)
20 | expect(windiUtils).toContain('bg-teal-900:hover')
21 | expect(windiUtils).toMatchSnapshot('windi utilities')
22 |
23 | done(err)
24 | });
25 | });
26 | it('should render react', done => {
27 | const compiler = reactWebpackCompiler('react-layers')
28 | compiler.run((err, stats) => {
29 | expect(stats.compilation.errors).toStrictEqual([])
30 | // check the windi file has generated the right classes
31 | const windiBase = getModuleSource('virtual:windi-base.css', stats)
32 | expect(windiBase).toContain('body {')
33 | expect(windiBase).toMatchSnapshot('windi base')
34 |
35 | const windiComponents = getModuleSource('virtual:windi-components.css', stats)
36 | expect(windiComponents).toContain('windicss layer components')
37 | expect(windiComponents).toMatchSnapshot('windi components')
38 |
39 | const windiUtils = getModuleSource('virtual:windi-utilities.css', stats)
40 | expect(windiUtils).toContain('bg-blue-500:hover')
41 | expect(windiUtils).toMatchSnapshot('windi utilities')
42 |
43 | done(err)
44 | });
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/plugin.svg:
--------------------------------------------------------------------------------
1 | illustration/plugin
--------------------------------------------------------------------------------
/test/helpers/vueWebpackCompiler.ts:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import webpack from 'webpack'
3 | import WebpackWindiCSSPlugin from '../../dist/plugin.mjs'
4 | import VueLoaderPlugin from 'vue-loader/lib/plugin'
5 |
6 | export function vueWebpackCompiler (type = 'vue', config = {}) {
7 | const root = path.dirname(__dirname)
8 | const context = path.join(root, 'fixtures', type)
9 | return webpack({
10 | entry: `./index.js`,
11 | context,
12 | mode: 'development',
13 | devtool: false,
14 | output: {
15 | path: path.join(root, '/dist'),
16 | },
17 | module: {
18 | rules: [
19 | {
20 | resourceQuery: /blockType=i18n/,
21 | type: 'javascript/auto',
22 | loader: '@intlify/vue-i18n-loader',
23 | },
24 | {
25 | test: /\.css$/,
26 | use: [
27 | 'vue-style-loader',
28 | 'css-loader'
29 | ]
30 | },
31 | {
32 | test: /\.vue$/,
33 | loader: 'vue-loader'
34 | },
35 | {
36 | test: /\.scss$/,
37 | use: [
38 | 'vue-style-loader',
39 | 'css-loader',
40 | 'sass-loader'
41 | ]
42 | },
43 | {
44 | test: /\.sass$/,
45 | use: [
46 | 'vue-style-loader',
47 | 'css-loader',
48 | {
49 | loader: 'sass-loader',
50 | options: {
51 | sassOptions: {
52 | indentedSyntax: true
53 | }
54 | }
55 | }
56 | ]
57 | },
58 | {
59 | test: /\.less$/,
60 | use: [
61 | 'vue-style-loader',
62 | 'css-loader',
63 | 'less-loader'
64 | ]
65 | },
66 | {
67 | test: /\.styl(us)?$/,
68 | use: [
69 | 'vue-style-loader',
70 | 'css-loader',
71 | 'stylus-loader'
72 | ]
73 | },
74 | ]
75 | },
76 | plugins: [
77 | new WebpackWindiCSSPlugin({
78 | root: context,
79 | ...config,
80 | }),
81 | new VueLoaderPlugin()
82 | ],
83 | });
84 | }
85 |
--------------------------------------------------------------------------------
/example/nuxt/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation .
8 |
9 |
Installed CLI Plugins
10 |
14 |
Essential Links
15 |
22 |
Ecosystem
23 |
30 |
31 |
32 |
33 |
41 |
42 |
43 |
59 |
--------------------------------------------------------------------------------
/example/vue3/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation .
8 |
9 |
Installed CLI Plugins
10 |
14 |
Essential Links
15 |
22 |
Ecosystem
23 |
30 |
31 |
32 |
33 |
41 |
42 |
43 |
59 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation .
8 |
9 |
Installed CLI Plugins
10 |
14 |
Essential Links
15 |
22 |
Ecosystem
23 |
30 |
31 |
32 |
33 |
41 |
42 |
43 |
59 |
--------------------------------------------------------------------------------
/test/regex.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest'
2 |
3 | describe("Virtual module regex tests", function() {
4 |
5 | it('should match on windows path', () => {
6 | expect(
7 | /virtual:windi-?(.*?)\.css/.test('D:\\a\\windicss-webpack-plugin\\windicss-webpack-plugin\\test\\virtual:windi.css')
8 | ).toBeTruthy()
9 | });
10 | });
11 |
12 | describe("CSS parsing skip", function() {
13 |
14 | it('should detect when to skip css parsing', () => {
15 | expect(/@(apply|variants|screen|layer)\s/gm.test('import \'virtual:windi.css\';\n' +
16 | ' export default function Layout({\n' +
17 | ' title,\n' +
18 | ' children\n' +
19 | ' }) {\n' +
20 | ' return /*#__PURE__*/React.createElement(\\"div\\", {\n' +
21 | ' id: \\"layout-wrapper\\",\n' +
22 | ' className: \'bg-gray-100 text-gray-900 dark:bg-gray-900 dark:text-gray-100\'\n' +
23 | ' }, /*#__PURE__*/React.createElement(Head, null, /*#__PURE__*/React.createElement(\\"title\\", null, title)), children, /*#__PURE__*/React.createElement(\\"style\\", {\n' +
24 | ' jsx: true,\n' +
25 | ' global: true\n' +
26 | ' }, `\n' +
27 | ' body {\n' +
28 | ' @apply m-0 p-0 w-100vw h-100vh overflow-hidden hover:bg-blue-500 hover:text-xs;\n' +
29 | ' font-family: \'-apple-system\', \'BlinkMacSystemFont\', \'Segoe UI\',\n' +
30 | ' \'Roboto\', \'Oxygen\', \'Ubuntu\', \'Cantarell\', \'Fira Sans\', \'Droid Sans\',\n' +
31 | ' \'Helvetica Neue\', \'sans-serif\';\n' +
32 | ' -webkit-font-smoothing: antialiased;\n' +
33 | ' -moz-osx-font-smoothing: grayscale;\n' +
34 | ' }\n' +
35 | ' `));\n' +
36 | ' }')).toBeTruthy()
37 | });
38 | it('sass-global', () => {
39 | expect(/@(apply|variants|screen|layer)\s/gm.test('.sass-global\n' +
40 | '@apply bg-orange-400 text-white p-4 w-1/4 transition hover:(bg-orange-900 text-orange-100)\n' +
41 | ' h2\n' +
42 | '@apply font-bold text-sm')).toBeTruthy()
43 | expect(/@(apply|variants|screen|layer)\s/gm.test('.sass-global\n' +
44 | '@apply bg-orange-400 text-white p-4 w-1/4 transition hover:(bg-orange-900 text-orange-100)\n' +
45 | ' h2\n' +
46 | '@apply font-bold text-sm')).toBeTruthy()
47 | });
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/src/core/utils.ts:
--------------------------------------------------------------------------------
1 | import type { WindiPluginUtils } from '@windicss/plugin-utils'
2 | import type webpack from 'webpack'
3 | import { HAS_DIRECTIVE_TEST, HAS_THEME_FUNCTION_TEST, MODULE_ID_VIRTUAL_PREFIX } from './constants'
4 | import debug from './debug'
5 |
6 | export function cssRequiresTransform(source: string) {
7 | return HAS_DIRECTIVE_TEST.test(source) || HAS_THEME_FUNCTION_TEST.test(source)
8 | }
9 |
10 | export function isJsx(source: string) {
11 | return /{`(.*)`}/gms.test(source)
12 | }
13 |
14 | export function transformCSS(service: WindiPluginUtils, source: string, resource: string) {
15 | if (!source || source.length <= 0)
16 | return source
17 |
18 | // make sure the transform is required, can be expensive
19 | if (!cssRequiresTransform(source))
20 | return source
21 |
22 | let output = source
23 | try {
24 | output = service.transformCSS(source, resource, { globaliseKeyframes: true })
25 | if (!output || output.length <= 0) {
26 | debug.loader(`[WindiCSS] Invalid response from windi core transforming resource: ${resource}.`)
27 | return source
28 | }
29 | debug.loader('Transformed CSS', resource)
30 | }
31 | catch (e) {
32 | debug.loader(`[WindiCSS] Exception when transforming CSS for resource: ${resource}.`, e)
33 | return source
34 | }
35 | return output
36 | }
37 |
38 | /**
39 | * Default function. Take the value or the default
40 | */
41 | export function def(val: any, def: any) {
42 | if (val)
43 | return val
44 |
45 | return def
46 | }
47 |
48 | export function getChangedModuleNames(utils: WindiPluginUtils) {
49 | if (utils.hasPending)
50 | utils.buildPendingStyles()
51 |
52 | const moduleNames = [
53 | `${MODULE_ID_VIRTUAL_PREFIX}.css`,
54 | ]
55 |
56 | Object.entries(utils.layersMeta).forEach(([name, meta]) => {
57 | if (meta.cssCache == null)
58 | moduleNames.push(`${MODULE_ID_VIRTUAL_PREFIX}-${name}.css`)
59 | })
60 |
61 | return moduleNames
62 | }
63 |
64 | export const isDev = () => process.env.NODE_ENV === 'development'
65 |
66 | export function isWebCompilerTarget(target: webpack.Configuration['target']) {
67 | let isWeb = true
68 | if (typeof target === 'string') {
69 | isWeb = !target.includes('node')
70 | }
71 | else if (Array.isArray(target)) {
72 | target.forEach((str) => {
73 | if (str.includes('node'))
74 | isWeb = false
75 | })
76 | }
77 | else {
78 | isWeb = false
79 | }
80 | return isWeb
81 | }
82 |
--------------------------------------------------------------------------------
/example/next/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | min-height: 100vh;
3 | padding: 0 0.5rem;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | }
9 |
10 | .main {
11 | padding: 5rem 0;
12 | flex: 1;
13 | display: flex;
14 | flex-direction: column;
15 | justify-content: center;
16 | align-items: center;
17 | }
18 |
19 | .footer {
20 | width: 100%;
21 | height: 100px;
22 | border-top: 1px solid #eaeaea;
23 | display: flex;
24 | justify-content: center;
25 | align-items: center;
26 | }
27 |
28 | .footer img {
29 | margin-left: 0.5rem;
30 | }
31 |
32 | .footer a {
33 | display: flex;
34 | justify-content: center;
35 | align-items: center;
36 | }
37 |
38 | .title a {
39 | color: #0070f3;
40 | text-decoration: none;
41 | }
42 |
43 | .title a:hover,
44 | .title a:focus,
45 | .title a:active {
46 | text-decoration: underline;
47 | }
48 |
49 | .title {
50 | margin: 0;
51 | line-height: 1.15;
52 | font-size: 4rem;
53 | }
54 |
55 | .title,
56 | .description {
57 | text-align: center;
58 | }
59 |
60 | .description {
61 | line-height: 1.5;
62 | font-size: 1.5rem;
63 | }
64 |
65 | .code {
66 | background: #fafafa;
67 | border-radius: 5px;
68 | padding: 0.75rem;
69 | font-size: 1.1rem;
70 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
71 | Bitstream Vera Sans Mono, Courier New, monospace;
72 | }
73 |
74 | .grid {
75 | display: flex;
76 | align-items: center;
77 | justify-content: center;
78 | flex-wrap: wrap;
79 | max-width: 800px;
80 | margin-top: 3rem;
81 | }
82 |
83 | .card {
84 | margin: 1rem;
85 | flex-basis: 45%;
86 | padding: 1.5rem;
87 | text-align: left;
88 | color: inherit;
89 | text-decoration: none;
90 | border: 1px solid #eaeaea;
91 | border-radius: 10px;
92 | transition: color 0.15s ease, border-color 0.15s ease;
93 | }
94 |
95 | .card:hover,
96 | .card:focus,
97 | .card:active {
98 | color: #0070f3;
99 | border-color: #0070f3;
100 | }
101 |
102 | .card h3 {
103 | margin: 0 0 1rem 0;
104 | font-size: 1.5rem;
105 | }
106 |
107 | .card p {
108 | margin: 0;
109 | font-size: 1.25rem;
110 | line-height: 1.5;
111 | }
112 |
113 | .logo {
114 | height: 1em;
115 | }
116 |
117 | @media (max-width: 600px) {
118 | .grid {
119 | width: 100%;
120 | flex-direction: column;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/loaders/windicss-style-pitcher.ts:
--------------------------------------------------------------------------------
1 | import type { loader } from 'webpack'
2 |
3 | type LoaderTest = (l: { path: string; ident?: string }) => boolean
4 |
5 | const windiTemplateTest: LoaderTest = l => /(\/|\\|@)windicss-template/.test(l.path)
6 | const windiStylePitcherTest: LoaderTest = l => /(\/|\\|@)windicss-style-pitcher/.test(l.path)
7 | const postCssLoaderTest: LoaderTest = l => /(\/|\\|@)postcss-loader/.test(l.path)
8 | const cssLoaderTest: LoaderTest = l => /(\/|\\|@)css-loader/.test(l.path)
9 |
10 | /*
11 | * Move the position of the transform-template loader for Vue SFCs.
12 | *
13 | * We move it just after the PostCSS loader
14 | */
15 | export const pitch = function (this: loader.LoaderContext, remainingRequest: string) {
16 | const findLoaderIndex = (test: LoaderTest) => this.loaders.findIndex((loader) => {
17 | return test(loader) && !loader.normalExecuted
18 | })
19 |
20 | const markLoaderAsExecuted: (test: LoaderTest) => any = (test) => {
21 | let index, loader
22 | while ((index = findLoaderIndex(test)) !== -1) {
23 | loader = this.loaders[index]
24 | /*
25 | * Hacky solution to avoid the loader from running.
26 | * Previously we removed the loader entirely however, this caused
27 | * a conflict with other loaders (see https://github.com/windicss/windicss-webpack-plugin/issues/111).
28 | */
29 | loader.pitchExecuted = true
30 | loader.normalExecuted = true
31 | }
32 | return loader
33 | }
34 |
35 | // remove the pitcher immediately
36 | markLoaderAsExecuted(windiStylePitcherTest)
37 |
38 | // make sure we're dealing with style-loader
39 | if (!remainingRequest.includes('&type=style')) {
40 | // clean up
41 | markLoaderAsExecuted(windiTemplateTest)
42 | return
43 | }
44 |
45 | let newTemplateLoaderIndex = findLoaderIndex(postCssLoaderTest)
46 | // just in-case they don't have post-css for whatever reason we also search for the css-loader
47 | if (newTemplateLoaderIndex === -1)
48 | newTemplateLoaderIndex = findLoaderIndex(cssLoaderTest)
49 |
50 | // we couldn't find either PostCSS loader or CSS loader so we bail out
51 | if (newTemplateLoaderIndex === -1) {
52 | // clean up
53 | markLoaderAsExecuted(windiTemplateTest)
54 | return
55 | }
56 |
57 | const templateLoader = markLoaderAsExecuted(windiTemplateTest)
58 | // re-insert the template-loader in the right spot
59 | if (templateLoader)
60 | this.loaders.splice(newTemplateLoaderIndex + 1, 0, templateLoader)
61 | }
62 |
--------------------------------------------------------------------------------
/example/vue3-storybook/src/stories/assets/stackalt.svg:
--------------------------------------------------------------------------------
1 | illustration/stackalt
--------------------------------------------------------------------------------
/example/craco/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/icejs/public/favicon.png:
--------------------------------------------------------------------------------
1 | �PNG
2 |
3 |
IHDR � � ��g-
4 | fIDATx��klSe�_E��Cza�ʸ��0�2@�>x ^?(bl;ƌZ���& &��/^h)0.
5 | ��4E�@� �Զnc�v�<>o��ҵ��zN�����
�lky��{zΙ �hLv�-vM���q����q��M��c#?����鲺���8�� ���������=��o⏽�/X*i���� hX�4���67�͢�N��$�*�}������#�)k90N/
�)O����&[��?�g���]9�M�**�v�����d���?�a����t.%��0�*�6�����A�r� �����S$����kO�-<�zT�����Y��/�$�>X��`��2�M��_���߹Zn��
r
6 | ���\�8d��g7�*i� ���K����&���g���D`l�����Cf.�1���@-��N���������M��+Ĺ�Fʷ���$,,]Zl.�W �7��i�\�6!'y�-@��>��7�\������u��4L 5XW�]����^��w�~�<��_C��3C�iMf�+����֒���0�1�4J ����� 0�9-@���/R\��{xfm�"���W�,2gF+
+��jK&�M��y^S�Y*�*@��F�z�%���@@E9����44.GJ6�9Ԥ�K@���4�T�;�� �8O��=ovC�Rj����x`�CE��y����Ʉ&�i嬓W� 3QZ{n������upy����'�|���Ȓ�M�5� �����o���8g�G�z�����0_z���=���=��Ùu�7�\�y����C�������ܦ��F�x*���5��h?�� `�.�[�UT(�B�qZZ�Z�v��A���-G�M��tD.)�?����DD�.�Y�g�N��V�;� M�V�Mɞ�xZI-���~5 7�,��!pe�/�������!�e����(��~.�IfRM'D2�����>���wt�g�vi�i��*l.�-2Ź+4���w�C1)ܕ2��"�N�/�}�����H�zǤd������"Y�C��-J�t�����D
7 | �i��s���
�d�ݴ�~ȝ/(��&�ۂ4}�YZЖ��Hvq��6�
^~��T��<P�7HJj���9 %�p/���4A�S�sG�=�IiT���~Xў�����<�P4�IY��o��0
8 | ���<�*}�S��͎m�je�p'�æ4����"WL��3���� �����B/�;�r?lR����!���;�Y$�
9 | K�w���C���m�a�^���n�F뇾�k�`����3< �,q�C���q���<?��2_�WS�0:���i�,7C@���C�E�Q/�xR������W�f����嵍+
10 | �
����yI�L0�J�c��!ݥ�EW���$[�����f)]6�&ݔnR�n
11 | �t��&I����,J�Ē5��a;�%[��N&�4rl����3�����^ )������y������Od?�i����<�v��91��wm�3�D(���{S�������~BFz5�!��Z���:*�j���I�o��_��"��7�W�H~0�@�<3��>��G��_�U���f�C����x�e��/ꇕOe?�:���~�~��督�^σ�&(��A�+�_��٦�1�����j�O�|bf8��8���@��):�� r�{O@w�h���f��~PY� ���n��� ���l����+����ּHz�A�����!��f��Xncjd�ؐ!
12 | f�I���=�η�H.S<��\@���t��]lD���U���0�������������2������
�����d�0*V���U�$�p�Β7��D�CW����,nv����В��Y�������oӼ��?�%#��Ӧ�こ�hz�4�FsI�L����d�]��'krP�� ]��SW^��)�m}ѹ������f!kskz��:w8-Q��Q� �$�S[I��:��П~�������~����-��S�S�Q�t��x�$O�%^��&Z�@[j�r��������!����"�Ʋ�I�r�M��m}PM�?�3b��)�r������X��jV��a�V��,�W�][� ^�͝3/ivOG����|G�>���25����xI�n&�o�
�T̷����������w�+ ݪ]�X��rz��>�~K-O ��Μ�7dg�}12SX�m��-�t�{Ř[�
13 | l