Skip to content

Commit 36b0168

Browse files
dummdidummRich-HarrisConduitry
authored
fix: dont emit false positive export condition warning (#9109)
* fix: dont emit false positive export condition warning fixes #9097 * Update .changeset/friendly-pandas-sort.md Co-authored-by: Conduitry <[email protected]> --------- Co-authored-by: Rich Harris <[email protected]> Co-authored-by: Conduitry <[email protected]>
1 parent 04f49bd commit 36b0168

File tree

10 files changed

+203
-25
lines changed

10 files changed

+203
-25
lines changed

.changeset/friendly-pandas-sort.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/package': patch
3+
---
4+
5+
fix: don't emit false positive export condition warning

packages/package/src/validate.js

+43-18
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,46 @@
1-
import { existsSync, readFileSync } from 'node:fs';
1+
import { readFileSync } from 'node:fs';
2+
import { join } from 'node:path';
23
import colors from 'kleur';
34

45
/**
56
* @param {import("./types").Options} options
67
*/
78
export function create_validator(options) {
9+
const { analyse_code, validate } = _create_validator(options);
10+
11+
return {
12+
/**
13+
* Checks a file content for problematic imports and things like `import.meta`
14+
* @param {string} name
15+
* @param {string} content
16+
*/
17+
analyse_code(name, content) {
18+
analyse_code(name, content);
19+
},
20+
validate() {
21+
/** @type {Record<string, any>} */
22+
const pkg = JSON.parse(readFileSync(join(options.cwd, 'package.json'), 'utf-8'));
23+
const warnings = validate(pkg);
24+
// Just warnings, not errors, because
25+
// - would be annoying in watch mode (would have to restart the server)
26+
// - maybe there's a custom post-build script that fixes some of these
27+
if (warnings.length) {
28+
console.log(
29+
colors
30+
.bold()
31+
.yellow('@sveltejs/package found the following issues while packaging your library:')
32+
);
33+
for (const warning of warnings) {
34+
console.log(colors.yellow(`${warning}\n`));
35+
}
36+
}
37+
}
38+
};
39+
}
40+
/**
41+
* @param {import("./types").Options} options
42+
*/
43+
export function _create_validator(options) {
844
/** @type {Set<string>} */
945
const imports = new Set();
1046
let uses_import_meta = false;
@@ -32,9 +68,10 @@ export function create_validator(options) {
3268
}
3369
}
3470

35-
function validate() {
36-
/** @type {Record<string, any>} */
37-
const pkg = JSON.parse(readFileSync('package.json', 'utf-8'));
71+
/**
72+
* @param {Record<string, any>} pkg
73+
*/
74+
function validate(pkg) {
3875
/** @type {string[]} */
3976
const warnings = [];
4077

@@ -109,19 +146,7 @@ export function create_validator(options) {
109146
);
110147
}
111148

112-
// Just warnings, not errors, because
113-
// - would be annoying in watch mode (would have to restart the server)
114-
// - maybe there's a custom post-build script that fixes some of these
115-
if (warnings.length) {
116-
console.log(
117-
colors
118-
.bold()
119-
.yellow('@sveltejs/package found the following issues while packaging your library:')
120-
);
121-
for (const warning of warnings) {
122-
console.log(colors.yellow(`${warning}\n`));
123-
}
124-
}
149+
return warnings;
125150
}
126151

127152
return {
@@ -146,7 +171,7 @@ function traverse_exports(exports_map) {
146171
*/
147172
function traverse(exports_map, is_first_level) {
148173
for (const key of Object.keys(exports_map ?? {})) {
149-
if (is_first_level) {
174+
if (!is_first_level) {
150175
conditions.add(key);
151176
}
152177

packages/package/test/fixtures/assets/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,14 @@
22
"name": "assets",
33
"private": true,
44
"version": "1.0.0",
5-
"description": "no tampering assets"
5+
"description": "no tampering assets",
6+
"peerDependencies": {
7+
"svelte": "^3.55.0"
8+
},
9+
"exports": {
10+
".": {
11+
"types": "./dist/index.d.ts",
12+
"svelte": "./dist/index.js"
13+
}
14+
}
615
}

packages/package/test/fixtures/emitTypes-false/package.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,13 @@
33
"private": true,
44
"version": "1.0.0",
55
"description": "emitTypes settings disabled",
6-
"type": "module"
6+
"type": "module",
7+
"peerDependencies": {
8+
"svelte": "^3.55.0"
9+
},
10+
"exports": {
11+
".": {
12+
"svelte": "./dist/index.js"
13+
}
14+
}
715
}

packages/package/test/fixtures/javascript/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,14 @@
22
"name": "javascript",
33
"private": true,
44
"version": "1.0.0",
5-
"description": "standard javascript package"
5+
"description": "standard javascript package",
6+
"peerDependencies": {
7+
"svelte": "^3.55.0"
8+
},
9+
"exports": {
10+
".": {
11+
"types": "./dist/index.d.ts",
12+
"svelte": "./dist/index.js"
13+
}
14+
}
615
}

packages/package/test/fixtures/resolve-alias/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
"private": true,
44
"version": "1.0.0",
55
"description": "package using $lib alias",
6-
"type": "module"
6+
"type": "module",
7+
"peerDependencies": {
8+
"svelte": "^3.55.0"
9+
},
10+
"exports": {
11+
".": {
12+
"types": "./dist/index.d.ts",
13+
"svelte": "./dist/index.js"
14+
}
15+
}
716
}

packages/package/test/fixtures/svelte-kit/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
"private": true,
44
"version": "1.0.0",
55
"type": "module",
6-
"description": "SvelteKit library project"
6+
"description": "SvelteKit library project",
7+
"peerDependencies": {
8+
"svelte": "^3.55.0"
9+
},
10+
"exports": {
11+
".": {
12+
"types": "./dist/index.d.ts",
13+
"svelte": "./dist/index.js"
14+
}
15+
}
716
}

packages/package/test/fixtures/typescript/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
"private": true,
44
"version": "1.0.0",
55
"description": "standard typescript package",
6-
"type": "module"
6+
"type": "module",
7+
"peerDependencies": {
8+
"svelte": "^3.55.0"
9+
},
10+
"exports": {
11+
".": {
12+
"types": "./dist/index.d.ts",
13+
"svelte": "./dist/index.js"
14+
}
15+
}
716
}

