@foxford/tsup-config 1.0.0 → 1.0.2

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/index.cjs CHANGED
@@ -19,6 +19,18 @@ var __spreadValues = (a, b) => {
19
19
  }
20
20
  return a;
21
21
  };
22
+ var __objRest = (source, exclude) => {
23
+ var target = {};
24
+ for (var prop in source)
25
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
26
+ target[prop] = source[prop];
27
+ if (source != null && __getOwnPropSymbols)
28
+ for (var prop of __getOwnPropSymbols(source)) {
29
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
30
+ target[prop] = source[prop];
31
+ }
32
+ return target;
33
+ };
22
34
  var __export = (target, all) => {
23
35
  for (var name in all)
24
36
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -64,6 +76,7 @@ var __async = (__this, __arguments, generator) => {
64
76
  // src/index.js
65
77
  var src_exports = {};
66
78
  __export(src_exports, {
79
+ addExtensionsToRelativeImports: () => addExtensionsToRelativeImports,
67
80
  assertSourceExports: () => assertSourceExports,
68
81
  copyReadme: () => copyReadme,
69
82
  createTsupConfig: () => createTsupConfig,
@@ -141,8 +154,8 @@ function writeBuildPackageJson({ entries, extensions, main, module: moduleField,
141
154
  "files"
142
155
  ]);
143
156
  const packageJson = Object.fromEntries(Object.entries(source).filter(([field]) => !DEV_ONLY.has(field)));
144
- packageJson.main = main;
145
- packageJson.module = moduleField;
157
+ if (main !== void 0) packageJson.main = main;
158
+ if (moduleField !== void 0) packageJson.module = moduleField;
146
159
  packageJson.exports = toBuildExports(entries, { extensions });
147
160
  import_node_fs.default.writeFileSync(import_node_path.default.join(outDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}
148
161
  `);
@@ -169,9 +182,36 @@ function updateBuildFiles(outDir = "build") {
169
182
  function copyReadme(outDir = "build") {
170
183
  import_node_fs.default.copyFileSync("README.mdx", import_node_path.default.join(outDir, "README.mdx"));
171
184
  }
185
+ function addExtensionsToRelativeImports(outDir = "build") {
186
+ const RELATIVE = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+)(['"])(\.[^'"]*)\2/g;
187
+ let patched = 0;
188
+ const walk = (dir) => {
189
+ for (const entry of import_node_fs.default.readdirSync(dir, { withFileTypes: true })) {
190
+ const full = import_node_path.default.join(dir, entry.name);
191
+ if (entry.isDirectory()) {
192
+ walk(full);
193
+ continue;
194
+ }
195
+ if (!entry.name.endsWith(".js")) continue;
196
+ const source = import_node_fs.default.readFileSync(full, "utf-8");
197
+ const result = source.replace(RELATIVE, (match, prefix, quote, specifier) => {
198
+ if (/\.[cm]?jsx?$/.test(specifier)) return match;
199
+ const target = import_node_path.default.resolve(import_node_path.default.dirname(full), specifier);
200
+ const suffix = import_node_fs.default.existsSync(`${target}.js`) ? ".js" : import_node_fs.default.existsSync(import_node_path.default.join(target, "index.js")) ? "/index.js" : null;
201
+ if (suffix === null) return match;
202
+ patched += 1;
203
+ return `${prefix}${quote}${specifier}${suffix}${quote}`;
204
+ });
205
+ if (result !== source) import_node_fs.default.writeFileSync(full, result);
206
+ }
207
+ };
208
+ walk(outDir);
209
+ return patched;
210
+ }
172
211
  function createTsupConfig({ entries, overrides = {} }) {
212
+ const _a = overrides, { esbuildOptions: overrideEsbuildOptions } = _a, rest = __objRest(_a, ["esbuildOptions"]);
173
213
  const extensions = (name) => ({
174
- import: `./${name}.mjs`,
214
+ import: `./${name}.js`,
175
215
  require: `./${name}.cjs`,
176
216
  types: `./${name}.d.ts`
177
217
  });
@@ -190,26 +230,34 @@ function createTsupConfig({ entries, overrides = {} }) {
190
230
  clean: true,
191
231
  dts: true,
192
232
  entry: toTsupEntry(entries),
233
+ // JSX собираем automatic-рантаймом. Базовый tsconfig монорепо держит
234
+ // "jsx": "preserve" (его ждут Vite/Next в приложениях), но для esbuild это
235
+ // означает откат к classic-трансформу: он печатает React.createElement и НЕ
236
+ // добавляет импорт React. Исходники импортируют только хуки, поэтому в
237
+ // артефакте оставался несвязанный React → ReferenceError при первом же рендере
238
+ // (см. @foxford/den-react@1.0.1). Automatic-рантайм сам подтягивает
239
+ // react/jsx-runtime и от области видимости не зависит.
240
+ esbuildOptions: (options, context) => {
241
+ options.jsx = "automatic";
242
+ overrideEsbuildOptions == null ? void 0 : overrideEsbuildOptions(options, context);
243
+ },
193
244
  format: ["cjs", "esm"],
194
245
  onSuccess: () => __async(null, null, function* () {
195
246
  copyReadme();
196
- writeBuildPackageJson({
247
+ const root = entries["."];
248
+ writeBuildPackageJson(__spreadValues({
197
249
  entries,
198
- extensions,
199
- main: "./index.cjs",
200
- module: "./index.mjs"
201
- });
250
+ extensions
251
+ }, root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }));
202
252
  }),
203
253
  outDir: "build",
204
- // Явные расширения: при "type": "module" tsup по умолчанию отдаёт ESM как .js,
205
- // и ссылки на ./*.mjs в build/package.json оказываются битыми
206
- outExtension: ({ format }) => ({ js: format === "cjs" ? ".cjs" : ".mjs" }),
207
254
  sourcemap: false,
208
255
  splitting: false
209
- }, overrides);
256
+ }, rest);
210
257
  }
211
258
  // Annotate the CommonJS export names for ESM import in node:
212
259
  0 && (module.exports = {
260
+ addExtensionsToRelativeImports,
213
261
  assertSourceExports,
214
262
  copyReadme,
215
263
  createTsupConfig,
package/index.d.ts CHANGED
@@ -36,5 +36,11 @@ export function verifyBuildExports(outDir?: string): void
36
36
  /** Копирует README.mdx рядом с артефактом. */
37
37
  export function copyReadme(outDir?: string): void
38
38
 
39
+ /**
40
+ * Дописывает расширения в относительных импортах собранного ESM (Node их требует,
41
+ * а tsc переносит спецификаторы из исходника как есть). Возвращает число правок.
42
+ */
43
+ export function addExtensionsToRelativeImports(outDir?: string): number
44
+
39
45
  /** Готовый tsup-конфиг публикуемого пакета монорепо. */
40
46
  export function createTsupConfig(options: { entries: Entries; overrides?: Options }): Options
package/index.mjs CHANGED
@@ -14,6 +14,18 @@ var __spreadValues = (a, b) => {
14
14
  }
15
15
  return a;
16
16
  };
17
+ var __objRest = (source, exclude) => {
18
+ var target = {};
19
+ for (var prop in source)
20
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
21
+ target[prop] = source[prop];
22
+ if (source != null && __getOwnPropSymbols)
23
+ for (var prop of __getOwnPropSymbols(source)) {
24
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
25
+ target[prop] = source[prop];
26
+ }
27
+ return target;
28
+ };
17
29
  var __async = (__this, __arguments, generator) => {
18
30
  return new Promise((resolve, reject) => {
19
31
  var fulfilled = (value) => {
@@ -102,8 +114,8 @@ function writeBuildPackageJson({ entries, extensions, main, module: moduleField,
102
114
  "files"
103
115
  ]);
104
116
  const packageJson = Object.fromEntries(Object.entries(source).filter(([field]) => !DEV_ONLY.has(field)));
105
- packageJson.main = main;
106
- packageJson.module = moduleField;
117
+ if (main !== void 0) packageJson.main = main;
118
+ if (moduleField !== void 0) packageJson.module = moduleField;
107
119
  packageJson.exports = toBuildExports(entries, { extensions });
108
120
  fs.writeFileSync(path.join(outDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}
109
121
  `);
@@ -130,9 +142,36 @@ function updateBuildFiles(outDir = "build") {
130
142
  function copyReadme(outDir = "build") {
131
143
  fs.copyFileSync("README.mdx", path.join(outDir, "README.mdx"));
132
144
  }
145
+ function addExtensionsToRelativeImports(outDir = "build") {
146
+ const RELATIVE = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+)(['"])(\.[^'"]*)\2/g;
147
+ let patched = 0;
148
+ const walk = (dir) => {
149
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
150
+ const full = path.join(dir, entry.name);
151
+ if (entry.isDirectory()) {
152
+ walk(full);
153
+ continue;
154
+ }
155
+ if (!entry.name.endsWith(".js")) continue;
156
+ const source = fs.readFileSync(full, "utf-8");
157
+ const result = source.replace(RELATIVE, (match, prefix, quote, specifier) => {
158
+ if (/\.[cm]?jsx?$/.test(specifier)) return match;
159
+ const target = path.resolve(path.dirname(full), specifier);
160
+ const suffix = fs.existsSync(`${target}.js`) ? ".js" : fs.existsSync(path.join(target, "index.js")) ? "/index.js" : null;
161
+ if (suffix === null) return match;
162
+ patched += 1;
163
+ return `${prefix}${quote}${specifier}${suffix}${quote}`;
164
+ });
165
+ if (result !== source) fs.writeFileSync(full, result);
166
+ }
167
+ };
168
+ walk(outDir);
169
+ return patched;
170
+ }
133
171
  function createTsupConfig({ entries, overrides = {} }) {
172
+ const _a = overrides, { esbuildOptions: overrideEsbuildOptions } = _a, rest = __objRest(_a, ["esbuildOptions"]);
134
173
  const extensions = (name) => ({
135
- import: `./${name}.mjs`,
174
+ import: `./${name}.js`,
136
175
  require: `./${name}.cjs`,
137
176
  types: `./${name}.d.ts`
138
177
  });
@@ -151,25 +190,33 @@ function createTsupConfig({ entries, overrides = {} }) {
151
190
  clean: true,
152
191
  dts: true,
153
192
  entry: toTsupEntry(entries),
193
+ // JSX собираем automatic-рантаймом. Базовый tsconfig монорепо держит
194
+ // "jsx": "preserve" (его ждут Vite/Next в приложениях), но для esbuild это
195
+ // означает откат к classic-трансформу: он печатает React.createElement и НЕ
196
+ // добавляет импорт React. Исходники импортируют только хуки, поэтому в
197
+ // артефакте оставался несвязанный React → ReferenceError при первом же рендере
198
+ // (см. @foxford/den-react@1.0.1). Automatic-рантайм сам подтягивает
199
+ // react/jsx-runtime и от области видимости не зависит.
200
+ esbuildOptions: (options, context) => {
201
+ options.jsx = "automatic";
202
+ overrideEsbuildOptions == null ? void 0 : overrideEsbuildOptions(options, context);
203
+ },
154
204
  format: ["cjs", "esm"],
155
205
  onSuccess: () => __async(null, null, function* () {
156
206
  copyReadme();
157
- writeBuildPackageJson({
207
+ const root = entries["."];
208
+ writeBuildPackageJson(__spreadValues({
158
209
  entries,
159
- extensions,
160
- main: "./index.cjs",
161
- module: "./index.mjs"
162
- });
210
+ extensions
211
+ }, root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }));
163
212
  }),
164
213
  outDir: "build",
165
- // Явные расширения: при "type": "module" tsup по умолчанию отдаёт ESM как .js,
166
- // и ссылки на ./*.mjs в build/package.json оказываются битыми
167
- outExtension: ({ format }) => ({ js: format === "cjs" ? ".cjs" : ".mjs" }),
168
214
  sourcemap: false,
169
215
  splitting: false
170
- }, overrides);
216
+ }, rest);
171
217
  }
172
218
  export {
219
+ addExtensionsToRelativeImports,
173
220
  assertSourceExports,
174
221
  copyReadme,
175
222
  createTsupConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxford/tsup-config",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Общая сборка публикуемых пакетов: декларация точек входа, tsup-конфиг, генерация публикуемого package.json",
5
5
  "keywords": [
6
6
  "foxford",
@@ -37,6 +37,6 @@
37
37
  "index.mjs",
38
38
  "package.json"
39
39
  ],
40
- "sha": "fd3591a",
40
+ "sha": "83d658b",
41
41
  "scripts": {}
42
42
  }