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 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 in any way.
3
+ > This is an unofficial plugin, and is not affiliated with Uniwind or Next.js.
4
4
 
5
- Next.js plugin for [Uniwind](https://uniwind.dev/) support. Note that only Webpack-based projects are supported, there are no plans to support Turbopack-based projects.
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 known differences.
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 `next` version `16.1`, but other versions will likely work fine.
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
- "@tailwindcss/postcss": {},
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.resolve.alias = {
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 { DefinePlugin, NormalModuleReplacementPlugin } from "webpack";
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniwind-plugin-next",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Compatibility plugin for using Uniwind with Next.js",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.0.3",