uniwind-plugin-next 1.0.1 → 1.1.1
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/README.md +16 -9
- package/dist/clientDirectiveLoader.js +9 -0
- package/dist/index.cjs +9 -16
- package/dist/index.mjs +8 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# uniwind-plugin-next
|
|
2
2
|
|
|
3
|
-
> This is an unofficial plugin, and is not affiliated with Uniwind or Next.js
|
|
3
|
+
> This is an unofficial plugin, and is not affiliated with Uniwind or Next.js.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Uniwind](https://uniwind.dev/) config plugin for Next.js. Note that only Webpack-based projects are supported, there are no plans to support Turbopack-based projects.
|
|
6
6
|
|
|
7
|
-
The implementation of this plugin is based on the official [Uniwind Vite plugin](https://docs.uniwind.dev/quickstart#vite), and aims to match its functionality as closely as possible. All Uniwind features should work as expected - see the limitations section below for
|
|
7
|
+
The implementation of this plugin is based on the official [Uniwind Vite plugin](https://docs.uniwind.dev/quickstart#vite), and aims to match its functionality as closely as possible. All Uniwind features should work as expected - see the limitations section below for any documented differences.
|
|
8
8
|
|
|
9
9
|
## Compatibility
|
|
10
10
|
See the table below for tested versions of `uniwind-plugin-next` and corresponding versions of `uniwind`. Other versions of `uniwind` may work, but are not guaranteed to.
|
|
11
11
|
|
|
12
|
-
Tested on
|
|
12
|
+
Tested on Next `16.1`, but other versions will likely work fine.
|
|
13
13
|
|
|
14
14
|
| uniwind-plugin-next | Uniwind |
|
|
15
15
|
|---------------------|---------|
|
|
@@ -18,16 +18,17 @@ Tested on `next` version `16.1`, but other versions will likely work fine.
|
|
|
18
18
|
## Installation & setup
|
|
19
19
|
This setup guide assumes you already have a next.js project setup with Tailwind v4
|
|
20
20
|
|
|
21
|
-
1. Install uniwind and this plugin
|
|
21
|
+
1. Install uniwind and this plugin. You will probably also need `@expo/next-adapter` if you don't already have it, to handle react-native web support.
|
|
22
22
|
|
|
23
23
|
```shell
|
|
24
|
-
pnpm install uniwind uniwind-plugin-next
|
|
24
|
+
pnpm install uniwind uniwind-plugin-next @expo/next-adapter
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
2. Wrap next.js config with `withUniwind()`
|
|
28
28
|
```ts
|
|
29
29
|
// next.config.ts
|
|
30
30
|
import type { NextConfig } from "next";
|
|
31
|
+
import { withExpo } from "@expo/next-adapter";
|
|
31
32
|
import { withUniwind } from 'uniwind-plugin-next'
|
|
32
33
|
|
|
33
34
|
const nextConfig: NextConfig = {
|
|
@@ -35,19 +36,18 @@ const nextConfig: NextConfig = {
|
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
// Wrap your config with `withUniwind()`
|
|
38
|
-
export default withUniwind(nextConfig, {
|
|
39
|
+
export default withUniwind(withExpo(nextConfig), {
|
|
39
40
|
cssEntryFile: './app/globals.css',
|
|
40
41
|
// Takes the same options as the vite & metro plugins.
|
|
41
42
|
// See https://docs.uniwind.dev/api/metro-config#configuration-options
|
|
42
43
|
});
|
|
43
44
|
```
|
|
44
|
-
> Note that you do not need `@expo/next-adapter` if you are using `uniwind-plugin-next`.
|
|
45
45
|
|
|
46
46
|
3. Add the postcss plugin
|
|
47
47
|
```js
|
|
48
48
|
const config = {
|
|
49
49
|
plugins: {
|
|
50
|
-
|
|
50
|
+
'@tailwindcss/postcss': {},
|
|
51
51
|
'uniwind-plugin-next/postcss': {}, // Add this line
|
|
52
52
|
},
|
|
53
53
|
};
|
|
@@ -75,6 +75,13 @@ return (
|
|
|
75
75
|
|
|
76
76
|
6. Start the dev server to generate `uniwind-types.d.ts`. Make sure that it's included in your `tsconfig.json`'s `include` array.
|
|
77
77
|
|
|
78
|
+
## SSR Considerations
|
|
79
|
+
- This plugin marks all Uniwind web components with `'use client'` automatically, so you do not need to do this manually.
|
|
80
|
+
|
|
81
|
+
- Be aware that some Uniwind features, such as `withUniwind` and `useResolveClassNames` will not work in a server environment, as they rely on accessing `window` or `document`.
|
|
82
|
+
|
|
83
|
+
-
|
|
84
|
+
|
|
78
85
|
## Known limitations
|
|
79
86
|
|
|
80
87
|
- This plugin uses a much more primitive regex-based postcss plugin for transforming Uniwind CSS functions (`pixelRatio()`, `fontScale()`, `hairlineWidth()`) compared to the official Vite plugin (which uses a full AST parser). As a result, some edge cases may not be handled correctly. If you do not use these functions in your CSS, this will not impact you. If you do run into any issues, please open an issue.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export default function clientDirectiveLoader(source) {
|
|
2
|
+
console.log(this.resourcePath);
|
|
3
|
+
// Don't add the directive if it's already present
|
|
4
|
+
if (source.startsWith('"use client"') || source.startsWith("'use client'")) {
|
|
5
|
+
return source;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return `"use client";\n${source}`;
|
|
9
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
28
|
let webpack = require("webpack");
|
|
29
|
+
webpack = __toESM(webpack);
|
|
29
30
|
let path = require("path");
|
|
30
31
|
path = __toESM(path);
|
|
31
32
|
let fs = require("fs");
|
|
@@ -330,11 +331,18 @@ var UniwindWebpackPlugin = class {
|
|
|
330
331
|
options: { stringifiedThemes: stringifyThemes(this.themes) }
|
|
331
332
|
}]
|
|
332
333
|
});
|
|
334
|
+
compiler.options.module.rules.push({
|
|
335
|
+
test: /\.js$/,
|
|
336
|
+
exclude: /index\.js$/,
|
|
337
|
+
include: /uniwind[\/\\]dist[\/\\]module[\/\\]components[\/\\]web/,
|
|
338
|
+
use: [{ loader: path.default.resolve(__dirname, "clientDirectiveLoader.js") }]
|
|
339
|
+
});
|
|
333
340
|
}
|
|
334
341
|
};
|
|
335
342
|
|
|
336
343
|
//#endregion
|
|
337
344
|
//#region src/webpack/withUniwind.ts
|
|
345
|
+
const { NormalModuleReplacementPlugin } = webpack.default;
|
|
338
346
|
function withUniwind(nextConfig = {}, uniwindConfig) {
|
|
339
347
|
return {
|
|
340
348
|
...nextConfig,
|
|
@@ -345,23 +353,8 @@ function withUniwind(nextConfig = {}, uniwindConfig) {
|
|
|
345
353
|
"react-native-web"
|
|
346
354
|
]),
|
|
347
355
|
webpack(config, options) {
|
|
348
|
-
if (!config.resolve) config.resolve = {};
|
|
349
356
|
if (!config.plugins) config.plugins = [];
|
|
350
|
-
config.
|
|
351
|
-
...config.resolve.alias || {},
|
|
352
|
-
"react-native/Libraries/EventEmitter/RCTDeviceEventEmitter$": "react-native-web/dist/vendor/react-native/NativeEventEmitter/RCTDeviceEventEmitter",
|
|
353
|
-
"react-native/Libraries/vendor/emitter/EventEmitter$": "react-native-web/dist/vendor/react-native/emitter/EventEmitter",
|
|
354
|
-
"react-native/Libraries/EventEmitter/NativeEventEmitter$": "react-native-web/dist/vendor/react-native/NativeEventEmitter"
|
|
355
|
-
};
|
|
356
|
-
config.resolve.extensions = [
|
|
357
|
-
".web.js",
|
|
358
|
-
".web.jsx",
|
|
359
|
-
".web.ts",
|
|
360
|
-
".web.tsx",
|
|
361
|
-
...config.resolve?.extensions ?? []
|
|
362
|
-
];
|
|
363
|
-
config.plugins.push(new webpack.DefinePlugin({ __DEV__: JSON.stringify(process.env.NODE_ENV !== "production") }));
|
|
364
|
-
config.plugins.push(new webpack.NormalModuleReplacementPlugin(/^react-native$/, (resource) => {
|
|
357
|
+
config.plugins.push(new NormalModuleReplacementPlugin(/^react-native$/, (resource) => {
|
|
365
358
|
if ((resource.context || "").includes(`${path.default.sep}uniwind${path.default.sep}dist${path.default.sep}module${path.default.sep}components${path.default.sep}web`)) resource.request = "react-native-web";
|
|
366
359
|
else resource.request = "uniwind/components/index";
|
|
367
360
|
}));
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __require } from "./chunk-3qlvafw2.mjs";
|
|
2
|
-
import
|
|
2
|
+
import webpack from "webpack";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import { compile } from "@tailwindcss/node";
|
|
@@ -302,11 +302,18 @@ var UniwindWebpackPlugin = class {
|
|
|
302
302
|
options: { stringifiedThemes: stringifyThemes(this.themes) }
|
|
303
303
|
}]
|
|
304
304
|
});
|
|
305
|
+
compiler.options.module.rules.push({
|
|
306
|
+
test: /\.js$/,
|
|
307
|
+
exclude: /index\.js$/,
|
|
308
|
+
include: /uniwind[\/\\]dist[\/\\]module[\/\\]components[\/\\]web/,
|
|
309
|
+
use: [{ loader: path.resolve(__dirname, "clientDirectiveLoader.js") }]
|
|
310
|
+
});
|
|
305
311
|
}
|
|
306
312
|
};
|
|
307
313
|
|
|
308
314
|
//#endregion
|
|
309
315
|
//#region src/webpack/withUniwind.ts
|
|
316
|
+
const { NormalModuleReplacementPlugin } = webpack;
|
|
310
317
|
function withUniwind(nextConfig = {}, uniwindConfig) {
|
|
311
318
|
return {
|
|
312
319
|
...nextConfig,
|
|
@@ -317,22 +324,7 @@ function withUniwind(nextConfig = {}, uniwindConfig) {
|
|
|
317
324
|
"react-native-web"
|
|
318
325
|
]),
|
|
319
326
|
webpack(config, options) {
|
|
320
|
-
if (!config.resolve) config.resolve = {};
|
|
321
327
|
if (!config.plugins) config.plugins = [];
|
|
322
|
-
config.resolve.alias = {
|
|
323
|
-
...config.resolve.alias || {},
|
|
324
|
-
"react-native/Libraries/EventEmitter/RCTDeviceEventEmitter$": "react-native-web/dist/vendor/react-native/NativeEventEmitter/RCTDeviceEventEmitter",
|
|
325
|
-
"react-native/Libraries/vendor/emitter/EventEmitter$": "react-native-web/dist/vendor/react-native/emitter/EventEmitter",
|
|
326
|
-
"react-native/Libraries/EventEmitter/NativeEventEmitter$": "react-native-web/dist/vendor/react-native/NativeEventEmitter"
|
|
327
|
-
};
|
|
328
|
-
config.resolve.extensions = [
|
|
329
|
-
".web.js",
|
|
330
|
-
".web.jsx",
|
|
331
|
-
".web.ts",
|
|
332
|
-
".web.tsx",
|
|
333
|
-
...config.resolve?.extensions ?? []
|
|
334
|
-
];
|
|
335
|
-
config.plugins.push(new DefinePlugin({ __DEV__: JSON.stringify(process.env.NODE_ENV !== "production") }));
|
|
336
328
|
config.plugins.push(new NormalModuleReplacementPlugin(/^react-native$/, (resource) => {
|
|
337
329
|
if ((resource.context || "").includes(`${path.sep}uniwind${path.sep}dist${path.sep}module${path.sep}components${path.sep}web`)) resource.request = "react-native-web";
|
|
338
330
|
else resource.request = "uniwind/components/index";
|