@astral/pack 1.9.1 → 2.0.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
@@ -20,6 +20,67 @@ yarn add @astral/utils
20
20
 
21
21
  ---
22
22
 
23
+ ## Migration Guide v1 -> v2
24
+
25
+ ### Удалено свойство `packageExports` из конфигурации
26
+
27
+ **v1**
28
+ ```js
29
+ // pack.config.js
30
+ module.exports = defineConfig({
31
+ packageExports: {
32
+ './components/Button': {
33
+ module: './components/Button/index.js',
34
+ require: './node/components/Button/index.js',
35
+ types: './components/Button/index.d.ts',
36
+ },
37
+ },
38
+ });
39
+ ```
40
+
41
+ **v2**
42
+
43
+ Теперь экспорты задаются через исходный `package.json`:
44
+ ```json
45
+ {
46
+ "exports": {
47
+ "./components/Button": "./components/Button/index.ts",
48
+ "./components/Input": "./components/Button/index.tsx"
49
+ }
50
+ }
51
+ ```
52
+
53
+ Строковые экспорты автоматически расширяются в полные объекты с учетом настроек `format` и `lang` из `pack.config.js`:
54
+ ```json
55
+ {
56
+ "exports": {
57
+ ".": {
58
+ "module": "./index.js",
59
+ "require": "./node/index.js",
60
+ "types": "./index.d.ts",
61
+ "default": "./index.js",
62
+ "import": "./index.js"
63
+ },
64
+ "./components/Button": {
65
+ "module": "./components/Button/index.js",
66
+ "require": "./node/components/Button/index.js",
67
+ "types": "./components/Button/index.d.ts",
68
+ "default": "./components/Button/index.js",
69
+ "import": "./components/Button/index.js"
70
+ },
71
+ "./components/Input": {
72
+ "module": "./components/Input/index.js",
73
+ "require": "./node/components/Input/index.js",
74
+ "types": "./components/Input/index.d.ts",
75
+ "default": "./components/Input/index.js",
76
+ "import": "./components/Input/index.js"
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ---
83
+
23
84
  ## Build
24
85
 
25
86
  `pack.config.js`
@@ -36,14 +97,6 @@ module.exports = defineConfig({
36
97
  filter: ['src/**/*.d.ts'],
37
98
  ignoreSrc: true,
38
99
  },
39
- // Добавит к root exports дополнительный
40
- packageExports: {
41
- './server': {
42
- module: './server/index.js',
43
- require: './node/server/index.js',
44
- types: './server/index.d.ts',
45
- },
46
- },
47
100
  });
48
101
  ```
49
102
 
@@ -74,27 +127,69 @@ pack create-release
74
127
  ## Exports
75
128
 
76
129
  По-дефолту добавляет exports вида:
77
- ```js
130
+ ```json
78
131
  {
79
- '.': {
80
- module: './index.js',
81
- require: './node/index.js',
82
- types: './index.d.ts'
83
- },
132
+ "exports": {
133
+ ".": {
134
+ "module": "./index.js",
135
+ "require": "./node/index.js",
136
+ "types": "./index.d.ts",
137
+ "default": "./index.js",
138
+ "import": "./index.js"
139
+ }
140
+ }
84
141
  }
