setup-nativewind 1.1.3 → 1.2.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 +11 -8
- package/package.json +1 -1
- package/src/fileWriter.js +90 -10
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# setup-nativewind
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> CLI tool to instantly set up NativeWind v4 for Expo and React Native projects
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
|
+
|
|
6
7
|
```bash
|
|
7
8
|
npx setup-nativewind
|
|
8
9
|
```
|
|
@@ -10,18 +11,20 @@ npx setup-nativewind
|
|
|
10
11
|
## What it does
|
|
11
12
|
|
|
12
13
|
- ✅ Auto detects your project type (Expo managed, Expo bare, React Native CLI)
|
|
13
|
-
- ✅
|
|
14
|
+
- ✅ Asks if your project is JavaScript or TypeScript
|
|
14
15
|
- ✅ Installs `nativewind` and `tailwindcss` automatically
|
|
15
16
|
- ✅ Creates all required config files
|
|
17
|
+
- ✅ Smart merges existing `babel.config.js` and `metro.config.js`
|
|
16
18
|
- ✅ Creates `nativewind-env.d.ts` for TypeScript projects
|
|
19
|
+
- ✅ Auto updates `tsconfig.json` for TypeScript projects
|
|
17
20
|
|
|
18
21
|
## Supported Project Types
|
|
19
22
|
|
|
20
|
-
| Project Type
|
|
21
|
-
|
|
22
|
-
| Expo Managed
|
|
23
|
-
| Expo Bare
|
|
24
|
-
| React Native CLI | ✅
|
|
23
|
+
| Project Type | JavaScript | TypeScript |
|
|
24
|
+
| ---------------- | ---------- | ---------- |
|
|
25
|
+
| Expo Managed | ✅ | ✅ |
|
|
26
|
+
| Expo Bare | ✅ | ✅ |
|
|
27
|
+
| React Native CLI | ✅ | ✅ |
|
|
25
28
|
|
|
26
29
|
## Requirements
|
|
27
30
|
|
|
@@ -30,4 +33,4 @@ npx setup-nativewind
|
|
|
30
33
|
|
|
31
34
|
## License
|
|
32
35
|
|
|
33
|
-
MIT
|
|
36
|
+
MIT
|
package/package.json
CHANGED
package/src/fileWriter.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
import { fileURLToPath } from
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
4
|
|
|
5
5
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
6
|
|
|
7
7
|
export async function writeConfigFiles(projectType) {
|
|
8
|
-
const templateDir = path.join(__dirname,
|
|
8
|
+
const templateDir = path.join(__dirname, "templates", projectType);
|
|
9
9
|
const targetDir = process.cwd();
|
|
10
10
|
const files = fs.readdirSync(templateDir);
|
|
11
11
|
|
|
@@ -14,6 +14,18 @@ export async function writeConfigFiles(projectType) {
|
|
|
14
14
|
const dest = path.join(targetDir, file);
|
|
15
15
|
|
|
16
16
|
if (fs.existsSync(dest)) {
|
|
17
|
+
// Smart merge for babel.config.js
|
|
18
|
+
if (file === "babel.config.js") {
|
|
19
|
+
await mergeBabelConfig(dest, projectType);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Smart merge for metro.config.js
|
|
24
|
+
if (file === "metro.config.js") {
|
|
25
|
+
await mergeMetroConfig(dest, projectType);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
console.log(`⚠️ Skipping ${file} — already exists`);
|
|
18
30
|
continue;
|
|
19
31
|
}
|
|
@@ -23,13 +35,81 @@ export async function writeConfigFiles(projectType) {
|
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
// For TS projects update tsconfig.json automatically
|
|
26
|
-
if (projectType.includes(
|
|
38
|
+
if (projectType.includes("ts")) {
|
|
27
39
|
await updateTsConfig(targetDir);
|
|
28
40
|
}
|
|
29
41
|
}
|
|
30
42
|
|
|
43
|
+
async function mergeBabelConfig(destPath, projectType) {
|
|
44
|
+
const content = fs.readFileSync(destPath, "utf8");
|
|
45
|
+
|
|
46
|
+
// Already has nativewind config
|
|
47
|
+
if (content.includes("nativewind")) {
|
|
48
|
+
console.log("⚠️ Skipping babel.config.js — already has NativeWind config");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let updated;
|
|
53
|
+
|
|
54
|
+
if (projectType.includes("expo")) {
|
|
55
|
+
// Expo babel config
|
|
56
|
+
updated = content.replace(
|
|
57
|
+
/presets:\s*\[/,
|
|
58
|
+
`presets: [\n ["babel-preset-expo", { jsxImportSource: "nativewind" }],\n "nativewind/babel",`,
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
// RN CLI babel config
|
|
62
|
+
updated = content.replace(
|
|
63
|
+
/plugins:\s*\[/,
|
|
64
|
+
`plugins: [\n "nativewind/babel",`,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// If no plugins array exists add it
|
|
68
|
+
if (!content.includes("plugins")) {
|
|
69
|
+
updated = content.replace(
|
|
70
|
+
/presets:\s*\[([^\]]*)\]/,
|
|
71
|
+
`presets: [$1],\n plugins: ["nativewind/babel"]`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fs.writeFileSync(destPath, updated, "utf8");
|
|
77
|
+
console.log("✅ Updated babel.config.js");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function mergeMetroConfig(destPath, projectType) {
|
|
81
|
+
const content = fs.readFileSync(destPath, "utf8");
|
|
82
|
+
|
|
83
|
+
// Already has nativewind config
|
|
84
|
+
if (content.includes("nativewind")) {
|
|
85
|
+
console.log("⚠️ Skipping metro.config.js — already has NativeWind config");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let updated;
|
|
90
|
+
|
|
91
|
+
if (projectType.includes("expo")) {
|
|
92
|
+
// Expo metro config
|
|
93
|
+
updated = `const { getDefaultConfig } = require("expo/metro-config");\nconst { withNativeWind } = require("nativewind/metro");\n\nconst config = getDefaultConfig(__dirname);\n\nmodule.exports = withNativeWind(config, { input: "./global.css" });\n`;
|
|
94
|
+
} else {
|
|
95
|
+
// RN CLI metro config — add withNativeWind import and wrap export
|
|
96
|
+
updated = content
|
|
97
|
+
.replace(
|
|
98
|
+
/const\s*\{\s*getDefaultConfig,\s*mergeConfig\s*\}\s*=\s*require\(['"]@react-native\/metro-config['"]\);/,
|
|
99
|
+
`const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");\nconst { withNativeWind } = require("nativewind/metro");`,
|
|
100
|
+
)
|
|
101
|
+
.replace(
|
|
102
|
+
/module\.exports\s*=\s*mergeConfig\(([^;]+)\);/s, // ← fixed: [^;]+ with s flag
|
|
103
|
+
`const mergedConfig = mergeConfig($1);\nmodule.exports = withNativeWind(mergedConfig, { input: "./global.css" });`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
fs.writeFileSync(destPath, updated, "utf8");
|
|
108
|
+
console.log("✅ Updated metro.config.js");
|
|
109
|
+
}
|
|
110
|
+
|
|
31
111
|
async function updateTsConfig(targetDir) {
|
|
32
|
-
const tsconfigPath = path.join(targetDir,
|
|
112
|
+
const tsconfigPath = path.join(targetDir, "tsconfig.json");
|
|
33
113
|
|
|
34
114
|
if (!fs.existsSync(tsconfigPath)) return;
|
|
35
115
|
|
|
@@ -39,9 +119,9 @@ async function updateTsConfig(targetDir) {
|
|
|
39
119
|
tsconfig.include = [];
|
|
40
120
|
}
|
|
41
121
|
|
|
42
|
-
if (!tsconfig.include.includes(
|
|
43
|
-
tsconfig.include.push(
|
|
122
|
+
if (!tsconfig.include.includes("nativewind-env.d.ts")) {
|
|
123
|
+
tsconfig.include.push("nativewind-env.d.ts");
|
|
44
124
|
fs.writeJsonSync(tsconfigPath, tsconfig, { spaces: 2 });
|
|
45
|
-
console.log(
|
|
125
|
+
console.log("✅ Updated tsconfig.json");
|
|
46
126
|
}
|
|
47
|
-
}
|
|
127
|
+
}
|