@foxford/tsup-config 1.0.1 → 1.1.0

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.mdx CHANGED
@@ -47,12 +47,18 @@ export default defineConfig(
47
47
  ## Что делает сборка
48
48
 
49
49
  1. `entry` для tsup — из декларации;
50
- 2. ESM → `.mjs`, CJS → `.cjs` (явно, иначе при `"type": "module"` ESM уходит в `.js`);
50
+ 2. ESM → `.js`, CJS → `.cjs` для пакетов с `"type": "module"`;
51
51
  3. `build/package.json`: метаданные без dev-полей, `exports` внутрь артефакта,
52
52
  `files` — по фактическому содержимому `build/`;
53
53
  4. падает, если объявленного подпути нет в `exports` исходного package.json,
54
54
  если `exports` ведёт не на исходник, или если файла из `exports` нет в `build/`.
55
55
 
56
+ Синтаксис пакетного выхода понижается до production-целей `@foxford/browserslist-config/build` для ESM-приложений. Окружение выбрано явно: `NODE_ENV=test` или dev-режим команды не меняют публикуемый код. Пакеты, исполняемые только в Node, задают `overrides: { target: 'node18' }`; сам `tsup-config` также собирается для Node 18.
57
+
58
+ Пакетная сборка не добавляет глобальные полифиллы. Итоговый сборщик приложения обрабатывает код вместе с зависимостями и подключает нужные API. У `den-preact` в промежуточном ESM сохраняются `import.meta` и optional chaining: они нужны сборщику потребителя для удаления серверного рендера из браузерного выхода.
59
+
60
+ Для старых Safari профиль применяет тот же обход destructuring, что и Vite 7: esbuild сохраняет этот синтаксис. Это позволяет собрать код, но не исправляет известный баг движка в отдельных операциях с array rest. Условие обхода и ограничение описаны в [пакете браузерных целей](https://github.com/foxford/frontend-platform/blob/main/packages/browserslist-config/README.mdx).
61
+
56
62
  ## Пакеты со своей сборкой
57
63
 
58
64
  `@foxford/den-vike` собирается `tsc`, а не tsup: его vike-хуки связаны импортами
package/index.cjs CHANGED
@@ -3,22 +3,8 @@ var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
6
  var __getProtoOf = Object.getPrototypeOf;
8
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
8
  var __export = (target, all) => {
23
9
  for (var name in all)
24
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -40,26 +26,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
40
26
  mod
41
27
  ));
42
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
43
- var __async = (__this, __arguments, generator) => {
44
- return new Promise((resolve, reject) => {
45
- var fulfilled = (value) => {
46
- try {
47
- step(generator.next(value));
48
- } catch (e) {
49
- reject(e);
50
- }
51
- };
52
- var rejected = (value) => {
53
- try {
54
- step(generator.throw(value));
55
- } catch (e) {
56
- reject(e);
57
- }
58
- };
59
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
60
- step((generator = generator.apply(__this, __arguments)).next());
61
- });
62
- };
63
29
 
64
30
  // src/index.js
65
31
  var src_exports = {};
@@ -78,6 +44,7 @@ __export(src_exports, {
78
44
  module.exports = __toCommonJS(src_exports);
79
45
  var import_node_fs = __toESM(require("fs"), 1);
80
46
  var import_node_path = __toESM(require("path"), 1);
47
+ var import_build = require("@foxford/browserslist-config/build");
81
48
  function defineEntries(map) {
82
49
  for (const [subpath, source] of Object.entries(map)) {
83
50
  if (!subpath.startsWith(".")) {
@@ -97,9 +64,8 @@ function toTsupEntry(entries) {
97
64
  return Object.fromEntries(Object.entries(entries).map(([subpath, source]) => [artifactName(subpath, source), source]));
98
65
  }
99
66
  function assertSourceExports(entries, packageJson) {
100
- var _a;
101
67
  const declared = new Set(Object.keys(entries));
102
- const actual = new Set(Object.keys((_a = packageJson.exports) != null ? _a : {}).filter((key) => !key.endsWith(".mdx")));
68
+ const actual = new Set(Object.keys(packageJson.exports ?? {}).filter((key) => !key.endsWith(".mdx")));
103
69
  const missing = [...declared].filter((key) => !actual.has(key));
104
70
  const extra = [...actual].filter((key) => !declared.has(key));
105
71
  if (missing.length > 0 || extra.length > 0) {
@@ -124,7 +90,7 @@ function toBuildExports(entries, { extensions }) {
124
90
  return Object.fromEntries(
125
91
  Object.entries(entries).map(([subpath, source]) => {
126
92
  const name = artifactName(subpath, source);
127
- return [subpath, __spreadValues({}, extensions(name))];
93
+ return [subpath, { ...extensions(name) }];
128
94
  })
129
95
  );
130
96
  }
@@ -149,9 +115,8 @@ function writeBuildPackageJson({ entries, extensions, main, module: moduleField,
149
115
  `);
150
116
  }
151
117
  function verifyBuildExports(outDir = "build") {
152
- var _a;
153
118
  const packageJson = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(outDir, "package.json"), "utf-8"));
154
- const missing = Object.values((_a = packageJson.exports) != null ? _a : {}).flatMap((entry) => typeof entry === "string" ? [entry] : Object.values(entry)).filter((file) => !import_node_fs.default.existsSync(import_node_path.default.join(outDir, file)));
119
+ const missing = Object.values(packageJson.exports ?? {}).flatMap((entry) => typeof entry === "string" ? [entry] : Object.values(entry)).filter((file) => !import_node_fs.default.existsSync(import_node_path.default.join(outDir, file)));
155
120
  if (missing.length > 0) {
156
121
  throw new Error(`\u0432 ${outDir}/ \u043D\u0435\u0442 \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043B\u044F exports: ${[...new Set(missing)].join(", ")}`);
157
122
  }
@@ -197,11 +162,9 @@ function addExtensionsToRelativeImports(outDir = "build") {
197
162
  return patched;
198
163
  }
199
164
  function createTsupConfig({ entries, overrides = {} }) {
200
- const extensions = (name) => ({
201
- import: `./${name}.js`,
202
- require: `./${name}.cjs`,
203
- types: `./${name}.d.ts`
204
- });
165
+ const { esbuildOptions: overrideEsbuildOptions, target, ...rest } = overrides;
166
+ const browserProfile = target === void 0 ? (0, import_build.resolveBrowserBuild)({ env: "production" }) : void 0;
167
+ const extensions = (name) => ({ import: `./${name}.js`, require: `./${name}.cjs`, types: `./${name}.d.ts` });
205
168
  process.on("beforeExit", (code) => {
206
169
  if (code !== 0) return;
207
170
  updateBuildFiles();
@@ -212,24 +175,45 @@ function createTsupConfig({ entries, overrides = {} }) {
212
175
  process.exitCode = 1;
213
176
  }
214
177
  });
215
- return __spreadValues({
178
+ return {
216
179
  bundle: true,
217
180
  clean: true,
218
181
  dts: true,
219
182
  entry: toTsupEntry(entries),
183
+ // JSX собираем automatic-рантаймом. Базовый tsconfig монорепо держит
184
+ // "jsx": "preserve" (его ждут Vite/Next в приложениях), но для esbuild это
185
+ // означает откат к classic-трансформу: он печатает React.createElement и НЕ
186
+ // добавляет импорт React. Исходники импортируют только хуки, поэтому в
187
+ // артефакте оставался несвязанный React → ReferenceError при первом же рендере
188
+ // (см. @foxford/den-react@1.0.1). Automatic-рантайм сам подтягивает
189
+ // react/jsx-runtime и от области видимости не зависит.
190
+ esbuildOptions: (options, context) => {
191
+ options.jsx = "automatic";
192
+ if (browserProfile) {
193
+ options.supported = { ...options.supported, ...browserProfile.esbuildSupported };
194
+ }
195
+ overrideEsbuildOptions?.(options, context);
196
+ },
220
197
  format: ["cjs", "esm"],
221
- onSuccess: () => __async(null, null, function* () {
198
+ onSuccess: async () => {
222
199
  copyReadme();
223
200
  const root = entries["."];
224
- writeBuildPackageJson(__spreadValues({
201
+ writeBuildPackageJson({
225
202
  entries,
226
- extensions
227
- }, root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }));
228
- }),
203
+ extensions,
204
+ ...root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }
205
+ });
206
+ },
229
207
  outDir: "build",
230
208
  sourcemap: false,
231
- splitting: false
232
- }, overrides);
209
+ splitting: false,
210
+ // Пакетный выход ещё пересобирает приложение: здесь понижается синтаксис,
211
+ // а полифиллы и совместимость всех зависимостей проверяет финальная сборка.
212
+ target: target ?? browserProfile?.targets,
213
+ // Хук уже дополнен jsx: 'automatic', а undefined target не должен отменять
214
+ // общую браузерную цель — обе опции исключены из спреда.
215
+ ...rest
216
+ };
233
217
  }
234
218
  // Annotate the CommonJS export names for ESM import in node:
235
219
  0 && (module.exports = {
package/index.d.ts CHANGED
@@ -42,5 +42,9 @@ export function copyReadme(outDir?: string): void
42
42
  */
43
43
  export function addExtensionsToRelativeImports(outDir?: string): number
44
44
 
45
- /** Готовый tsup-конфиг публикуемого пакета монорепо. */
45
+ /**
46
+ * Готовый tsup-конфиг публикуемого пакета монорепо.
47
+ * По умолчанию — production-цели @foxford/browserslist-config для ESM-приложений.
48
+ * Пакеты для Node задают overrides.target; полифиллы добавляет сборка приложения.
49
+ */
46
50
  export function createTsupConfig(options: { entries: Entries; overrides?: Options }): Options
package/index.mjs CHANGED
@@ -1,43 +1,7 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
- var __async = (__this, __arguments, generator) => {
18
- return new Promise((resolve, reject) => {
19
- var fulfilled = (value) => {
20
- try {
21
- step(generator.next(value));
22
- } catch (e) {
23
- reject(e);
24
- }
25
- };
26
- var rejected = (value) => {
27
- try {
28
- step(generator.throw(value));
29
- } catch (e) {
30
- reject(e);
31
- }
32
- };
33
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
34
- step((generator = generator.apply(__this, __arguments)).next());
35
- });
36
- };
37
-
38
1
  // src/index.js
39
2
  import fs from "fs";
40
3
  import path from "path";
4
+ import { resolveBrowserBuild } from "@foxford/browserslist-config/build";
41
5
  function defineEntries(map) {
42
6
  for (const [subpath, source] of Object.entries(map)) {
43
7
  if (!subpath.startsWith(".")) {
@@ -57,9 +21,8 @@ function toTsupEntry(entries) {
57
21
  return Object.fromEntries(Object.entries(entries).map(([subpath, source]) => [artifactName(subpath, source), source]));
58
22
  }
59
23
  function assertSourceExports(entries, packageJson) {
60
- var _a;
61
24
  const declared = new Set(Object.keys(entries));
62
- const actual = new Set(Object.keys((_a = packageJson.exports) != null ? _a : {}).filter((key) => !key.endsWith(".mdx")));
25
+ const actual = new Set(Object.keys(packageJson.exports ?? {}).filter((key) => !key.endsWith(".mdx")));
63
26
  const missing = [...declared].filter((key) => !actual.has(key));
64
27
  const extra = [...actual].filter((key) => !declared.has(key));
65
28
  if (missing.length > 0 || extra.length > 0) {
@@ -84,7 +47,7 @@ function toBuildExports(entries, { extensions }) {
84
47
  return Object.fromEntries(
85
48
  Object.entries(entries).map(([subpath, source]) => {
86
49
  const name = artifactName(subpath, source);
87
- return [subpath, __spreadValues({}, extensions(name))];
50
+ return [subpath, { ...extensions(name) }];
88
51
  })
89
52
  );
90
53
  }
@@ -109,9 +72,8 @@ function writeBuildPackageJson({ entries, extensions, main, module: moduleField,
109
72
  `);
110
73
  }
111
74
  function verifyBuildExports(outDir = "build") {
112
- var _a;
113
75
  const packageJson = JSON.parse(fs.readFileSync(path.join(outDir, "package.json"), "utf-8"));
114
- const missing = Object.values((_a = packageJson.exports) != null ? _a : {}).flatMap((entry) => typeof entry === "string" ? [entry] : Object.values(entry)).filter((file) => !fs.existsSync(path.join(outDir, file)));
76
+ const missing = Object.values(packageJson.exports ?? {}).flatMap((entry) => typeof entry === "string" ? [entry] : Object.values(entry)).filter((file) => !fs.existsSync(path.join(outDir, file)));
115
77
  if (missing.length > 0) {
116
78
  throw new Error(`\u0432 ${outDir}/ \u043D\u0435\u0442 \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043B\u044F exports: ${[...new Set(missing)].join(", ")}`);
117
79
  }
@@ -157,11 +119,9 @@ function addExtensionsToRelativeImports(outDir = "build") {
157
119
  return patched;
158
120
  }
159
121
  function createTsupConfig({ entries, overrides = {} }) {
160
- const extensions = (name) => ({
161
- import: `./${name}.js`,
162
- require: `./${name}.cjs`,
163
- types: `./${name}.d.ts`
164
- });
122
+ const { esbuildOptions: overrideEsbuildOptions, target, ...rest } = overrides;
123
+ const browserProfile = target === void 0 ? resolveBrowserBuild({ env: "production" }) : void 0;
124
+ const extensions = (name) => ({ import: `./${name}.js`, require: `./${name}.cjs`, types: `./${name}.d.ts` });
165
125
  process.on("beforeExit", (code) => {
166
126
  if (code !== 0) return;
167
127
  updateBuildFiles();
@@ -172,24 +132,45 @@ function createTsupConfig({ entries, overrides = {} }) {
172
132
  process.exitCode = 1;
173
133
  }
174
134
  });
175
- return __spreadValues({
135
+ return {
176
136
  bundle: true,
177
137
  clean: true,
178
138
  dts: true,
179
139
  entry: toTsupEntry(entries),
140
+ // JSX собираем automatic-рантаймом. Базовый tsconfig монорепо держит
141
+ // "jsx": "preserve" (его ждут Vite/Next в приложениях), но для esbuild это
142
+ // означает откат к classic-трансформу: он печатает React.createElement и НЕ
143
+ // добавляет импорт React. Исходники импортируют только хуки, поэтому в
144
+ // артефакте оставался несвязанный React → ReferenceError при первом же рендере
145
+ // (см. @foxford/den-react@1.0.1). Automatic-рантайм сам подтягивает
146
+ // react/jsx-runtime и от области видимости не зависит.
147
+ esbuildOptions: (options, context) => {
148
+ options.jsx = "automatic";
149
+ if (browserProfile) {
150
+ options.supported = { ...options.supported, ...browserProfile.esbuildSupported };
151
+ }
152
+ overrideEsbuildOptions?.(options, context);
153
+ },
180
154
  format: ["cjs", "esm"],
181
- onSuccess: () => __async(null, null, function* () {
155
+ onSuccess: async () => {
182
156
  copyReadme();
183
157
  const root = entries["."];
184
- writeBuildPackageJson(__spreadValues({
158
+ writeBuildPackageJson({
185
159
  entries,
186
- extensions
187
- }, root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }));
188
- }),
160
+ extensions,
161
+ ...root === void 0 ? {} : { main: extensions(artifactName(".", root)).require, module: extensions(artifactName(".", root)).import }
162
+ });
163
+ },
189
164
  outDir: "build",
190
165
  sourcemap: false,
191
- splitting: false
192
- }, overrides);
166
+ splitting: false,
167
+ // Пакетный выход ещё пересобирает приложение: здесь понижается синтаксис,
168
+ // а полифиллы и совместимость всех зависимостей проверяет финальная сборка.
169
+ target: target ?? browserProfile?.targets,
170
+ // Хук уже дополнен jsx: 'automatic', а undefined target не должен отменять
171
+ // общую браузерную цель — обе опции исключены из спреда.
172
+ ...rest
173
+ };
193
174
  }
194
175
  export {
195
176
  addExtensionsToRelativeImports,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxford/tsup-config",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Общая сборка публикуемых пакетов: декларация точек входа, tsup-конфиг, генерация публикуемого package.json",
5
5
  "keywords": [
6
6
  "foxford",
@@ -8,6 +8,13 @@
8
8
  "build",
9
9
  "config"
10
10
  ],
11
+ "homepage": "https://github.com/foxford/frontend-platform",
12
+ "bugs": "https://github.com/foxford/frontend-platform/issues",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/foxford/frontend-platform.git",
16
+ "directory": "packages/tsup-config"
17
+ },
11
18
  "license": "MIT",
12
19
  "author": "Foxford Co",
13
20
  "maintainers": [
@@ -18,6 +25,9 @@
18
25
  }
19
26
  ],
20
27
  "type": "module",
28
+ "dependencies": {
29
+ "@foxford/browserslist-config": "^1.2.0"
30
+ },
21
31
  "peerDependencies": {
22
32
  "tsup": "*"
23
33
  },
@@ -37,6 +47,6 @@
37
47
  "index.mjs",
38
48
  "package.json"
39
49
  ],
40
- "sha": "d0aa793",
50
+ "sha": "6bf9ff8",
41
51
  "scripts": {}
42
52
  }