@nlabs/lex 2.0.3 → 2.0.4
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/CHANGELOG.md +21 -0
- package/MIGRATION_V2.md +331 -0
- package/README.md +73 -102
- package/config.json +4 -8
- package/docs/assets/lex-logo.png +0 -0
- package/examples/lex.config.js +7 -10
- package/lex.config.js +12 -11
- package/lib/commands/ai/ai.js +22 -6
- package/lib/commands/serverless-dev/serverless-dev.d.ts +8 -0
- package/lib/commands/serverless-dev/serverless-dev.js +42 -6
- package/lib/commands/storybook/storybook.js +2 -25
- package/lib/lex.js +7 -10
- package/lib/utils/vite/config.js +12 -1
- package/package.json +17 -16
- package/scripts/validate-docs.js +141 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Disabled browser response caching in the Vite development server and forced dependency re-optimization on each development-server start.
|
|
6
|
+
- Allowed projects to override the new cache defaults through standard Vite configuration.
|
|
7
|
+
- Pinned Vitest and its V8 coverage provider to the same version to prevent peer-dependency resolution warnings during installation.
|
|
8
|
+
|
|
9
|
+
## 2.0.3
|
|
10
|
+
|
|
11
|
+
- Fixed TypeScript configuration path resolution for compilation and declaration generation.
|
|
12
|
+
|
|
13
|
+
## 2.0.2
|
|
14
|
+
|
|
15
|
+
- Fixed project and Lex package resolution in the Vite configuration.
|
|
16
|
+
- Expanded Vite migration and asset-pipeline documentation.
|
|
17
|
+
|
|
18
|
+
## 2.0.1
|
|
19
|
+
|
|
20
|
+
- Removed unused dependency overrides and the vulnerable broad Node polyfill dependency chain.
|
|
21
|
+
- Replaced the broad polyfill package with targeted browser shims used by Lex.
|
|
22
|
+
- Updated dependencies and cleared build warnings.
|
|
23
|
+
|
|
3
24
|
## 2.0.0
|
|
4
25
|
|
|
5
26
|
### Breaking changes
|
package/MIGRATION_V2.md
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# Migrating from Lex 1 to Lex 2
|
|
2
|
+
|
|
3
|
+
Lex 2 replaces Webpack with Vite for web development and production builds. It is a major-version upgrade: Webpack configuration is not read, and Lex does not provide a compatibility layer for it. Node, Lambda, and mobile projects use SWC by default.
|
|
4
|
+
|
|
5
|
+
This guide assumes a project is upgrading from the latest Lex 1 release. If the project uses an older Lex 1 release, update to the latest v1 release and establish a passing build before starting the v2 migration.
|
|
6
|
+
|
|
7
|
+
## What changes
|
|
8
|
+
|
|
9
|
+
| Area | Lex 1 | Lex 2 | Required action |
|
|
10
|
+
|------|-------|-------|-----------------|
|
|
11
|
+
| Web bundler | Webpack | Vite | Replace `webpack` configuration and custom Webpack integrations. |
|
|
12
|
+
| Non-web builds | SWC | SWC | Usually no source changes. Confirm the project preset and output. |
|
|
13
|
+
| Web development | Webpack development server | Vite development server | Review server configuration and asset URLs. |
|
|
14
|
+
| Dynamic imports | Webpack chunks | Native Vite/Rollup chunks | Keep standard `import()` expressions unchanged. |
|
|
15
|
+
| Browser shims | Webpack polyfills | Targeted Vite shims | Verify any Node modules used in browser code. |
|
|
16
|
+
| Storybook | React Webpack framework | React Vite framework | Replace project-owned Webpack Storybook packages and configuration. |
|
|
17
|
+
| Runtime requirement | Depends on the v1 release | Node.js 22 or newer | Upgrade Node.js before installing Lex 2. |
|
|
18
|
+
|
|
19
|
+
Lex 2 retains GraphQL document imports, PostCSS processing, source maps, environment modes, library output, static rendering, bundle reports, static file copying, image optimization, SVG sprites, favicon and social-image generation, and gzip sidecars.
|
|
20
|
+
|
|
21
|
+
## 1. Prepare the project
|
|
22
|
+
|
|
23
|
+
Use a migration branch and make sure the existing v1 application builds and tests successfully. Commit the current lockfile before continuing because the optional migration command replaces it.
|
|
24
|
+
|
|
25
|
+
Confirm the Node.js version:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
node --version
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Lex 2 requires Node.js 22 or newer.
|
|
32
|
+
|
|
33
|
+
## 2. Upgrade Lex
|
|
34
|
+
|
|
35
|
+
For a project-local development dependency:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install --save-dev @nlabs/lex@^2
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use the equivalent command if the project uses another supported package manager.
|
|
42
|
+
|
|
43
|
+
### Optional dependency cleanup
|
|
44
|
+
|
|
45
|
+
After committing `package.json` and the lockfile, run:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
lex migrate
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The command removes `node_modules`, removes the npm and Yarn lockfiles, removes non-`@types` dependencies whose package names contain `vite` or `vitest`, and runs the package manager configured by Lex. Review direct Vite or Vitest dependencies before using it if the project intentionally owns those packages.
|
|
52
|
+
|
|
53
|
+
`lex migrate` does not convert Webpack configuration or application source code. The remaining steps are still required.
|
|
54
|
+
|
|
55
|
+
## 3. Replace the Lex configuration
|
|
56
|
+
|
|
57
|
+
Rename the top-level `webpack` property to `vite` and retain `staticPath` if the project uses it.
|
|
58
|
+
|
|
59
|
+
Lex 1:
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
export default {
|
|
63
|
+
entryHTML: 'index.html',
|
|
64
|
+
entryJs: 'index.tsx',
|
|
65
|
+
outputPath: './dist',
|
|
66
|
+
preset: 'web',
|
|
67
|
+
sourcePath: './src',
|
|
68
|
+
targetEnvironment: 'web',
|
|
69
|
+
useTypescript: true,
|
|
70
|
+
webpack: {
|
|
71
|
+
staticPath: './src/static'
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Lex 2:
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
export default {
|
|
80
|
+
entryHTML: 'index.html',
|
|
81
|
+
entryJs: 'index.tsx',
|
|
82
|
+
outputPath: './dist',
|
|
83
|
+
preset: 'web',
|
|
84
|
+
sourcePath: './src',
|
|
85
|
+
targetEnvironment: 'web',
|
|
86
|
+
useTypescript: true,
|
|
87
|
+
vite: {
|
|
88
|
+
base: '/',
|
|
89
|
+
staticPath: './src/static'
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Do not leave both properties in the file. Lex 2 ignores `webpack`.
|
|
95
|
+
|
|
96
|
+
### Configuration mapping
|
|
97
|
+
|
|
98
|
+
| Lex 1 / Webpack setting | Lex 2 equivalent |
|
|
99
|
+
|-------------------------|------------------|
|
|
100
|
+
| `webpack.staticPath` | `vite.staticPath` |
|
|
101
|
+
| `webpack.entry` | Top-level `entryJs`, `lex build --entry`, or `vite.build` for an advanced multi-entry build |
|
|
102
|
+
| `webpack.output.path` | Top-level `outputPath` |
|
|
103
|
+
| `webpack.output.filename` | Top-level `outputFile`; use `outputHash` for Lex-managed hashed names |
|
|
104
|
+
| `webpack.resolve.alias` | `vite.resolve.alias` |
|
|
105
|
+
| `webpack.devServer` | `vite.server`; keep `dev.port` for Lex's default port |
|
|
106
|
+
| `webpack.plugins` | `vite.plugins` using Vite-compatible plugins |
|
|
107
|
+
| `webpack.module.rules` | Vite plugins or Vite-native asset and CSS handling |
|
|
108
|
+
| `DefinePlugin` | `vite.define` or Vite environment variables |
|
|
109
|
+
| `CopyWebpackPlugin` | `vite.staticPath`, conventional Lex asset directories, or `copyFiles` |
|
|
110
|
+
| `HtmlWebpackPlugin` | `<sourcePath>/<entryHTML>` as the Vite HTML entry |
|
|
111
|
+
|
|
112
|
+
Standard Vite options are placed directly inside `vite`. Project Vite plugins are appended to Lex's built-in plugin stack.
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
import examplePlugin from 'vite-plugin-example';
|
|
116
|
+
|
|
117
|
+
export default {
|
|
118
|
+
vite: {
|
|
119
|
+
base: '/application/',
|
|
120
|
+
plugins: [examplePlugin()],
|
|
121
|
+
resolve: {
|
|
122
|
+
alias: {
|
|
123
|
+
'@app': '/src'
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
server: {
|
|
127
|
+
proxy: {
|
|
128
|
+
'/api': 'http://localhost:4000'
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Only add a project plugin after confirming that Lex does not already provide the behavior.
|
|
136
|
+
|
|
137
|
+
## 4. Remove project-owned Webpack tooling
|
|
138
|
+
|
|
139
|
+
Remove Webpack packages that were added only for the Lex web build. Common examples include:
|
|
140
|
+
|
|
141
|
+
- `webpack`, `webpack-cli`, and `webpack-dev-server`
|
|
142
|
+
- `copy-webpack-plugin`, `compression-webpack-plugin`, and `html-webpack-plugin`
|
|
143
|
+
- `css-loader`, `style-loader`, and `mini-css-extract-plugin`
|
|
144
|
+
- `file-loader`, `url-loader`, and other Webpack-only loaders
|
|
145
|
+
- `favicons-webpack-plugin` and `image-minimizer-webpack-plugin`
|
|
146
|
+
- `dotenv-webpack`
|
|
147
|
+
- `@storybook/react-webpack5` and `@storybook/addon-styling-webpack`
|
|
148
|
+
|
|
149
|
+
Do not remove a package that another project-owned build still uses. Lex 2 supplies its own Vite and asset dependencies, so projects do not need to install Vite plugins for built-in Lex behavior.
|
|
150
|
+
|
|
151
|
+
Delete imports of Lex's former `webpack.config.js` and remove scripts that directly invoke Webpack for the Lex build.
|
|
152
|
+
|
|
153
|
+
## 5. Keep dynamic imports
|
|
154
|
+
|
|
155
|
+
Standard dynamic imports require no compatibility wrapper or plugin:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
export const loadDashboard = async () => import('./Dashboard.js');
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Vite preserves the dynamic boundary and creates a production chunk. If a project builds a path dynamically, follow Vite's statically analyzable import rules or use `import.meta.glob`.
|
|
162
|
+
|
|
163
|
+
Webpack-specific APIs do require changes:
|
|
164
|
+
|
|
165
|
+
| Webpack API | Vite approach |
|
|
166
|
+
|-------------|---------------|
|
|
167
|
+
| `require.context(...)` | `import.meta.glob(...)` |
|
|
168
|
+
| `require.ensure(...)` | Standard `import()` |
|
|
169
|
+
| `__webpack_public_path__` | `vite.base` or `import.meta.env.BASE_URL` |
|
|
170
|
+
| Loader prefixes such as `raw-loader!./file` | Vite query imports or a Vite plugin |
|
|
171
|
+
|
|
172
|
+
Example glob migration:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const modules = import.meta.glob('./views/*.tsx');
|
|
176
|
+
|
|
177
|
+
export const loadView = async (name: string) => {
|
|
178
|
+
const loader = modules[`./views/${name}.tsx`];
|
|
179
|
+
if(!loader) throw new Error(`Unknown view: ${name}`);
|
|
180
|
+
return loader();
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 6. Verify browser polyfills
|
|
185
|
+
|
|
186
|
+
Lex 2 automatically injects `Buffer`, `process`, and `global`, and provides browser replacements for:
|
|
187
|
+
|
|
188
|
+
- `assert`
|
|
189
|
+
- `buffer`
|
|
190
|
+
- `http`
|
|
191
|
+
- `https`
|
|
192
|
+
- `os`
|
|
193
|
+
- `path`
|
|
194
|
+
- `process`
|
|
195
|
+
- `stream`
|
|
196
|
+
- `util`
|
|
197
|
+
- `vm`
|
|
198
|
+
|
|
199
|
+
`crypto` and `node:crypto` resolve to an empty compatibility module, matching Lex 1 behavior. Browser code that needs cryptography should use the browser Web Crypto API instead of relying on the Node module.
|
|
200
|
+
|
|
201
|
+
Test every browser path that uses a Node API. A module being resolvable does not mean every Node runtime method is available in a browser shim.
|
|
202
|
+
|
|
203
|
+
## 7. Migrate environment variables
|
|
204
|
+
|
|
205
|
+
Vite exposes mode-specific `.env` files through `import.meta.env`. Client-visible custom variables should use the `VITE_` prefix:
|
|
206
|
+
|
|
207
|
+
```dotenv
|
|
208
|
+
VITE_API_URL=https://api.example.com
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
export const apiUrl = import.meta.env.VITE_API_URL;
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Replace client-side values previously injected by `dotenv-webpack` or `DefinePlugin`. Lex continues to define `process.env.NODE_ENV`. For other intentionally compiled constants, use `vite.define`:
|
|
216
|
+
|
|
217
|
+
```javascript
|
|
218
|
+
export default {
|
|
219
|
+
vite: {
|
|
220
|
+
define: {
|
|
221
|
+
__BUILD_ID__: JSON.stringify(process.env.BUILD_ID || 'local')
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Never place secrets in client environment variables or compiled definitions; both are included in browser output.
|
|
228
|
+
|
|
229
|
+
## 8. Verify HTML and assets
|
|
230
|
+
|
|
231
|
+
Vite uses `<sourcePath>/<entryHTML>` as the web HTML entry when that file exists. Keep the application module referenced with a module script:
|
|
232
|
+
|
|
233
|
+
```html
|
|
234
|
+
<div id="root"></div>
|
|
235
|
+
<script type="module" src="/index.tsx"></script>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Lex 2 preserves its conventional asset pipeline:
|
|
239
|
+
|
|
240
|
+
| Source | Production destination | Behavior |
|
|
241
|
+
|--------|------------------------|----------|
|
|
242
|
+
| `vite.staticPath` | Output root | Recursively copied |
|
|
243
|
+
| `<sourcePath>/images` | `images` | Copied and optimized |
|
|
244
|
+
| `<sourcePath>/fonts` | `fonts` | Copied |
|
|
245
|
+
| `<sourcePath>/docs` | `docs` | Copied |
|
|
246
|
+
| `<sourcePath>/icons/*.svg` | `icons/icons.svg` | Combined into an optimized SVG sprite |
|
|
247
|
+
| `<sourcePath>/images/logo.png` | Output root | Generates favicons, manifests, Open Graph, and Twitter images |
|
|
248
|
+
|
|
249
|
+
Compressible production files of at least 8 KiB receive `.gz` sidecars. GIF, JPEG, PNG, SVG, and WebP assets are optimized.
|
|
250
|
+
|
|
251
|
+
Files in `vite.staticPath` are referenced from the site root. For example, `src/static/robots.txt` is `/robots.txt`. Conventional image files retain their directory prefix, such as `/images/banner.png`.
|
|
252
|
+
|
|
253
|
+
## 9. Update Storybook
|
|
254
|
+
|
|
255
|
+
Lex 2 uses Storybook's React Vite framework. If the project owns `.storybook/main.ts`, use:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
import type {StorybookConfig} from '@storybook/react-vite';
|
|
259
|
+
|
|
260
|
+
const config: StorybookConfig = {
|
|
261
|
+
framework: '@storybook/react-vite',
|
|
262
|
+
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)']
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export default config;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Remove Webpack-only Storybook framework packages, addons, `webpackFinal` hooks, and loader rules. Convert necessary custom behavior to Vite plugins or a `viteFinal` hook. See the [Storybook guide](src/commands/storybook/README.md) for Lex-managed configuration.
|
|
269
|
+
|
|
270
|
+
## 10. Validate the migration
|
|
271
|
+
|
|
272
|
+
Inspect the fully resolved Vite configuration:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
lex config vite
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Then validate development, tests, and a clean production build:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
lex dev
|
|
282
|
+
lex test --unit
|
|
283
|
+
lex build --bundler vite --mode production --remove
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Check the following in both development and the production output:
|
|
287
|
+
|
|
288
|
+
- The application starts and client-side routes load directly.
|
|
289
|
+
- Every dynamic route or feature creates and loads its chunk.
|
|
290
|
+
- CSS, fonts, images, documents, and the SVG sprite resolve under the configured `base`.
|
|
291
|
+
- Favicons and social images are generated when `images/logo.png` exists.
|
|
292
|
+
- Browser code using `Buffer`, `process`, or Node module shims works as expected.
|
|
293
|
+
- GraphQL document imports resolve.
|
|
294
|
+
- Environment-specific API URLs contain the expected non-secret values.
|
|
295
|
+
- The deployment server serves precompressed `.gz` files when configured to do so.
|
|
296
|
+
|
|
297
|
+
## Troubleshooting
|
|
298
|
+
|
|
299
|
+
### A blank page or missing entry module
|
|
300
|
+
|
|
301
|
+
Confirm that `entryHTML` is relative to `sourcePath` and that its module script points to the source entry. Run `lex config vite` and inspect `root` and `build.rolldownOptions.input`.
|
|
302
|
+
|
|
303
|
+
### Assets return 404
|
|
304
|
+
|
|
305
|
+
Check `vite.base`, `vite.staticPath`, and the source directory conventions above. Do not include `src/static` in a public URL; files from that directory are served from the site root.
|
|
306
|
+
|
|
307
|
+
### A dependency imports an unsupported Node module
|
|
308
|
+
|
|
309
|
+
Prefer a browser-native dependency or add a narrowly scoped Vite alias/plugin. Avoid reinstalling a broad Node polyfill bundle unless the application has verified runtime requirements beyond Lex's targeted shims.
|
|
310
|
+
|
|
311
|
+
### A custom Webpack plugin has no Vite equivalent
|
|
312
|
+
|
|
313
|
+
First determine whether Lex 2 already covers the output. Otherwise, replace it with a Vite/Rollup-compatible plugin or a small project plugin. Webpack plugins cannot be placed in `vite.plugins`.
|
|
314
|
+
|
|
315
|
+
### The production deployment works at `/` but not a subpath
|
|
316
|
+
|
|
317
|
+
Set `vite.base` to the deployment prefix and verify that application routing uses the same base.
|
|
318
|
+
|
|
319
|
+
## Completion checklist
|
|
320
|
+
|
|
321
|
+
- [ ] Node.js is version 22 or newer.
|
|
322
|
+
- [ ] `@nlabs/lex` is version 2.x.
|
|
323
|
+
- [ ] The `webpack` property and Lex Webpack imports are removed.
|
|
324
|
+
- [ ] Required custom configuration has Vite equivalents.
|
|
325
|
+
- [ ] Webpack-only dependencies and scripts are removed.
|
|
326
|
+
- [ ] Dynamic imports and former Webpack-specific import APIs are tested.
|
|
327
|
+
- [ ] Client environment variables use Vite-compatible access.
|
|
328
|
+
- [ ] Storybook uses the React Vite framework.
|
|
329
|
+
- [ ] Development, unit tests, and a clean production build pass.
|
|
330
|
+
- [ ] Production chunks, assets, favicons, sprites, and gzip files are verified.
|
|
331
|
+
|