Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/solid-singers-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'sv': patch
---

fix(cli): `--from-playground` will create projects with `experimental.async` enabled _(if svelte version allows it)_
24 changes: 21 additions & 3 deletions packages/create/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'node:fs';
import path from 'node:path';
import * as js from '@sveltejs/cli-core/js';
import { parseJson, parseScript, parseSvelte } from '@sveltejs/cli-core/parsers';
import { isVersionUnsupportedBelow } from '@sveltejs/cli-core';

export function validatePlaygroundUrl(link: string): boolean {
try {
Expand Down Expand Up @@ -196,6 +197,16 @@ export function setupPlaygroundProject(
}
}

let experimentalAsyncNeeded = true;
const addExperimentalAsync = () => {
const svelteConfigPath = path.join(cwd, 'svelte.config.js');
const svelteConfig = fs.readFileSync(svelteConfigPath, 'utf-8');
const { ast, generateCode } = parseScript(svelteConfig);
const { value: config } = js.exports.createDefault(ast, { fallback: js.object.create({}) });
js.object.overrideProperties(config, { compilerOptions: { experimental: { async: true } } });
fs.writeFileSync(svelteConfigPath, generateCode(), 'utf-8');
};

// we want to change the svelte version, even if the user decieded
// to not install external dependencies
if (playground.svelteVersion) {
Expand All @@ -204,11 +215,18 @@ export function setupPlaygroundProject(
// from https://github.com/sveltejs/svelte.dev/blob/ba7ad256f786aa5bc67eac3a58608f3f50b59e91/packages/repl/src/lib/workers/npm.ts#L14
const pkgPrNewRegex = /^(pr|commit|branch)-(.+)/;
const match = pkgPrNewRegex.exec(playground.svelteVersion);
pkgJson.data.devDependencies['svelte'] = match
? `https://pkg.pr.new/svelte@${match[2]}`
: `^${playground.svelteVersion}`;
const version = match ? `https://pkg.pr.new/svelte@${match[2]}` : `${playground.svelteVersion}`;
pkgJson.data.devDependencies['svelte'] = version;

// if the version is a "pkg.pr.new" version, we don't need to check for support, we will use the fallback
if (!version.includes('pkg.pr.new')) {
const unsupported = isVersionUnsupportedBelow(version, '5.36');
if (unsupported) experimentalAsyncNeeded = false;
}
}

if (experimentalAsyncNeeded) addExperimentalAsync();

// only update the package.json if we made any changes
if (updatePackageJson) fs.writeFileSync(pkgPath, pkgJson.generateCode(), 'utf-8');
}
37 changes: 35 additions & 2 deletions packages/create/test/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ test('detect dependencies from playground files', () => {
expect(Array.from(dependencies.keys()).length).toBe(3);
});

test('real world download and convert playground', async () => {
test('real world download and convert playground async', async () => {
const directory = path.join(testWorkspaceDir, 'real-world-playground');
if (fs.existsSync(directory)) {
fs.rmdirSync(directory, { recursive: true });
Expand All @@ -174,5 +174,38 @@ test('real world download and convert playground', async () => {
const packageJsonPath = path.join(directory, 'package.json');
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8');
expect(packageJsonContent).toContain('"change-case": "latest"');
expect(packageJsonContent).toContain('"svelte": "^5.38.7"');
expect(packageJsonContent).toContain('"svelte": "5.38.7"');

const svelteConfigPath = path.join(directory, 'svelte.config.js');
const svelteConfigContent = fs.readFileSync(svelteConfigPath, 'utf-8');
expect(svelteConfigContent).toContain('experimental: { async: true }');
});

test('real world download and convert playground without async', async () => {
const directory = path.join(testWorkspaceDir, 'real-world-playground-old');
if (fs.existsSync(directory)) {
fs.rmdirSync(directory, { recursive: true });
}

create(directory, {
name: 'real-world-playground-old',
template: 'minimal',
types: 'typescript'
});

const playground = await downloadPlaygroundData({
playgroundId: '770bbef086034b9f8e337bab57efe8d8',
hash: undefined,
svelteVersion: '5.0.5'
});

setupPlaygroundProject(playground, directory, true);

const packageJsonPath = path.join(directory, 'package.json');
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8');
expect(packageJsonContent).toContain('"svelte": "5.0.5"');

const svelteConfigPath = path.join(directory, 'svelte.config.js');
const svelteConfigContent = fs.readFileSync(svelteConfigPath, 'utf-8');
expect(svelteConfigContent).not.toContain('experimental: { async: true }');
});
Loading