packages/package/test/index.js

+86
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as assert from 'uvu/assert';
99
import { build, watch } from '../src/index.js';
1010
import { load_config } from '../src/config.js';
1111
import { rimraf, walk } from '../src/filesystem.js';
12+
import { _create_validator } from '../src/validate.js';
1213

1314
const __filename = fileURLToPath(import.meta.url);
1415
const __dirname = join(__filename, '..');
@@ -214,4 +215,89 @@ if (!process.env.CI) {
214215
});
215216
}
216217

218+
/**
219+
* @param {string[]} actual
220+
* @param {string[]} expected
221+
*/
222+
function has_warnings(actual, expected) {
223+
assert.equal(actual.length, expected.length);
224+
assert.equal(
225+
actual.filter((warning) => expected.some((str) => warning.startsWith(str))).length,
226+
expected.length
227+
);
228+
}
229+
230+
test('validates package (1)', () => {
231+
const { analyse_code, validate } = _create_validator({
232+
config: {},
233+
cwd: '',
234+
input: '',
235+
output: '',
236+
types: true
237+
});
238+
analyse_code('src/lib/index.js', 'export const a = 1;import.meta.env;');
239+
analyse_code('src/lib/C.svelte', '');
240+
const warnings = validate({});
241+
242+
has_warnings(warnings, [
243+
'No `exports` field found in `package.json`, please provide one.',
244+
'Avoid usage of `import.meta.env` in your code',
245+
'You are using Svelte components or Svelte-specific imports in your code, but you have not declared a dependency on `svelte` in your `package.json`. '
246+
]);
247+
});
248+
249+
test('validates package (2)', () => {
250+
const { analyse_code, validate } = _create_validator({
251+
config: {},
252+
cwd: '',
253+
input: '',
254+
output: '',
255+
types: true
256+
});
257+
analyse_code('src/lib/C.svelte', '');
258+
const warnings = validate({
259+
exports: { '.': './dist/C.svelte' },
260+
peerDependencies: { svelte: '^3.55.0' }
261+
});
262+
263+
has_warnings(warnings, [
264+
'You are using Svelte files, but did not declare a `svelte` condition in one of your `exports` in your `package.json`. '
265+
]);
266+
});
267+
268+
test('validates package (all ok 1)', () => {
269+
const { analyse_code, validate } = _create_validator({
270+
config: {},
271+
cwd: '',
272+
input: '',
273+
output: '',
274+
types: true
275+
});
276+
analyse_code('src/lib/C.svelte', '');
277+
const warnings = validate({
278+
exports: { '.': { svelte: './dist/C.svelte' } },
279+
peerDependencies: { svelte: '^3.55.0' }
280+
});
281+
282+
assert.equal(warnings.length, 0);
283+
});
284+
285+
test('validates package (all ok 2)', () => {
286+
const { analyse_code, validate } = _create_validator({
287+
config: {},
288+
cwd: '',
289+
input: '',
290+
output: '',
291+
types: true
292+
});
293+
analyse_code('src/lib/C.svelte', '');
294+
const warnings = validate({
295+
exports: { '.': { svelte: './dist/C.svelte' } },
296+
peerDependencies: { svelte: '^3.55.0' },
297+
svelte: './dist/C.svelte'
298+
});
299+
300+
assert.equal(warnings.length, 0);
301+
});
302+
217303
test.run();
+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
{
22
"name": "watch",
3-
"type": "module"
3+
"type": "module",
4+
"peerDependencies": {
5+
"svelte": "^3.55.0"
6+
},
7+
"exports": {
8+
".": {
9+
"types": "./dist/index.d.ts",
10+
"svelte": "./dist/index.js"
11+
}
12+
}
413
}

0 commit comments

Comments
 (0)