@asd14/vblocks 1.0.0 → 2.0.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 +17 -25
- package/README.md +328 -93
- package/bin/vblocks.sh +107 -18
- package/package.json +46 -36
- package/src/postcss.config.js +7 -7
- package/src/types/client.d.ts +86 -0
- package/src/webpack.config.js +134 -26
- package/template/_common/_gitignore +3 -0
- package/template/_common/src/index.css +4 -0
- package/template/_common/src/index.html +11 -0
- package/template/_common/tsconfig.json +13 -0
- package/template/plain/package.json +23 -0
- package/template/plain/src/index.tsx +11 -0
- package/template/xyflow-playground/package.json +26 -0
- package/template/xyflow-playground/postcss.config.js +13 -0
- package/template/xyflow-playground/src/index.css +1 -0
- package/template/xyflow-playground/src/index.tsx +128 -0
- package/src/tailwind.config.js +0 -4
package/LICENSE
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025
|
|
4
|
-
All rights reserved.
|
|
3
|
+
Copyright (c) 2025 Andrei Dumitrescu
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
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:
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://github.com/asd-xiv/vblocks/actions/workflows/main.yml)
|
|
2
|
+
[](https://www.npmjs.com/package/@asd14/vblocks)
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
# @asd14/vblocks
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
modern toolchain integration.
|
|
6
|
+
> 📜 POSIX + 📦 Webpack, an unlikely story!
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
- **No configs** - All you need are `src/index.tsx` and `src/index.html`
|
|
11
|
+
- **Built in** - SWC for TypeScript, PostCSS, CSS Modules, MDX, React Refresh,
|
|
12
|
+
bundle analyzer
|
|
13
|
+
|
|
14
|
+
<!-- vim-markdown-toc GFM -->
|
|
15
|
+
|
|
16
|
+
- [Installation](#installation)
|
|
17
|
+
- [Peer Dependencies](#peer-dependencies)
|
|
18
|
+
- [Usage](#usage)
|
|
19
|
+
- [Quick Start](#quick-start)
|
|
20
|
+
- [Project Structure](#project-structure)
|
|
21
|
+
- [Configuration](#configuration)
|
|
22
|
+
- [Commands](#commands)
|
|
23
|
+
- [`vblocks init`](#vblocks-init)
|
|
24
|
+
- [`vblocks serve`](#vblocks-serve)
|
|
25
|
+
- [`vblocks build`](#vblocks-build)
|
|
26
|
+
- [`vblocks eject`](#vblocks-eject)
|
|
27
|
+
- [Features in Detail](#features-in-detail)
|
|
28
|
+
- [TypeScript](#typescript)
|
|
29
|
+
- [PostCSS](#postcss)
|
|
30
|
+
- [CSS Modules Support](#css-modules-support)
|
|
31
|
+
- [Asset Handling](#asset-handling)
|
|
32
|
+
- [Environment Variables](#environment-variables)
|
|
33
|
+
- [Path Alias](#path-alias)
|
|
34
|
+
- [How It Works](#how-it-works)
|
|
35
|
+
- [FAQ](#faq)
|
|
36
|
+
- [Does VBlocks support Tailwind?](#does-vblocks-support-tailwind)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
39
|
+
<!-- vim-markdown-toc -->
|
|
16
40
|
|
|
17
41
|
## Installation
|
|
18
42
|
|
|
@@ -20,170 +44,381 @@ modern toolchain integration.
|
|
|
20
44
|
npm install --save-dev @asd14/vblocks
|
|
21
45
|
```
|
|
22
46
|
|
|
47
|
+
> [!IMPORTANT]
|
|
48
|
+
> VBlocks needs Node `^22.22.3`, `^24.15.0` or `>=26.0`.
|
|
49
|
+
|
|
50
|
+
### Peer Dependencies
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
npm install react react-dom
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> [!IMPORTANT]
|
|
57
|
+
> VBlocks needs React `^18` or `^19`.
|
|
58
|
+
|
|
23
59
|
## Usage
|
|
24
60
|
|
|
25
61
|
### Quick Start
|
|
26
62
|
|
|
63
|
+
Create a project and start the dev server:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
npx @asd14/vblocks init my-app
|
|
67
|
+
cd my-app
|
|
68
|
+
npm install
|
|
69
|
+
npm start
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Run a command in a project that has VBlocks installed:
|
|
73
|
+
|
|
27
74
|
```sh
|
|
28
|
-
# Start
|
|
75
|
+
# Start the dev server
|
|
29
76
|
npx vblocks serve
|
|
30
77
|
|
|
31
78
|
# Build for production
|
|
32
79
|
npx vblocks build
|
|
33
80
|
|
|
34
|
-
#
|
|
81
|
+
# Print the default Webpack config
|
|
35
82
|
npx vblocks eject webpack
|
|
36
83
|
```
|
|
37
84
|
|
|
38
85
|
### Project Structure
|
|
39
86
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```
|
|
87
|
+
```text
|
|
43
88
|
your-project/
|
|
44
89
|
├── src/
|
|
45
90
|
│ ├── index.tsx # Application entry point
|
|
46
91
|
│ ├── index.html # HTML template
|
|
47
|
-
│ ├── index.css # Global
|
|
92
|
+
│ ├── index.css # Global CSS (optional)
|
|
48
93
|
│ └── public/
|
|
49
94
|
│ ├── favicon.svg # Favicon (optional)
|
|
50
|
-
│ └── robots.txt #
|
|
95
|
+
│ └── robots.txt # Crawler instructions (optional)
|
|
51
96
|
├── .env # Environment variables (optional)
|
|
52
97
|
└── dist/ # Build output
|
|
53
98
|
```
|
|
54
99
|
|
|
55
|
-
##
|
|
100
|
+
## Configuration
|
|
56
101
|
|
|
57
|
-
|
|
102
|
+
A config in your project root replaces the default of the same name.
|
|
58
103
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
3. **Proxies commands** - `build` and `serve` are passed directly to `webpack`
|
|
63
|
-
with custom parameters
|
|
64
|
-
4. **Provides configuration inspection** - `eject` outputs configuration content
|
|
65
|
-
for review
|
|
104
|
+
- `webpack.config.js`
|
|
105
|
+
- `postcss.config.js`
|
|
106
|
+
- `.swcrc`
|
|
66
107
|
|
|
67
|
-
|
|
108
|
+
To replace a default, first [`eject`](#vblocks-eject) it into your project root,
|
|
109
|
+
then edit the file:
|
|
68
110
|
|
|
69
|
-
|
|
70
|
-
|
|
111
|
+
```sh
|
|
112
|
+
npx vblocks eject postcss > postcss.config.js
|
|
113
|
+
```
|
|
71
114
|
|
|
72
|
-
|
|
73
|
-
|
|
115
|
+
> [!NOTE]
|
|
116
|
+
> VBlocks does not merge your config with the default, with two exceptions:
|
|
117
|
+
>
|
|
118
|
+
> - `.swcrc -> env.targets`: VBlocks adds the default when yours has none
|
|
119
|
+
> - `.swcrc -> jsc.transform.react.refresh`: VBlocks adds the React Refresh
|
|
120
|
+
> transform when `serve` runs in `development` mode
|
|
74
121
|
|
|
75
|
-
|
|
122
|
+
## Commands
|
|
76
123
|
|
|
77
|
-
|
|
78
|
-
- `postcss.config.js` - PostCSS configuration
|
|
79
|
-
- `tailwind.config.js` - TailwindCSS configuration
|
|
80
|
-
- `.swcrc` - SWC configuration
|
|
124
|
+
### `vblocks init`
|
|
81
125
|
|
|
82
|
-
|
|
126
|
+
```text
|
|
127
|
+
vblocks init <directory> [--template <name>]
|
|
128
|
+
```
|
|
83
129
|
|
|
84
|
-
|
|
130
|
+
Creates a project in `<directory>` from a template.
|
|
85
131
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
132
|
+
| Parameter | Required | Default | Description |
|
|
133
|
+
| ------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------ |
|
|
134
|
+
| `<directory>` | yes | none | The project root. `init` creates it when it is missing and fails when it exists and is not empty |
|
|
135
|
+
| `--template <name>` | no | `plain` | The template to copy: `plain` or `xyflow-playground` |
|
|
136
|
+
|
|
137
|
+
| Template | `src/index.tsx` | `dependencies` | Tailwind |
|
|
138
|
+
| ------------------- | ------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| `plain` | Hello World! | `react`, `react-dom` | no |
|
|
140
|
+
| `xyflow-playground` | Renders a graph of nodes you can drag and connect | `react`, `react-dom`, [`@xyflow/react`](https://reactflow.dev) | yes, `package.json`, `postcss.config.js` and `src/index.css` hold [the setup](#does-vblocks-support-tailwind) |
|
|
141
|
+
|
|
142
|
+
`init` writes:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
<directory>/
|
|
146
|
+
├── src/
|
|
147
|
+
│ ├── index.tsx # Application entry point
|
|
148
|
+
│ ├── index.html # HTML template
|
|
149
|
+
│ └── index.css # Global CSS
|
|
150
|
+
├── .gitignore # node_modules, dist, .env
|
|
151
|
+
├── package.json
|
|
152
|
+
├── postcss.config.js # Only in xyflow-playground
|
|
153
|
+
└── tsconfig.json
|
|
98
154
|
```
|
|
99
155
|
|
|
100
|
-
|
|
156
|
+
Run `init` through `npx @asd14/vblocks`. `init` installs no dependencies, so
|
|
157
|
+
install them next:
|
|
158
|
+
|
|
159
|
+
```sh
|
|
160
|
+
npx @asd14/vblocks init my-flow --template xyflow-playground
|
|
161
|
+
cd my-flow
|
|
162
|
+
npm install
|
|
163
|
+
```
|
|
101
164
|
|
|
102
165
|
### `vblocks serve`
|
|
103
166
|
|
|
104
|
-
|
|
105
|
-
|
|
167
|
+
```text
|
|
168
|
+
vblocks serve [--mode <mode>] [<webpack option>...]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Starts the dev server. Without `--port`, it listens on `http://localhost:8080`.
|
|
172
|
+
|
|
173
|
+
| Parameter | Required | Default | Description |
|
|
174
|
+
| ------------------ | -------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| `--mode <mode>` | no | `development` | The Webpack mode, `development` or `production`. React Refresh runs only in `development` |
|
|
176
|
+
| `<webpack option>` | no | none | Any other [`webpack serve`](https://webpack.js.org/configuration/dev-server/) option, eg. `--port 3000` or `--no-open`. VBlocks passes it to Webpack unchanged |
|
|
106
177
|
|
|
107
|
-
|
|
178
|
+
The dev server:
|
|
108
179
|
|
|
109
|
-
- Hot Module Replacement
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
|
|
180
|
+
- Replaces changed modules without a page reload, with Hot Module Replacement
|
|
181
|
+
and React Refresh
|
|
182
|
+
- Opens the browser
|
|
183
|
+
- Runs the bundle analyzer at `http://127.0.0.1:8888`. VBlocks does not open it
|
|
184
|
+
in the browser
|
|
185
|
+
- Serves `index.html` for every unknown path, for applications that use the
|
|
186
|
+
History API
|
|
187
|
+
|
|
188
|
+
**Runs**:
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
npx webpack serve --config <webpack config> \
|
|
192
|
+
--env entryDir=<project root> \
|
|
193
|
+
--mode development \
|
|
194
|
+
[...your arguments]
|
|
195
|
+
```
|
|
114
196
|
|
|
115
197
|
### `vblocks build`
|
|
116
198
|
|
|
117
|
-
|
|
118
|
-
|
|
199
|
+
```text
|
|
200
|
+
vblocks build [--mode <mode>] [--env single] [<webpack option>...]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Builds the project into `dist/`.
|
|
204
|
+
|
|
205
|
+
| Parameter | Required | Default | Description |
|
|
206
|
+
| ------------------ | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
207
|
+
| `--mode <mode>` | no | `production` | The Webpack mode, `development` or `production`. The build minifies JS, CSS and HTML only in `production` |
|
|
208
|
+
| `--env single` | no | off | Build one standalone `dist/index.html` |
|
|
209
|
+
| `<webpack option>` | no | none | Any other [`webpack build`](https://webpack.js.org/api/cli/) option, eg. `--stats errors-only`. VBlocks passes it to Webpack unchanged |
|
|
119
210
|
|
|
120
|
-
|
|
211
|
+
Without `--env single`, the build:
|
|
121
212
|
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
- Performance hints
|
|
213
|
+
- Writes JS and CSS files with content-hashed names
|
|
214
|
+
- Writes a `react` chunk, and a `vendors` chunk when your other dependencies
|
|
215
|
+
total over 20 KB
|
|
126
216
|
|
|
127
|
-
|
|
217
|
+
With `--env single`:
|
|
128
218
|
|
|
129
|
-
|
|
130
|
-
|
|
219
|
+
- `dist/index.html` holds every script, stylesheet, image, font and the favicon
|
|
220
|
+
- A browser opens the file from disk, with no server and no network
|
|
221
|
+
- Keep the route in the URL hash. On `file://`, `history.pushState` to another
|
|
222
|
+
path throws
|
|
223
|
+
|
|
224
|
+
**Runs**:
|
|
225
|
+
|
|
226
|
+
```sh
|
|
227
|
+
npx webpack build --config <webpack config> \
|
|
228
|
+
--env entryDir=<project root> \
|
|
229
|
+
--mode production \
|
|
230
|
+
[...your arguments]
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### `vblocks eject`
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
vblocks eject <config>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Prints a default config to stdout.
|
|
240
|
+
|
|
241
|
+
| Parameter | Required | Default | Description |
|
|
242
|
+
| ---------- | -------- | ------- | -------------------------------------------------- |
|
|
243
|
+
| `<config>` | yes | none | The config to print: `webpack`, `postcss` or `swc` |
|
|
244
|
+
|
|
245
|
+
Save the output in your project root to [replace the default](#configuration):
|
|
131
246
|
|
|
132
247
|
```sh
|
|
133
248
|
npx vblocks eject webpack > webpack.config.js
|
|
249
|
+
npx vblocks eject postcss > postcss.config.js
|
|
250
|
+
npx vblocks eject swc > .swcrc
|
|
134
251
|
```
|
|
135
252
|
|
|
136
253
|
## Features in Detail
|
|
137
254
|
|
|
255
|
+
### TypeScript
|
|
256
|
+
|
|
257
|
+
VBlocks does not check types and never reads your `tsconfig.json`. It only
|
|
258
|
+
compiles TypeScript with SWC.
|
|
259
|
+
|
|
260
|
+
For convenience, VBlocks provides client types in
|
|
261
|
+
[`client.d.ts`](src/types/client.d.ts) for:
|
|
262
|
+
|
|
263
|
+
- `.css` imports
|
|
264
|
+
- Image and font imports
|
|
265
|
+
- `process.env`
|
|
266
|
+
|
|
267
|
+
You can use them in your `tsconfig.json`:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"compilerOptions": {
|
|
272
|
+
"types": ["@asd14/vblocks/client"]
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
`tsc` needs the [`@self`](#path-alias) path alias in your `tsconfig.json`:
|
|
278
|
+
|
|
279
|
+
```diff
|
|
280
|
+
{
|
|
281
|
+
"compilerOptions": {
|
|
282
|
+
"types": ["@asd14/vblocks/client"],
|
|
283
|
+
+ "paths": { "@self/*": ["./src/*"] }
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The `tsconfig.json` that [`vblocks init`](#vblocks-init) writes has both.
|
|
289
|
+
|
|
290
|
+
### PostCSS
|
|
291
|
+
|
|
292
|
+
The default `postcss.config.js`:
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
/**
|
|
296
|
+
* @param {{ mode: "production" | "development" | "none" }} api
|
|
297
|
+
*/
|
|
298
|
+
export default ({ mode }) => ({
|
|
299
|
+
plugins: {
|
|
300
|
+
"postcss-preset-env": {
|
|
301
|
+
stage: 2,
|
|
302
|
+
},
|
|
303
|
+
"cssnano": mode === "production" && {
|
|
304
|
+
preset: "default",
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
})
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`postcss-preset-env` compiles nesting, `oklch()` and `color-mix()` for older
|
|
311
|
+
browsers and adds vendor prefixes.
|
|
312
|
+
|
|
138
313
|
### CSS Modules Support
|
|
139
314
|
|
|
140
|
-
- **Global CSS** - `import
|
|
141
|
-
- **Local CSS Modules** - `import styles from
|
|
315
|
+
- **Global CSS** - `import "./styles.css"`
|
|
316
|
+
- **Local CSS Modules** - `import styles from "./component.module.css"`
|
|
142
317
|
- **camelCase exports** - `.my-class` becomes `styles.myClass`
|
|
143
|
-
- **
|
|
318
|
+
- **Class names** - a bare hash in `production` mode, `[local]__[hash]` in
|
|
319
|
+
`development` mode
|
|
320
|
+
- **TypeScript** - the [client types](#typescript) declare `.css` imports
|
|
144
321
|
|
|
145
322
|
### Asset Handling
|
|
146
323
|
|
|
147
|
-
- **Images** -
|
|
148
|
-
- **Fonts** -
|
|
149
|
-
|
|
324
|
+
- **Images** - the build inlines `jpg`, `gif`, `png` and `svg` files up to 10 KB
|
|
325
|
+
- **Fonts** - the build writes `woff`, `woff2`, `ttf` and `eot` files to
|
|
326
|
+
`dist/fonts/`
|
|
327
|
+
- **Favicon and `robots.txt`** - yours or the default. `--env single` leaves
|
|
328
|
+
`robots.txt` out
|
|
150
329
|
|
|
151
330
|
### Environment Variables
|
|
152
331
|
|
|
153
|
-
VBlocks
|
|
332
|
+
VBlocks loads the `.env` file in your project root:
|
|
154
333
|
|
|
155
334
|
```env
|
|
156
|
-
|
|
157
|
-
REACT_APP_API_URL=https://api.example.com
|
|
335
|
+
API_URL=https://api.example.com
|
|
158
336
|
```
|
|
159
337
|
|
|
160
|
-
|
|
338
|
+
Read a variable in your code:
|
|
161
339
|
|
|
162
340
|
```tsx
|
|
163
|
-
const apiUrl = process.env
|
|
341
|
+
const apiUrl = process.env["API_URL"]
|
|
164
342
|
```
|
|
165
343
|
|
|
166
|
-
|
|
344
|
+
Webpack replaces each `process.env` read with the variable's value. A variable
|
|
345
|
+
that `.env` does not set reads as `undefined`. The build leaves out every
|
|
346
|
+
variable your code does not read.
|
|
347
|
+
|
|
348
|
+
The [client types](#typescript) declare `process.env` and nothing else from
|
|
349
|
+
Node, because Webpack replaces nothing else. With the client types, `tsc` fails
|
|
350
|
+
on `process.cwd()` and `Buffer`.
|
|
167
351
|
|
|
168
|
-
|
|
352
|
+
### Path Alias
|
|
353
|
+
|
|
354
|
+
`@self` points at your `src/` directory:
|
|
169
355
|
|
|
170
356
|
```tsx
|
|
171
|
-
// Instead of: import { Component } from
|
|
357
|
+
// Instead of: import { Component } from "../../../components"
|
|
172
358
|
import { Component } from "@self/components"
|
|
173
359
|
```
|
|
174
360
|
|
|
175
|
-
|
|
361
|
+
`tsc` needs the same alias in your `tsconfig.json`. See
|
|
362
|
+
[TypeScript](#typescript).
|
|
176
363
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
364
|
+
## How It Works
|
|
365
|
+
|
|
366
|
+
VBlocks is a POSIX shell script that runs Webpack. The script exports
|
|
367
|
+
`VB_POSTCSS_CONFIG` and `VB_SWC_CONFIG`, the paths of the configs it picked. The
|
|
368
|
+
Webpack config reads them.
|
|
369
|
+
|
|
370
|
+
## FAQ
|
|
371
|
+
|
|
372
|
+
### Does VBlocks support Tailwind?
|
|
373
|
+
|
|
374
|
+
Yes, VBlocks supports Tailwind but does not include it, so you need a
|
|
375
|
+
`postcss.config.js` in your project root.
|
|
376
|
+
|
|
377
|
+
1. Install Tailwind and the Tailwind plugin for PostCSS:
|
|
378
|
+
|
|
379
|
+
```sh
|
|
380
|
+
npm install --save-dev tailwindcss @tailwindcss/postcss
|
|
184
381
|
```
|
|
185
382
|
|
|
186
|
-
|
|
383
|
+
2. Eject the default PostCSS config into your project root:
|
|
384
|
+
|
|
385
|
+
```sh
|
|
386
|
+
npx vblocks eject postcss > postcss.config.js
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
3. Replace `postcss-preset-env` with the Tailwind plugin:
|
|
390
|
+
|
|
391
|
+
```diff
|
|
392
|
+
export default ({ mode }) => ({
|
|
393
|
+
plugins: {
|
|
394
|
+
- "postcss-preset-env": {
|
|
395
|
+
- stage: 2,
|
|
396
|
+
- },
|
|
397
|
+
+ "@tailwindcss/postcss": {
|
|
398
|
+
+ optimize: mode === "production",
|
|
399
|
+
+ },
|
|
400
|
+
"cssnano": mode === "production" && {
|
|
401
|
+
preset: "default",
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
})
|
|
405
|
+
```
|
|
187
406
|
|
|
188
|
-
|
|
407
|
+
> [!IMPORTANT]
|
|
408
|
+
> You do not need `postcss-preset-env`. Tailwind 4
|
|
409
|
+
> [compiles nesting and adds vendor prefixes](https://tailwindcss.com/docs/compatibility)
|
|
410
|
+
> itself. With both plugins, `postcss-preset-env` rewrites Tailwind's `@layer`
|
|
411
|
+
> rules into `:not(#\#)` selectors. The CSS file grows.
|
|
412
|
+
|
|
413
|
+
4. Add this import to `src/index.css`:
|
|
414
|
+
|
|
415
|
+
```css
|
|
416
|
+
@import "tailwindcss";
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
The `xyflow-playground` template of [`vblocks init`](#vblocks-init) has this
|
|
420
|
+
setup.
|
|
421
|
+
|
|
422
|
+
## License
|
|
189
423
|
|
|
424
|
+
MIT
|