85
142
  ```
86
143
 
87
- Для добавления доп. exports необходимо использовать `packageExports` в `pack.config.js`:
88
- ```js
89
- module.exports = {
90
- packageExports: {
91
- './server': {
92
- module: './server/index.js',
93
- require: './node/server/index.js',
94
- types: './server/index.d.ts',
144
+ Для добавления дополнительных exports укажите их в исходном `package.json`:
145
+ ```json
146
+ {
147
+ "exports": {
148
+ "./server": "./server/index.js",
149
+ "./components/Button": "./components/Button/index.tsx"
150
+ }
151
+ }
152
+ ```
153
+
154
+ Строковые экспорты автоматически расширяются в полные объекты с учетом настроек `format` и `lang`:
155
+ ```json
156
+ {
157
+ "exports": {
158
+ ".": {
159
+ "module": "./index.js",
160
+ "require": "./node/index.js",
161
+ "types": "./index.d.ts",
162
+ "default": "./index.js",
163
+ "import": "./index.js"
95
164
  },
96
- },
97
- };
165
+ "./server": {
166
+ "module": "./server/index.js",
167
+ "require": "./node/server/index.js",
168
+ "types": "./server/index.d.ts",
169
+ "default": "./server/index.js",
170
+ "import": "./server/index.js"
171
+ },
172
+ "./components/Button": {
173
+ "module": "./components/Button/index.js",
174
+ "require": "./node/components/Button/index.js",
175
+ "types": "./components/Button/index.d.ts",
176
+ "default": "./components/Button/index.js",
177
+ "import": "./components/Button/index.js"
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ Если нужен полный контроль, можно указать объект напрямую:
184
+ ```json
185
+ {
186
+ "exports": {
187
+ "./custom": {
188
+ "module": "./custom/special.js",
189
+ "require": "./custom/special.cjs"
190
+ }
191
+ }
192
+ }
98
193
  ```
99
194
 
100
195
  ## Настройка веток для semantic-release
@@ -39,15 +39,49 @@ const initUpdatingReleaseGroup = (config, packageVersion) => (originPackageJson)
39
39
  }, dependencies),
40
40
  };
41
41
  };
42
- const initExportsGenerator = ({ packageExports, format, lang }) => (originPackageJson) => {
43
- if (format.length === 1 && format.includes('cjs')) {
44
- const { exports, ...packageJson } = originPackageJson;
45
- return packageJson;
42
+ /**
43
+ * Преобразует строковый экспорт в полный объект экспорта
44
+ */
45
+ const expandStringExport = (value, format, lang) => {
46
+ const exportItem = {};
47
+ const jsPath = value.replace(/\.(ts|tsx|jsx)$/, '.js');
48
+ if (format.includes('esm')) {
49
+ exportItem.module = jsPath;
46
50
  }
47
- const rootExports = {};
48
- if (typeof rootExports === 'string') {
49
- return originPackageJson;
51
+ if (format.includes('cjs')) {
52
+ // Добавляем ./node/ перед путем для require
53
+ exportItem.require = jsPath.startsWith('./')
54
+ ? `./node/${jsPath.slice(2)}`
55
+ : `./node/${jsPath}`;
56
+ }
57
+ if (lang === 'ts') {
58
+ exportItem.types = jsPath.replace(/\.js$/, '.d.ts');
50
59
  }
60
+ exportItem.default = jsPath;
61
+ exportItem.import = jsPath;
62
+ return exportItem;
63
+ };
64
+ /**
65
+ * Обрабатывает и расширяет экспорты из объекта
66
+ */
67
+ const expandExportsObject = (exports, format, lang) => {
68
+ return Object.entries(exports).reduce((acc, [key, value]) => {
69
+ // Пропускаем корневой экспорт '.'
70
+ if (key === '.') {
71
+ return acc;
72
+ }
73
+ acc[key] =
74
+ typeof value === 'string'
75
+ ? expandStringExport(value, format, lang)
76
+ : value;
77
+ return acc;
78
+ }, {});
79
+ };
80
+ /**
81
+ * Создает корневой экспорт для package.json
82
+ */
83
+ const createRootExport = (format, lang) => {
84
+ const rootExports = {};
51
85
  if (format.includes('esm')) {
52
86
  rootExports.module = './index.js';
53
87
  }
@@ -59,11 +93,28 @@ const initExportsGenerator = ({ packageExports, format, lang }) => (originPackag
59
93
  }
60
94
  rootExports.default = './index.js';
61
95
  rootExports.import = './index.js';
96
+ return rootExports;
97
+ };
98
+ const initExportsGenerator = ({ format, lang }) => (originPackageJson) => {
99
+ if (format.length === 1 && format.includes('cjs')) {
100
+ const { exports, ...packageJson } = originPackageJson;
101
+ return packageJson;
102
+ }
103
+ const rootExports = createRootExport(format, lang);
104
+ if (typeof rootExports === 'string') {
105
+ return originPackageJson;
106
+ }
107
+ const originExports = originPackageJson.exports &&
108
+ typeof originPackageJson.exports === 'object' &&
109
+ !Array.isArray(originPackageJson.exports)
110
+ ? originPackageJson.exports
111
+ : {};
112
+ const expandedOriginExports = expandExportsObject(originExports, format, lang);
62
113
  return {
63
114
  ...originPackageJson,
64
115
  exports: {
65
116
  '.': rootExports,
66
- ...packageExports,
117
+ ...expandedOriginExports,
67
118
  },
68
119
  };
69
120
  };
@@ -28,7 +28,6 @@ export declare class ConfigService {
28
28
  releaseGroup?: string[];
29
29
  releaseBranches?: import("semantic-release").BranchSpec[];
30
30
  };
31
- get packageExports(): import("../types").PackageExports | undefined;
32
31
  get omitPackageJsonProps(): string[] | undefined;
33
32
  get overridePackageJson(): Record<string, unknown> | undefined;
34
33
  parseOriginPackageJson: ({ ignoreMain, }?: {
@@ -89,9 +89,6 @@ class ConfigService {
89
89
  versionsFileName: 'versions.json',
90
90
  };
91
91
  }
92
- get packageExports() {
93
- return this.config.packageExports;
94
- }
95
92
  get omitPackageJsonProps() {
96
93
  return this.config.omitPackageJsonProps;
97
94
  }
@@ -54,28 +54,6 @@ exports.validateConfig = v.object({
54
54
  prerelease: v.optional(v.or(v.string(), v.boolean())),
55
55
  }))))),
56
56
  }),
57
- packageExports: (value) => {
58
- if (!value) {
59
- return undefined;
60
- }
61
- const objectError = v.optional(v.object({}))(value);
62
- if (objectError) {
63
- return objectError;
64
- }
65
- const errors = Object.values(value)
66
- .map((exportValue) => {
67
- if (typeof exportValue === 'string') {
68
- return;
69
- }
70
- return v.object({
71
- require: v.string(),
72
- module: v.string(),
73
- types: v.string(),
74
- })(exportValue);
75
- })
76
- .filter(Boolean);
77
- return errors[0];
78
- },
79
57
  omitPackageJsonProps: v.optional(v.array(v.arrayItem(v.string()))),
80
58
  overridePackageJson: v.optional(v.object({})),
81
59
  });
package/config/types.d.ts CHANGED
@@ -70,10 +70,6 @@ export type PackConfig = {
70
70
  */
71
71
  tsConfigName?: string;
72
72
  semanticRelease: SemanticReleaseConfig;
73
- /**
74
- * exports свойство package.json
75
- */
76
- packageExports?: PackageExports;
77
73
  /**
78
74
  * Удаляет указанные props в сгенерированном package.json
79
75
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astral/pack",
3
- "version": "1.9.1",
3
+ "version": "2.0.1",
4
4
  "main": "./index.js",
5
5
  "bin": {
6
6
  "pack": "bin.js"