@douyinfe/semi-vite-plugin 2.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +83 -0
- package/README.md +200 -0
- package/lib/componentName.d.ts +2 -0
- package/lib/componentName.js +81 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +16 -0
- package/lib/plugin.d.ts +23 -0
- package/lib/plugin.js +169 -0
- package/lib/theme-loader.d.ts +18 -0
- package/lib/theme-loader.js +95 -0
- package/lib/types.d.ts +31 -0
- package/lib/types.js +2 -0
- package/lib/utils.d.ts +14 -0
- package/lib/utils.js +100 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 DouyinFE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
The code implementation of the external library is referenced by DouyinFe are:
|
|
24
|
+
|
|
25
|
+
- animate.css
|
|
26
|
+
|
|
27
|
+
The MIT License (MIT)
|
|
28
|
+
|
|
29
|
+
Copyright (c) 2020 Daniel Eden
|
|
30
|
+
|
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
32
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
33
|
+
in the Software without restriction, including without limitation the rights
|
|
34
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
35
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
36
|
+
furnished to do so, subject to the following conditions:
|
|
37
|
+
|
|
38
|
+
The above copyright notice and this permission notice shall be included in all
|
|
39
|
+
copies or substantial portions of the Software.
|
|
40
|
+
|
|
41
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
42
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
43
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
44
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
45
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
46
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
47
|
+
SOFTWARE.
|
|
48
|
+
|
|
49
|
+
- Ant Design
|
|
50
|
+
MIT LICENSE
|
|
51
|
+
|
|
52
|
+
Copyright (c) 2015-present Ant UED, https://xtech.antfin.com/
|
|
53
|
+
|
|
54
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
55
|
+
a copy of this software and associated documentation files (the
|
|
56
|
+
"Software"), to deal in the Software without restriction, including
|
|
57
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
58
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
59
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
60
|
+
the following conditions:
|
|
61
|
+
|
|
62
|
+
The above copyright notice and this permission notice shall be
|
|
63
|
+
included in all copies or substantial portions of the Software.
|
|
64
|
+
|
|
65
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
66
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
67
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
68
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
69
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
70
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
71
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
72
|
+
|
|
73
|
+
- rc-tree
|
|
74
|
+
|
|
75
|
+
MIT LICENSE
|
|
76
|
+
|
|
77
|
+
Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
|
|
78
|
+
|
|
79
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
80
|
+
|
|
81
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
82
|
+
|
|
83
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
> A vite plugin for Semi Design to custom theme, replace prefix and so on.
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
The plugin is designed for Semi Design with Vite, providing two major abilities:
|
|
6
|
+
|
|
7
|
+
- Custom theme
|
|
8
|
+
- Replace prefix of CSS selector
|
|
9
|
+
|
|
10
|
+
> Note: The plugin detects Semi related dependencies by package path. It supports both
|
|
11
|
+
> `@douyinfe/semi-ui` and version-suffixed packages like `@douyinfe/semi-ui-19` (also for `semi-icons`).
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Install
|
|
16
|
+
|
|
17
|
+
Install `@douyinfe/semi-vite-plugin` as a development dependency:
|
|
18
|
+
|
|
19
|
+
```shell
|
|
20
|
+
npm install --save-dev @douyinfe/semi-vite-plugin
|
|
21
|
+
# or
|
|
22
|
+
yarn add --dev @douyinfe/semi-vite-plugin
|
|
23
|
+
# or
|
|
24
|
+
pnpm add -D @douyinfe/semi-vite-plugin
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Custom theme
|
|
28
|
+
|
|
29
|
+
Semi Design uses Scss variables to extract thousands of Design Tokens. You can replace
|
|
30
|
+
those tokens through this plugin to achieve theme customization.
|
|
31
|
+
[More info](https://semi.design/dsm/)
|
|
32
|
+
|
|
33
|
+
You can custom theme through three ways:
|
|
34
|
+
|
|
35
|
+
- npm package generated by Semi DSM
|
|
36
|
+
- Local Scss file in your project
|
|
37
|
+
- Pass key-value pair parameters to plugin
|
|
38
|
+
|
|
39
|
+
Priority from low to high.
|
|
40
|
+
|
|
41
|
+
#### Through npm package
|
|
42
|
+
|
|
43
|
+
After finishing the customization on
|
|
44
|
+
[Semi Design System](https://semi.design/dsm/), Semi DSM will generate an npm
|
|
45
|
+
package for you, then use it like this:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// vite.config.ts
|
|
49
|
+
import { defineConfig } from 'vite';
|
|
50
|
+
import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
51
|
+
|
|
52
|
+
export default defineConfig({
|
|
53
|
+
plugins: [
|
|
54
|
+
semiTheming({
|
|
55
|
+
theme: '@semi-bot/semi-theme-yours',
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Through local Scss file
|
|
62
|
+
|
|
63
|
+
You can check which tokens can be customized on the
|
|
64
|
+
[Semi Website](https://semi.design/en-US/basic/tokens).
|
|
65
|
+
|
|
66
|
+
Step 1: add a local file
|
|
67
|
+
|
|
68
|
+
```scss
|
|
69
|
+
// local.scss
|
|
70
|
+
$font-size-small: 16px;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Step 2: config vite
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// vite.config.ts
|
|
77
|
+
import path from 'path';
|
|
78
|
+
import { defineConfig } from 'vite';
|
|
79
|
+
import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
80
|
+
|
|
81
|
+
export default defineConfig({
|
|
82
|
+
plugins: [
|
|
83
|
+
semiTheming({
|
|
84
|
+
include: path.resolve(__dirname, 'local.scss'),
|
|
85
|
+
}),
|
|
86
|
+
],
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Through parameters
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// vite.config.ts
|
|
94
|
+
import { defineConfig } from 'vite';
|
|
95
|
+
import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
96
|
+
|
|
97
|
+
export default defineConfig({
|
|
98
|
+
plugins: [
|
|
99
|
+
semiTheming({
|
|
100
|
+
variables: {
|
|
101
|
+
'$font-size-small': '16px',
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Replace prefix of CSS selector
|
|
109
|
+
|
|
110
|
+
The CSS selectors used by Semi Design are prefixed with `semi` by default
|
|
111
|
+
(e.g. `.semi-button`). You can replace the prefix through this plugin:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// vite.config.ts
|
|
115
|
+
import { defineConfig } from 'vite';
|
|
116
|
+
import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
117
|
+
|
|
118
|
+
export default defineConfig({
|
|
119
|
+
plugins: [
|
|
120
|
+
semiTheming({
|
|
121
|
+
prefixCls: 'custom',
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Then you get the replaced CSS selectors (e.g. `.custom-button`).
|
|
128
|
+
|
|
129
|
+
### Wrap output styles with CSS layer
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
// vite.config.ts
|
|
133
|
+
import { defineConfig } from 'vite';
|
|
134
|
+
import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
135
|
+
|
|
136
|
+
export default defineConfig({
|
|
137
|
+
plugins: [
|
|
138
|
+
semiTheming({
|
|
139
|
+
cssLayer: true,
|
|
140
|
+
}),
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## API
|
|
146
|
+
|
|
147
|
+
### semiTheming(options)
|
|
148
|
+
|
|
149
|
+
| Property | Type | Default | Description |
|
|
150
|
+
| -------------------- | ----------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
151
|
+
| `theme` | `string \| { name?: string }` | - | Custom theme package name generated by Semi DSM. |
|
|
152
|
+
| `prefixCls` | `string` | `semi` | Prefix of CSS class names. |
|
|
153
|
+
| `variables` | `Record<string, string \| number>` | `{}` | Key-value pair of Scss variables. |
|
|
154
|
+
| `include` | `string` | - | Absolute path of an extra Scss file to inject after theme variables. |
|
|
155
|
+
| `cssLayer` | `boolean` | `false` | When `true`, wrap the final compiled CSS with `@layer semi { ... }`. |
|
|
156
|
+
| `omitCss` | `boolean` | `false` | Comment out `.css` imports inside semi packages. Useful when the integration framework can't import global CSS from `node_modules` directly. |
|
|
157
|
+
|
|
158
|
+
## How it works
|
|
159
|
+
|
|
160
|
+
1. **CSS → SCSS rewrite**: Intercepts requests to
|
|
161
|
+
`@douyinfe/semi-(ui|icons|foundation)/lib/**/*.css`, switches the suffix to
|
|
162
|
+
`.scss` and reads the original Sass source.
|
|
163
|
+
2. **Theme injection**: Injects the theme `index.scss` / `global.scss` /
|
|
164
|
+
`animation.scss` / `local.scss` / user-provided variables and `include`
|
|
165
|
+
files, plus `$prefix` and (optional) `@layer semi { ... }` wrapper.
|
|
166
|
+
3. **Sass compilation**: Compiles the assembled Sass source with
|
|
167
|
+
`sass.compileString`, resolving `~package/...` imports against the node_modules
|
|
168
|
+
tree of the original `.scss` file.
|
|
169
|
+
4. **Prefix patch**: For files matching `@douyinfe/semi-*/.../env.js`, rewrites
|
|
170
|
+
`BASE_CLASS_PREFIX` constant to the configured `prefixCls`. To make the same
|
|
171
|
+
replacement work for Vite's dev-mode dep pre-bundle (`.vite/deps`), an
|
|
172
|
+
esbuild plugin is registered via `optimizeDeps.esbuildOptions.plugins` to
|
|
173
|
+
rewrite the env modules at pre-bundle time as well.
|
|
174
|
+
5. **omitCss**: Optionally comments out `.css` imports inside Semi packages so
|
|
175
|
+
they don't reach the bundler.
|
|
176
|
+
|
|
177
|
+
## FAQ
|
|
178
|
+
|
|
179
|
+
### Why are classnames still `semi-*` in `vite dev`?
|
|
180
|
+
|
|
181
|
+
Vite pre-bundles `node_modules` packages into `.vite/deps` using esbuild
|
|
182
|
+
(or Rolldown in Vite 8+). When `prefixCls` is set, this plugin injects an
|
|
183
|
+
esbuild plugin to rewrite the relevant `env.js` files inside the pre-bundle.
|
|
184
|
+
If you previously started `vite` once without the plugin (or with a different
|
|
185
|
+
`prefixCls`), you may have a stale `.vite/deps` cache. Stop the dev server
|
|
186
|
+
and run `rm -rf node_modules/.vite` to force a clean re-bundle.
|
|
187
|
+
|
|
188
|
+
### Vite 8 prints a deprecation warning about `optimizeDeps.esbuildOptions`
|
|
189
|
+
|
|
190
|
+
Vite 8 switched to Rolldown for dep pre-bundling and now prefers
|
|
191
|
+
`optimizeDeps.rolldownOptions`. The plugin still uses
|
|
192
|
+
`optimizeDeps.esbuildOptions` for broad compatibility with Vite ≥3; Rolldown
|
|
193
|
+
keeps an esbuild-compatible shim, so the warning is harmless and the prefix
|
|
194
|
+
rewrite still works correctly.
|
|
195
|
+
|
|
196
|
+
## Related
|
|
197
|
+
|
|
198
|
+
- [Semi Design](https://semi.design/)
|
|
199
|
+
- [`@douyinfe/semi-webpack-plugin`](https://www.npmjs.com/package/@douyinfe/semi-webpack-plugin)
|
|
200
|
+
- [`@douyinfe/semi-rspack-plugin`](https://www.npmjs.com/package/@douyinfe/semi-rspack-plugin)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const componentVariablePathList = [
|
|
4
|
+
// tooltip/variables.scss defines `$horizontal-rate` / `$vertical-rate`
|
|
5
|
+
// which are referenced by popover/variables.scss and other components,
|
|
6
|
+
// so it must be imported before the rest of the alphabetical list.
|
|
7
|
+
'@douyinfe/semi-foundation/tooltip/variables.scss',
|
|
8
|
+
'@douyinfe/semi-foundation/aiChatDialogue/variables.scss',
|
|
9
|
+
'@douyinfe/semi-foundation/aiChatInput/variables.scss',
|
|
10
|
+
'@douyinfe/semi-foundation/anchor/variables.scss',
|
|
11
|
+
'@douyinfe/semi-foundation/audioPlayer/variables.scss',
|
|
12
|
+
'@douyinfe/semi-foundation/autoComplete/variables.scss',
|
|
13
|
+
'@douyinfe/semi-foundation/avatar/variables.scss',
|
|
14
|
+
'@douyinfe/semi-foundation/backtop/variables.scss',
|
|
15
|
+
'@douyinfe/semi-foundation/badge/variables.scss',
|
|
16
|
+
'@douyinfe/semi-foundation/banner/variables.scss',
|
|
17
|
+
'@douyinfe/semi-foundation/breadcrumb/variables.scss',
|
|
18
|
+
'@douyinfe/semi-foundation/button/variables.scss',
|
|
19
|
+
'@douyinfe/semi-foundation/calendar/variables.scss',
|
|
20
|
+
'@douyinfe/semi-foundation/card/variables.scss',
|
|
21
|
+
'@douyinfe/semi-foundation/carousel/variables.scss',
|
|
22
|
+
'@douyinfe/semi-foundation/cascader/variables.scss',
|
|
23
|
+
'@douyinfe/semi-foundation/chat/variables.scss',
|
|
24
|
+
'@douyinfe/semi-foundation/checkbox/variables.scss',
|
|
25
|
+
'@douyinfe/semi-foundation/collapse/variables.scss',
|
|
26
|
+
'@douyinfe/semi-foundation/colorPicker/variables.scss',
|
|
27
|
+
'@douyinfe/semi-foundation/cropper/variables.scss',
|
|
28
|
+
'@douyinfe/semi-foundation/datePicker/variables.scss',
|
|
29
|
+
'@douyinfe/semi-foundation/descriptions/variables.scss',
|
|
30
|
+
'@douyinfe/semi-foundation/divider/variables.scss',
|
|
31
|
+
'@douyinfe/semi-foundation/dropdown/variables.scss',
|
|
32
|
+
'@douyinfe/semi-foundation/empty/variables.scss',
|
|
33
|
+
'@douyinfe/semi-foundation/floatButton/variables.scss',
|
|
34
|
+
'@douyinfe/semi-foundation/form/variables.scss',
|
|
35
|
+
'@douyinfe/semi-foundation/grid/variables.scss',
|
|
36
|
+
'@douyinfe/semi-foundation/highlight/variables.scss',
|
|
37
|
+
'@douyinfe/semi-foundation/hotKeys/variables.scss',
|
|
38
|
+
'@douyinfe/semi-foundation/image/variables.scss',
|
|
39
|
+
'@douyinfe/semi-foundation/input/variables.scss',
|
|
40
|
+
'@douyinfe/semi-foundation/inputNumber/variables.scss',
|
|
41
|
+
'@douyinfe/semi-foundation/jsonViewer/variables.scss',
|
|
42
|
+
'@douyinfe/semi-foundation/list/variables.scss',
|
|
43
|
+
'@douyinfe/semi-foundation/markdownRender/variables.scss',
|
|
44
|
+
'@douyinfe/semi-foundation/modal/variables.scss',
|
|
45
|
+
'@douyinfe/semi-foundation/navigation/variables.scss',
|
|
46
|
+
'@douyinfe/semi-foundation/notification/variables.scss',
|
|
47
|
+
'@douyinfe/semi-foundation/pagination/variables.scss',
|
|
48
|
+
'@douyinfe/semi-foundation/pincode/variables.scss',
|
|
49
|
+
'@douyinfe/semi-foundation/popconfirm/variables.scss',
|
|
50
|
+
'@douyinfe/semi-foundation/popover/variables.scss',
|
|
51
|
+
'@douyinfe/semi-foundation/progress/variables.scss',
|
|
52
|
+
'@douyinfe/semi-foundation/radio/variables.scss',
|
|
53
|
+
'@douyinfe/semi-foundation/rating/variables.scss',
|
|
54
|
+
'@douyinfe/semi-foundation/resizable/variables.scss',
|
|
55
|
+
'@douyinfe/semi-foundation/scrollList/variables.scss',
|
|
56
|
+
'@douyinfe/semi-foundation/select/variables.scss',
|
|
57
|
+
'@douyinfe/semi-foundation/sidebar/variables.scss',
|
|
58
|
+
'@douyinfe/semi-foundation/sideSheet/variables.scss',
|
|
59
|
+
'@douyinfe/semi-foundation/skeleton/variables.scss',
|
|
60
|
+
'@douyinfe/semi-foundation/slider/variables.scss',
|
|
61
|
+
'@douyinfe/semi-foundation/space/variables.scss',
|
|
62
|
+
'@douyinfe/semi-foundation/spin/variables.scss',
|
|
63
|
+
'@douyinfe/semi-foundation/steps/variables.scss',
|
|
64
|
+
'@douyinfe/semi-foundation/switch/variables.scss',
|
|
65
|
+
'@douyinfe/semi-foundation/table/variables.scss',
|
|
66
|
+
'@douyinfe/semi-foundation/tabs/variables.scss',
|
|
67
|
+
'@douyinfe/semi-foundation/tag/variables.scss',
|
|
68
|
+
'@douyinfe/semi-foundation/tagInput/variables.scss',
|
|
69
|
+
'@douyinfe/semi-foundation/timePicker/variables.scss',
|
|
70
|
+
'@douyinfe/semi-foundation/timeline/variables.scss',
|
|
71
|
+
'@douyinfe/semi-foundation/toast/variables.scss',
|
|
72
|
+
'@douyinfe/semi-foundation/tooltip/variables.scss',
|
|
73
|
+
'@douyinfe/semi-foundation/transfer/variables.scss',
|
|
74
|
+
'@douyinfe/semi-foundation/tree/variables.scss',
|
|
75
|
+
'@douyinfe/semi-foundation/treeSelect/variables.scss',
|
|
76
|
+
'@douyinfe/semi-foundation/typography/variables.scss',
|
|
77
|
+
'@douyinfe/semi-foundation/upload/variables.scss',
|
|
78
|
+
'@douyinfe/semi-foundation/userGuide/variables.scss',
|
|
79
|
+
'@douyinfe/semi-foundation/videoPlayer/variables.scss'
|
|
80
|
+
];
|
|
81
|
+
exports.default = componentVariablePathList;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformSemiTheme = exports.semiTheming = void 0;
|
|
4
|
+
const plugin_1 = require("./plugin");
|
|
5
|
+
Object.defineProperty(exports, "semiTheming", { enumerable: true, get: function () { return plugin_1.semiTheming; } });
|
|
6
|
+
const theme_loader_1 = require("./theme-loader");
|
|
7
|
+
Object.defineProperty(exports, "transformSemiTheme", { enumerable: true, get: function () { return theme_loader_1.transformSemiTheme; } });
|
|
8
|
+
exports.default = plugin_1.semiTheming;
|
|
9
|
+
const _exports = module.exports;
|
|
10
|
+
const _fn = plugin_1.semiTheming;
|
|
11
|
+
Object.assign(_fn, _exports);
|
|
12
|
+
_fn.default = _fn;
|
|
13
|
+
_fn.semiTheming = _fn;
|
|
14
|
+
_fn.transformSemiTheme = theme_loader_1.transformSemiTheme;
|
|
15
|
+
_fn.__esModule = true;
|
|
16
|
+
module.exports = _fn;
|
package/lib/plugin.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { SemiVitePluginOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Create a Vite plugin that customizes Semi Design themes, replaces selector prefix,
|
|
5
|
+
* and optionally omits CSS imports inside Semi packages.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { defineConfig } from 'vite';
|
|
10
|
+
* import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
11
|
+
*
|
|
12
|
+
* export default defineConfig({
|
|
13
|
+
* plugins: [
|
|
14
|
+
* semiTheming({
|
|
15
|
+
* theme: '@semi-bot/semi-theme-feishu',
|
|
16
|
+
* prefixCls: 'my-semi',
|
|
17
|
+
* }),
|
|
18
|
+
* ],
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function semiTheming(rawOptions?: SemiVitePluginOptions): Plugin;
|
|
23
|
+
export default semiTheming;
|
package/lib/plugin.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.semiTheming = void 0;
|
|
27
|
+
const fs_1 = require("fs");
|
|
28
|
+
const url_1 = require("url");
|
|
29
|
+
const utils_1 = require("./utils");
|
|
30
|
+
const theme_loader_1 = require("./theme-loader");
|
|
31
|
+
const SEMI_CSS_RE = /@douyinfe[\\/]+semi-(ui|icons|foundation)(-\d+)?[\\/]+lib[\\/]+.+\.css(\?.*)?$/;
|
|
32
|
+
const SEMI_JS_RE = /@douyinfe[\\/]+semi-(ui|icons)(-\d+)?[\\/]+lib[\\/]+.+\.js(\?.*)?$/;
|
|
33
|
+
const SEMI_ENV_JS_RE = /@douyinfe[\\/]+semi-[^\\/]+[\\/]+.+env\.js(\?.*)?$/;
|
|
34
|
+
const PREFIX_REGEX = /(BASE_CLASS_PREFIX\s*[:=]\s*['"])([^'"]+)(['"])/g;
|
|
35
|
+
const CSS_IMPORT_REGEX = /(import\s+['"][^'"]+\.css['"])/g;
|
|
36
|
+
const CSS_REQUIRE_REGEX = /(require\(['"][^'"]+\.css['"]\))/g;
|
|
37
|
+
/**
|
|
38
|
+
* Create a Vite plugin that customizes Semi Design themes, replaces selector prefix,
|
|
39
|
+
* and optionally omits CSS imports inside Semi packages.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { defineConfig } from 'vite';
|
|
44
|
+
* import semiTheming from '@douyinfe/semi-vite-plugin';
|
|
45
|
+
*
|
|
46
|
+
* export default defineConfig({
|
|
47
|
+
* plugins: [
|
|
48
|
+
* semiTheming({
|
|
49
|
+
* theme: '@semi-bot/semi-theme-feishu',
|
|
50
|
+
* prefixCls: 'my-semi',
|
|
51
|
+
* }),
|
|
52
|
+
* ],
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
function semiTheming(rawOptions = {}) {
|
|
57
|
+
const { theme, ...options } = rawOptions;
|
|
58
|
+
const themeOptions = typeof theme === 'object' && theme !== null ? { ...theme } : { name: theme };
|
|
59
|
+
const include = options.include ? (0, utils_1.normalizePath)(options.include) : undefined;
|
|
60
|
+
const variables = (0, utils_1.convertMapToString)(options.variables || {});
|
|
61
|
+
return {
|
|
62
|
+
name: 'semi-theme',
|
|
63
|
+
enforce: 'pre',
|
|
64
|
+
config() {
|
|
65
|
+
// In dev mode Vite pre-bundles `@douyinfe/semi-ui` and friends
|
|
66
|
+
// into `.vite/deps` via esbuild *before* this plugin's
|
|
67
|
+
// `transform` hook can rewrite `BASE_CLASS_PREFIX` in `env.js`.
|
|
68
|
+
// To make the prefix replacement work for the pre-bundled
|
|
69
|
+
// output, we register an esbuild plugin that intercepts the
|
|
70
|
+
// raw `base/env.js` files during pre-bundling and inlines the
|
|
71
|
+
// user-defined prefix. The same `transform` hook continues to
|
|
72
|
+
// cover non-bundled paths (build mode, SSR, lazy imports).
|
|
73
|
+
if (!options.prefixCls) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const prefixCls = options.prefixCls;
|
|
77
|
+
return {
|
|
78
|
+
optimizeDeps: {
|
|
79
|
+
esbuildOptions: {
|
|
80
|
+
plugins: [
|
|
81
|
+
{
|
|
82
|
+
name: 'semi-vite-prefix-env',
|
|
83
|
+
setup(build) {
|
|
84
|
+
build.onLoad({ filter: /@douyinfe[/\\]+semi-[^/\\]+[/\\]+lib[/\\]+(es|cjs)[/\\]+(base[/\\]+)?env\.js$/ }, () => ({
|
|
85
|
+
contents: `export const BASE_CLASS_PREFIX = ${JSON.stringify(prefixCls)};\n`,
|
|
86
|
+
loader: 'js'
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
async load(id) {
|
|
96
|
+
const filePath = (0, utils_1.normalizePath)(id.split('?')[0]);
|
|
97
|
+
if (!SEMI_CSS_RE.test(filePath)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const scssFilePath = filePath.replace(/\.css$/, '.scss');
|
|
101
|
+
if (!(0, fs_1.existsSync)(scssFilePath)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const rawSource = (0, fs_1.readFileSync)(scssFilePath, 'utf-8');
|
|
105
|
+
const transformed = (0, theme_loader_1.transformSemiTheme)(rawSource, scssFilePath, {
|
|
106
|
+
name: themeOptions.name,
|
|
107
|
+
prefixCls: options.prefixCls,
|
|
108
|
+
variables,
|
|
109
|
+
include,
|
|
110
|
+
cssLayer: options.cssLayer,
|
|
111
|
+
});
|
|
112
|
+
const { default: sass } = await Promise.resolve().then(() => __importStar(require('sass')));
|
|
113
|
+
const resolverCache = new Map();
|
|
114
|
+
const getResolver = (importer) => {
|
|
115
|
+
let resolver = resolverCache.get(importer);
|
|
116
|
+
if (!resolver) {
|
|
117
|
+
resolver = (0, utils_1.createCssImportResolver)(importer);
|
|
118
|
+
resolverCache.set(importer, resolver);
|
|
119
|
+
}
|
|
120
|
+
return resolver;
|
|
121
|
+
};
|
|
122
|
+
const compileOptions = {
|
|
123
|
+
importers: [
|
|
124
|
+
{
|
|
125
|
+
findFileUrl(url, context) {
|
|
126
|
+
const baseFile = context?.containingUrl
|
|
127
|
+
? (0, url_1.fileURLToPath)(context.containingUrl)
|
|
128
|
+
: scssFilePath;
|
|
129
|
+
return getResolver(baseFile)(url);
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
logger: sass.Logger.silent,
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
compileOptions.silenceDeprecations = ['import', 'legacy-js-api', 'global-builtin'];
|
|
137
|
+
const result = sass.compileString(transformed, compileOptions);
|
|
138
|
+
return result.css;
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
delete compileOptions.silenceDeprecations;
|
|
142
|
+
const result = sass.compileString(transformed, compileOptions);
|
|
143
|
+
return result.css;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
transform(code, id) {
|
|
147
|
+
const filePath = (0, utils_1.normalizePath)(id.split('?')[0]);
|
|
148
|
+
let nextCode = code;
|
|
149
|
+
let changed = false;
|
|
150
|
+
if (options.omitCss && SEMI_JS_RE.test(filePath)) {
|
|
151
|
+
const replaced = nextCode.replace(CSS_IMPORT_REGEX, '// $1').replace(CSS_REQUIRE_REGEX, '// $1');
|
|
152
|
+
if (replaced !== nextCode) {
|
|
153
|
+
nextCode = replaced;
|
|
154
|
+
changed = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (options.prefixCls && SEMI_ENV_JS_RE.test(filePath)) {
|
|
158
|
+
const replaced = nextCode.replace(PREFIX_REGEX, `$1${options.prefixCls}$3`);
|
|
159
|
+
if (replaced !== nextCode) {
|
|
160
|
+
nextCode = replaced;
|
|
161
|
+
changed = true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return changed ? { code: nextCode, map: null } : null;
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
exports.semiTheming = semiTheming;
|
|
169
|
+
exports.default = semiTheming;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface SemiThemeLoaderQuery {
|
|
2
|
+
name?: string;
|
|
3
|
+
prefixCls?: string;
|
|
4
|
+
variables?: string;
|
|
5
|
+
include?: string;
|
|
6
|
+
cssLayer?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Transform a raw SCSS source (the original `lib/**\/*.scss` of semi-ui/semi-icons/semi-foundation)
|
|
10
|
+
* by injecting theme variables, prefix and (optionally) wrapping with a CSS layer.
|
|
11
|
+
*
|
|
12
|
+
* This is a port of `semi-webpack/src/semi-theme-loader.ts` for sass.compileString environment.
|
|
13
|
+
*
|
|
14
|
+
* @param source the raw scss source code
|
|
15
|
+
* @param importer absolute path of the source file, used as the base directory for resolving `~` imports
|
|
16
|
+
* @param query loader options
|
|
17
|
+
*/
|
|
18
|
+
export declare function transformSemiTheme(source: string, importer: string, query: SemiThemeLoaderQuery): string;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.transformSemiTheme = void 0;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const componentName_1 = __importDefault(require("./componentName"));
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
/**
|
|
11
|
+
* Transform a raw SCSS source (the original `lib/**\/*.scss` of semi-ui/semi-icons/semi-foundation)
|
|
12
|
+
* by injecting theme variables, prefix and (optionally) wrapping with a CSS layer.
|
|
13
|
+
*
|
|
14
|
+
* This is a port of `semi-webpack/src/semi-theme-loader.ts` for sass.compileString environment.
|
|
15
|
+
*
|
|
16
|
+
* @param source the raw scss source code
|
|
17
|
+
* @param importer absolute path of the source file, used as the base directory for resolving `~` imports
|
|
18
|
+
* @param query loader options
|
|
19
|
+
*/
|
|
20
|
+
function transformSemiTheme(source, importer, query) {
|
|
21
|
+
const theme = query.name || '@douyinfe/semi-theme-default';
|
|
22
|
+
const cssLayer = query.cssLayer ?? false;
|
|
23
|
+
const scssVarStr = `@import "~${theme}/scss/index.scss";\n`;
|
|
24
|
+
const cssVarStr = `@import "~${theme}/scss/global.scss";\n`;
|
|
25
|
+
let animationStr = `@import "~${theme}/scss/animation.scss";\n`;
|
|
26
|
+
if (!(0, utils_1.tryResolve)(importer, `${theme}/scss/animation.scss`)) {
|
|
27
|
+
animationStr = '';
|
|
28
|
+
}
|
|
29
|
+
const shouldInject = source.includes('semi-base');
|
|
30
|
+
let fileStr = source;
|
|
31
|
+
const componentVariables = (0, utils_1.tryResolve)(importer, `${theme}/scss/local.scss`);
|
|
32
|
+
if (query.include || query.variables || componentVariables) {
|
|
33
|
+
let localImport = '';
|
|
34
|
+
if (componentVariables) {
|
|
35
|
+
localImport += `\n@import "~${theme}/scss/local.scss";`;
|
|
36
|
+
}
|
|
37
|
+
if (query.include) {
|
|
38
|
+
localImport += `\n@import "${query.include}";`;
|
|
39
|
+
}
|
|
40
|
+
if (query.variables) {
|
|
41
|
+
localImport += `\n${query.variables}`;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const regex = /(@import '.\/variables.scss';?|@import ".\/variables.scss";?)/g;
|
|
45
|
+
const fileSplit = source.split(regex).filter(item => Boolean(item));
|
|
46
|
+
if (fileSplit.length > 1) {
|
|
47
|
+
fileSplit.splice(fileSplit.length - 1, 0, localImport);
|
|
48
|
+
fileStr = fileSplit.join('');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
// ignore
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const prefixCls = query.prefixCls || 'semi';
|
|
56
|
+
const prefixClsStr = `$prefix: '${prefixCls}';\n`;
|
|
57
|
+
let finalCSS = '';
|
|
58
|
+
if (shouldInject) {
|
|
59
|
+
const customStr = (() => {
|
|
60
|
+
const resolvedCustom = (0, utils_1.tryResolve)(importer, `${theme}/scss/custom.scss`);
|
|
61
|
+
if (!resolvedCustom) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
let addBodySelector = true;
|
|
65
|
+
try {
|
|
66
|
+
const customFileContent = (0, fs_1.readFileSync)(resolvedCustom, 'utf-8');
|
|
67
|
+
const regex = /body\s*\{/;
|
|
68
|
+
if (regex.test(customFileContent)) {
|
|
69
|
+
addBodySelector = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
const collectAllVariablesPath = [
|
|
76
|
+
...componentName_1.default,
|
|
77
|
+
];
|
|
78
|
+
if (componentVariables) {
|
|
79
|
+
collectAllVariablesPath.push(`${theme}/scss/local.scss`);
|
|
80
|
+
}
|
|
81
|
+
collectAllVariablesPath.push(`${theme}/scss/custom.scss`);
|
|
82
|
+
const inner = collectAllVariablesPath.map(p => `@import "~${p}";`).join('\n');
|
|
83
|
+
return addBodySelector ? `body:not(:not(body)){${inner}};` : inner;
|
|
84
|
+
})();
|
|
85
|
+
finalCSS = `${animationStr}${cssVarStr}${scssVarStr}${prefixClsStr}${fileStr}${customStr}`;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
finalCSS = `${scssVarStr}${prefixClsStr}${fileStr}`;
|
|
89
|
+
}
|
|
90
|
+
if (cssLayer) {
|
|
91
|
+
finalCSS = `@layer semi{${finalCSS}}`;
|
|
92
|
+
}
|
|
93
|
+
return finalCSS;
|
|
94
|
+
}
|
|
95
|
+
exports.transformSemiTheme = transformSemiTheme;
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface SemiThemeOptions {
|
|
2
|
+
name?: string;
|
|
3
|
+
}
|
|
4
|
+
export interface SemiVitePluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Custom theme. Pass the npm package name generated by Semi DSM,
|
|
7
|
+
* or an object with `{ name }`.
|
|
8
|
+
*/
|
|
9
|
+
theme?: string | SemiThemeOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Wrap final CSS with `@layer semi { ... }`.
|
|
12
|
+
*/
|
|
13
|
+
cssLayer?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Prefix of the CSS selector. Default is `semi`.
|
|
16
|
+
*/
|
|
17
|
+
prefixCls?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Key-value pair of Scss variables. e.g. `{ '$font-size-small': '16px' }`
|
|
20
|
+
*/
|
|
21
|
+
variables?: Record<string, string | number>;
|
|
22
|
+
/**
|
|
23
|
+
* Absolute path of a local Scss file that will be injected after theme variables.
|
|
24
|
+
*/
|
|
25
|
+
include?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Omit the `import xxx.css` statements emitted from semi packages.
|
|
28
|
+
* Useful for Next.js/SSR scenarios where global css cannot be imported from node_modules.
|
|
29
|
+
*/
|
|
30
|
+
omitCss?: boolean;
|
|
31
|
+
}
|
package/lib/types.js
ADDED
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { URL } from 'url';
|
|
3
|
+
export declare function normalizePath(p: string): string;
|
|
4
|
+
export declare function convertMapToString(map: Record<string, string | number>): string;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a `~package/foo` style import to its absolute file URL by walking up node_modules
|
|
7
|
+
* from a given importer. Also supports relative paths.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createCssImportResolver(importer: string): (url: string) => URL | null;
|
|
10
|
+
/**
|
|
11
|
+
* Try to resolve a module path relative to a given importer file. Returns absolute file path
|
|
12
|
+
* when found, otherwise `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function tryResolve(importer: string, request: string): string | undefined;
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.tryResolve = exports.createCssImportResolver = exports.convertMapToString = exports.normalizePath = void 0;
|
|
27
|
+
const fs_1 = require("fs");
|
|
28
|
+
const os_1 = require("os");
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
const module_1 = require("module");
|
|
31
|
+
const url_1 = require("url");
|
|
32
|
+
const isWindows = (0, os_1.platform)() === 'win32';
|
|
33
|
+
function normalizePath(p) {
|
|
34
|
+
return path.posix.normalize(isWindows ? p.replace(/\\/g, '/') : p);
|
|
35
|
+
}
|
|
36
|
+
exports.normalizePath = normalizePath;
|
|
37
|
+
function convertMapToString(map) {
|
|
38
|
+
return Object.keys(map).reduce(function (prev, curr) {
|
|
39
|
+
return prev + `${curr}: ${map[curr]};\n`;
|
|
40
|
+
}, '');
|
|
41
|
+
}
|
|
42
|
+
exports.convertMapToString = convertMapToString;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a `~package/foo` style import to its absolute file URL by walking up node_modules
|
|
45
|
+
* from a given importer. Also supports relative paths.
|
|
46
|
+
*/
|
|
47
|
+
function createCssImportResolver(importer) {
|
|
48
|
+
const req = (0, module_1.createRequire)(importer.startsWith('file://') ? importer : (0, url_1.pathToFileURL)(importer).toString());
|
|
49
|
+
return (id) => {
|
|
50
|
+
if (id.startsWith('~')) {
|
|
51
|
+
const pkgPath = id.substring(1);
|
|
52
|
+
try {
|
|
53
|
+
const resolved = req.resolve(pkgPath);
|
|
54
|
+
if ((0, fs_1.existsSync)(resolved)) {
|
|
55
|
+
return (0, url_1.pathToFileURL)(resolved);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
// ignore, fallback to manual walk below
|
|
60
|
+
}
|
|
61
|
+
let currentDir = path.dirname(importer);
|
|
62
|
+
const root = path.parse(currentDir).root;
|
|
63
|
+
while (currentDir && currentDir !== root) {
|
|
64
|
+
const candidate = path.join(currentDir, 'node_modules', pkgPath);
|
|
65
|
+
if ((0, fs_1.existsSync)(candidate)) {
|
|
66
|
+
return (0, url_1.pathToFileURL)(candidate);
|
|
67
|
+
}
|
|
68
|
+
const parent = path.dirname(currentDir);
|
|
69
|
+
if (parent === currentDir)
|
|
70
|
+
break;
|
|
71
|
+
currentDir = parent;
|
|
72
|
+
}
|
|
73
|
+
const rootNodeModulesPath = path.join(process.cwd(), 'node_modules', pkgPath);
|
|
74
|
+
if ((0, fs_1.existsSync)(rootNodeModulesPath)) {
|
|
75
|
+
return (0, url_1.pathToFileURL)(rootNodeModulesPath);
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const resolvedFilePath = path.resolve(path.dirname(importer), id);
|
|
80
|
+
if ((0, fs_1.existsSync)(resolvedFilePath)) {
|
|
81
|
+
return (0, url_1.pathToFileURL)(resolvedFilePath);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
exports.createCssImportResolver = createCssImportResolver;
|
|
87
|
+
/**
|
|
88
|
+
* Try to resolve a module path relative to a given importer file. Returns absolute file path
|
|
89
|
+
* when found, otherwise `undefined`.
|
|
90
|
+
*/
|
|
91
|
+
function tryResolve(importer, request) {
|
|
92
|
+
try {
|
|
93
|
+
const req = (0, module_1.createRequire)(importer.startsWith('file://') ? importer : (0, url_1.pathToFileURL)(importer).toString());
|
|
94
|
+
return req.resolve(request);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.tryResolve = tryResolve;
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@douyinfe/semi-vite-plugin",
|
|
3
|
+
"version": "2.98.0",
|
|
4
|
+
"description": "A vite plugin for Semi Design to custom theme, replace prefix and so on.",
|
|
5
|
+
"homepage": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"directories": {
|
|
10
|
+
"lib": "lib"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"lib",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build:lib": "rimraf lib && tsc",
|
|
22
|
+
"dev": "tsc -w --sourceMap",
|
|
23
|
+
"test": "npm run build:lib && node test/run.mjs",
|
|
24
|
+
"prepublishOnly": "npm run build:lib"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"sass": "^1.54.9"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"vite": ">=3.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"rimraf": "^3.0.2",
|
|
34
|
+
"typescript": "^4",
|
|
35
|
+
"vite": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"gitHead": "e33a947a4e0745a7ad15d3e773355cc19d23b174"
|
|
38
|
+
}
|