diff --git a/.changeset/brown-bears-retire-adapters.md b/.changeset/brown-bears-retire-adapters.md new file mode 100644 index 000000000000..5b03c0f3415d --- /dev/null +++ b/.changeset/brown-bears-retire-adapters.md @@ -0,0 +1,9 @@ +--- +'@sveltejs/adapter-node': patch +'@sveltejs/adapter-static': patch +'@sveltejs/adapter-cloudflare': patch +'@sveltejs/adapter-netlify': patch +'@sveltejs/adapter-vercel': patch +--- + +chore: use `node:fs` instead of deprecated `builder.rimraf` and `builder.mkdirp` diff --git a/.changeset/brown-bears-retire.md b/.changeset/brown-bears-retire.md new file mode 100644 index 000000000000..600c035e7b09 --- /dev/null +++ b/.changeset/brown-bears-retire.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +chore: deprecate `builder.rimraf` and `builder.mkdirp` in favour of `node:fs` methods diff --git a/.changeset/package-fs-helpers.md b/.changeset/package-fs-helpers.md new file mode 100644 index 000000000000..5b2e03cd03c1 --- /dev/null +++ b/.changeset/package-fs-helpers.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/package': patch +--- + +chore: replace private fs helpers with Node built-ins diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index c39f57e61521..185c964ceafc 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -1,4 +1,4 @@ -import { copyFileSync, existsSync, readFileSync, writeFileSync } from 'node:fs'; +import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; @@ -72,15 +72,15 @@ export default function (options = {}) { const files = fileURLToPath(new URL('./files', import.meta.url).href); const tmp = builder.getBuildDirectory('cloudflare-tmp'); - builder.rimraf(dest); - builder.rimraf(worker_dest); + rmSync(dest, { force: true, recursive: true }); + rmSync(worker_dest, { force: true, recursive: true }); - builder.mkdirp(dest); - builder.mkdirp(tmp); + mkdirSync(dest, { recursive: true }); + mkdirSync(tmp, { recursive: true }); // client assets and prerendered pages const assets_dest = `${dest}${builder.config.kit.paths.base}`; - builder.mkdirp(assets_dest); + mkdirSync(assets_dest, { recursive: true }); if ( building_for_cloudflare_pages || wrangler_config.assets?.not_found_handling === '404-page' diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js index 2c1355b42425..8e893a94a7a0 100644 --- a/packages/adapter-netlify/index.js +++ b/packages/adapter-netlify/index.js @@ -1,4 +1,4 @@ -import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { join, posix } from 'node:path'; import { fileURLToPath } from 'node:url'; import { builtinModules } from 'node:module'; @@ -60,19 +60,19 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) { const publish = get_publish_directory(netlify_config, builder) || 'build'; // empty out existing build directories - builder.rimraf(publish); - builder.rimraf('.netlify/v1'); + rmSync(publish, { force: true, recursive: true }); + rmSync('.netlify/v1', { force: true, recursive: true }); // clean up legacy directories from older adapter versions to avoid // gnarly edge cases when an existing project is upgraded to this version - builder.rimraf('.netlify/edge-functions'); - builder.rimraf('.netlify/server'); - builder.rimraf('.netlify/package.json'); - builder.rimraf('.netlify/serverless.js'); + rmSync('.netlify/edge-functions', { force: true, recursive: true }); + rmSync('.netlify/server', { force: true, recursive: true }); + rmSync('.netlify/package.json', { force: true, recursive: true }); + rmSync('.netlify/serverless.js', { force: true, recursive: true }); if (existsSync('.netlify/functions-internal')) { for (const file of readdirSync('.netlify/functions-internal')) { if (file.startsWith(FUNCTION_PREFIX)) { - builder.rimraf(join('.netlify/functions-internal', file)); + rmSync(join('.netlify/functions-internal', file), { force: true, recursive: true }); } } } @@ -118,7 +118,7 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) { */ function generate_serverless_functions({ builder, publish, split }) { // https://docs.netlify.com/build/frameworks/frameworks-api/#netlifyv1functions - builder.mkdirp(netlify_framework_serverless_path); + mkdirSync(netlify_framework_serverless_path, { recursive: true }); builder.writeServer('.netlify/v1/server'); @@ -243,7 +243,7 @@ function write_frameworks_config({ builder }) { ] }; - builder.mkdirp('.netlify/v1'); + mkdirSync('.netlify/v1', { recursive: true }); writeFileSync(netlify_framework_config_path, s(config)); } @@ -354,11 +354,11 @@ const rolldown_config = { */ async function generate_edge_functions({ builder }) { const tmp = builder.getBuildDirectory('netlify-tmp'); - builder.rimraf(tmp); - builder.mkdirp(tmp); + rmSync(tmp, { force: true, recursive: true }); + mkdirSync(tmp, { recursive: true }); // https://docs.netlify.com/build/frameworks/frameworks-api/#edge-functions - builder.mkdirp('.netlify/v1/edge-functions'); + mkdirSync('.netlify/v1/edge-functions', { recursive: true }); builder.log.minor('Generating Edge Function...'); const relativePath = posix.relative(tmp, builder.getServerDirectory()); diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index dd26779b9380..62fb04a64e5a 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -1,4 +1,4 @@ -import { readFileSync, writeFileSync } from 'node:fs'; +import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { extname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { rolldown } from 'rolldown'; @@ -19,9 +19,9 @@ export default function (opts = {}) { async adapt(builder) { const tmp = builder.getBuildDirectory('adapter-node'); - builder.rimraf(out); - builder.rimraf(tmp); - builder.mkdirp(tmp); + rmSync(out, { force: true, recursive: true }); + rmSync(tmp, { force: true, recursive: true }); + mkdirSync(tmp, { recursive: true }); builder.log.minor('Copying assets'); const written = [ diff --git a/packages/adapter-static/index.js b/packages/adapter-static/index.js index a1d65f277019..f6c0b5a450c4 100644 --- a/packages/adapter-static/index.js +++ b/packages/adapter-static/index.js @@ -1,3 +1,4 @@ +import { rmSync } from 'node:fs'; import path from 'node:path'; import { platforms } from './platforms.js'; @@ -72,8 +73,8 @@ ${dynamic_routes.map((route) => ` - ${path.posix.join(prefix, route.id)}`).join precompress } = options ?? platform?.defaults ?? /** @type {import('./index.js').AdapterOptions} */ ({}); - builder.rimraf(assets); - builder.rimraf(pages); + rmSync(assets, { force: true, recursive: true }); + rmSync(pages, { force: true, recursive: true }); builder.generateEnvModule(); builder.writeClient(assets); diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 13875c7e8187..4f1590665282 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -22,8 +22,8 @@ const plugin = function (defaults = {}) { const dir = '.vercel/output'; const tmp = builder.getBuildDirectory('vercel-tmp'); - builder.rimraf(dir); - builder.rimraf(tmp); + fs.rmSync(dir, { force: true, recursive: true }); + fs.rmSync(tmp, { force: true, recursive: true }); if (fs.existsSync('vercel.json')) { const vercel_file = fs.readFileSync('vercel.json', 'utf-8'); @@ -215,7 +215,7 @@ const plugin = function (defaults = {}) { const target = path.join(dirs.functions, INTERNAL, 'catchall.func'); // Ensure the parent directory exists before symlinking - builder.mkdirp(path.join(dirs.functions, app_path)); + fs.mkdirSync(path.join(dirs.functions, app_path), { recursive: true }); const relative = path.relative(path.dirname(remote_symlink_path), target); @@ -238,7 +238,7 @@ const plugin = function (defaults = {}) { if (isr) { const isr_name = route.id.slice(1) || '__root__'; // should we check that __root__ isn't a route? const base = `${dirs.functions}/${isr_name}`; - builder.mkdirp(base); + fs.mkdirSync(base, { recursive: true }); const target = `${dirs.functions}/${name}.func`; const relative = path.relative(path.dirname(base), target); @@ -289,7 +289,7 @@ const plugin = function (defaults = {}) { const target = path.join(dirs.functions, `${name}.func`); // The actual function directory e.g., .vercel/output/functions/![-].func // Ensure the directory for the data endpoint symlink exists (e.g., functions/index/) - builder.mkdirp(base_dir); + fs.mkdirSync(base_dir, { recursive: true }); // Calculate relative paths FROM the directory containing the symlink TO the target const relative_for_main = path.relative(path.dirname(main_symlink_path), target); diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index 29acc4c30780..4d0f42254cee 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -5,12 +5,19 @@ /** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger, RemoteChunk } from 'types' */ import { loadEnv } from 'vite'; import * as devalue from 'devalue'; -import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs'; +import { + createReadStream, + createWriteStream, + existsSync, + mkdirSync, + rmSync, + statSync +} from 'node:fs'; import { extname, resolve, join, dirname, relative } from 'node:path'; import { pipeline } from 'node:stream'; import { promisify } from 'node:util'; import zlib from 'node:zlib'; -import { copy, rimraf, mkdirp } from '../../utils/filesystem.js'; +import { copy } from '../../utils/filesystem.js'; import { posixify } from '../../utils/os.js'; import { generate_manifest } from '../generate_manifest/index.js'; import { get_route_segments } from '../../utils/routing.js'; @@ -99,8 +106,8 @@ export function create_builder({ return { log, - rimraf, - mkdirp, + rimraf: (dir) => rmSync(dir, { force: true, recursive: true }), + mkdirp: (dir) => mkdirSync(dir, { recursive: true }), copy, config, @@ -271,7 +278,7 @@ export function create_builder({ exports: module.exports }); - rimraf(entrypoint); + rmSync(entrypoint, { force: true, recursive: true }); write(entrypoint, facade); } }; diff --git a/packages/kit/src/core/postbuild/prerender.js b/packages/kit/src/core/postbuild/prerender.js index ef66691fdda5..34f6ea765db1 100644 --- a/packages/kit/src/core/postbuild/prerender.js +++ b/packages/kit/src/core/postbuild/prerender.js @@ -1,7 +1,7 @@ -import { existsSync, readFileSync, statSync, writeFileSync } from 'node:fs'; +import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { pathToFileURL } from 'node:url'; -import { mkdirp, walk } from '../../utils/filesystem.js'; +import { walk } from '../../utils/filesystem.js'; import { posixify } from '../../utils/os.js'; import { noop } from '../../utils/functions.js'; import { decode_uri, is_root_relative, resolve } from '../../utils/url.js'; @@ -157,7 +157,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit const file = output_filename('/', true); const dest = `${config.outDir}/output/prerendered/pages/${file}`; - mkdirp(dirname(dest)); + mkdirSync(dirname(dest), { recursive: true }); writeFileSync(dest, fallback); prerendered.pages.set('/', { file }); @@ -476,7 +476,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit } if (!headers['x-sveltekit-normalize']) { - mkdirp(dirname(dest)); + mkdirSync(dirname(dest), { recursive: true }); writeFileSync( dest, @@ -522,7 +522,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit ); } - mkdirp(dir); + mkdirSync(dir, { recursive: true }); writeFileSync(dest, body); written.add(file); diff --git a/packages/kit/src/core/sync/utils.js b/packages/kit/src/core/sync/utils.js index 9da5d4e282bb..41e26e818ade 100644 --- a/packages/kit/src/core/sync/utils.js +++ b/packages/kit/src/core/sync/utils.js @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { styleText } from 'node:util'; -import { mkdirp, resolve_entry } from '../../utils/filesystem.js'; +import { resolve_entry } from '../../utils/filesystem.js'; /** @type {Map} */ const previous_contents = new Map(); @@ -22,7 +22,7 @@ export function write_if_changed(file, code) { */ export function write(file, code) { previous_contents.set(file, code); - mkdirp(path.dirname(file)); + fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, code); } diff --git a/packages/kit/src/core/sync/write_types/index.js b/packages/kit/src/core/sync/write_types/index.js index 09d02365e13a..40589df2ab67 100644 --- a/packages/kit/src/core/sync/write_types/index.js +++ b/packages/kit/src/core/sync/write_types/index.js @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import MagicString from 'magic-string'; -import { rimraf, walk, resolve_entry } from '../../../utils/filesystem.js'; +import { walk, resolve_entry } from '../../../utils/filesystem.js'; import { compact } from '../../../utils/array.js'; import { posixify } from '../../../utils/os.js'; import { ts } from '../ts.js'; @@ -49,7 +49,7 @@ export function write_all_types(config, manifest_data, root) { for (const file of walk(types_dir)) { const dir = path.dirname(file); if (!expected_directories.has(dir)) { - rimraf(path.join(types_dir, file)); + fs.rmSync(path.join(types_dir, file), { force: true, recursive: true }); } } } diff --git a/packages/kit/src/core/sync/write_types/index.spec.js b/packages/kit/src/core/sync/write_types/index.spec.js index cc6e369de4ba..4bad115fabe7 100644 --- a/packages/kit/src/core/sync/write_types/index.spec.js +++ b/packages/kit/src/core/sync/write_types/index.spec.js @@ -3,7 +3,6 @@ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { assert, describe, expect, test } from 'vitest'; -import { rimraf } from '../../../utils/filesystem.js'; import create_manifest_data from '../create_manifest_data/index.js'; import { tweak_types, write_all_types } from './index.js'; import { write_app_types } from '../write_app_types.js'; @@ -16,7 +15,7 @@ const cwd = path.join(import.meta.dirname, 'test'); * @param {string} dir */ function run_test(dir) { - rimraf(path.join(cwd, dir, '.svelte-kit')); + fs.rmSync(path.join(cwd, dir, '.svelte-kit'), { force: true, recursive: true }); const initial = validate_config({}); diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 70ce0c084097..209844c2dedc 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -121,9 +121,15 @@ type UnpackValidationError = export interface Builder { /** Print messages to the console. `log.info` and `log.minor` are silent unless Vite's `logLevel` is `info`. */ log: Logger; - /** Remove `dir` and all its contents. */ + /** + * Remove `dir` and all its contents. + * @deprecated Use `fs.rmSync(dir, { force: true, recursive: true })` instead + */ rimraf: (dir: string) => void; - /** Create `dir` and any required parent directories. */ + /** + * Create `dir` and any required parent directories. + * @deprecated Use `fs.mkdirSync(dir, { recursive: true })` instead + */ mkdirp: (dir: string) => void; /** The fully resolved SvelteKit config. */ diff --git a/packages/kit/src/exports/vite/build/build_server.js b/packages/kit/src/exports/vite/build/build_server.js index de55700d5cb5..1de30641c14c 100644 --- a/packages/kit/src/exports/vite/build/build_server.js +++ b/packages/kit/src/exports/vite/build/build_server.js @@ -1,7 +1,6 @@ /** @import { AssetDependencies, ManifestData, SSRNode, ValidatedKitConfig } from 'types' */ /** @import { Manifest, Rolldown } from 'vite' */ import fs from 'node:fs'; -import { mkdirp } from '../../../utils/filesystem.js'; import { create_function_as_string, filter_fonts, @@ -36,8 +35,8 @@ export function build_server_nodes( chunks, root ) { - mkdirp(`${out}/server/nodes`); - mkdirp(`${out}/server/stylesheets`); + fs.mkdirSync(`${out}/server/nodes`, { recursive: true }); + fs.mkdirSync(`${out}/server/stylesheets`, { recursive: true }); /** * Stylesheet names and their contents which are below the inline threshold diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 655843db6996..61a743427bbe 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -11,7 +11,7 @@ import MagicString from 'magic-string'; import { loadEnv } from 'vite'; import { exactRegex, prefixRegex } from 'rolldown/filter'; -import { copy, mkdirp, read, resolve_entry, rimraf } from '../../utils/filesystem.js'; +import { copy, read, resolve_entry } from '../../utils/filesystem.js'; import { posixify } from '../../utils/os.js'; import { to_fs } from '../../utils/vite.js'; import { @@ -1551,9 +1551,9 @@ function kit({ svelte_config }) { async buildApp(builder) { // clears the output directories if (!builder.config.build.watch) { - rimraf(out); + fs.rmSync(out, { force: true, recursive: true }); } - mkdirp(out); + fs.mkdirSync(out, { recursive: true }); await load_and_validate_params({ routes: manifest_data.routes, diff --git a/packages/kit/src/utils/filesystem.js b/packages/kit/src/utils/filesystem.js index 1173086bd112..c672f42328c0 100644 --- a/packages/kit/src/utils/filesystem.js +++ b/packages/kit/src/utils/filesystem.js @@ -2,28 +2,6 @@ import fs from 'node:fs'; import path from 'node:path'; import { posixify } from './os.js'; -/** @param {string} dir */ -export function mkdirp(dir) { - try { - fs.mkdirSync(dir, { recursive: true }); - } catch (/** @type {any} */ e) { - if (e.code === 'EEXIST') { - if (!fs.statSync(dir).isDirectory()) { - throw new Error(`Cannot create directory ${dir}, a file already exists at this position`, { - cause: e - }); - } - return; - } - throw e; - } -} - -/** @param {string} path */ -export function rimraf(path) { - fs.rmSync(path, { force: true, recursive: true }); -} - /** * @param {string} source * @param {string} target @@ -58,7 +36,7 @@ export function copy(source, target, opts = {}) { go(path.join(from, file), path.join(to, file)); }); } else { - mkdirp(path.dirname(to)); + fs.mkdirSync(path.dirname(to), { recursive: true }); if (opts.replace) { const data = fs.readFileSync(from, 'utf-8'); diff --git a/packages/kit/src/utils/filesystem.spec.js b/packages/kit/src/utils/filesystem.spec.js index 86e0322f02ff..29412768d0ed 100644 --- a/packages/kit/src/utils/filesystem.spec.js +++ b/packages/kit/src/utils/filesystem.spec.js @@ -2,7 +2,7 @@ import { mkdtempSync, writeFileSync, readdirSync, mkdirSync, readFileSync } from import { tmpdir } from 'node:os'; import { dirname, join } from 'node:path'; import { assert, expect, beforeEach, test } from 'vitest'; -import { copy, mkdirp, resolve_entry } from './filesystem.js'; +import { copy, resolve_entry } from './filesystem.js'; /** @type {string} */ let source_dir; @@ -23,7 +23,7 @@ beforeEach(() => { */ const write = (file, contents) => { const filepath = join(source_dir, file); - mkdirp(dirname(filepath)); + mkdirSync(dirname(filepath), { recursive: true }); writeFileSync(filepath, contents); }; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 00cc2aac3d70..6f42c0a0130f 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -95,9 +95,15 @@ declare module '@sveltejs/kit' { export interface Builder { /** Print messages to the console. `log.info` and `log.minor` are silent unless Vite's `logLevel` is `info`. */ log: Logger; - /** Remove `dir` and all its contents. */ + /** + * Remove `dir` and all its contents. + * @deprecated Use `fs.rmSync(dir, { force: true, recursive: true })` instead + */ rimraf: (dir: string) => void; - /** Create `dir` and any required parent directories. */ + /** + * Create `dir` and any required parent directories. + * @deprecated Use `fs.mkdirSync(dir, { recursive: true })` instead + */ mkdirp: (dir: string) => void; /** The fully resolved SvelteKit config. */ diff --git a/packages/package/src/filesystem.js b/packages/package/src/filesystem.js index 0a0b737728ac..52ee66f8a21b 100644 --- a/packages/package/src/filesystem.js +++ b/packages/package/src/filesystem.js @@ -1,108 +1,4 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -/** @param {string} dir */ -export function mkdirp(dir) { - try { - fs.mkdirSync(dir, { recursive: true }); - } catch (/** @type {any} */ e) { - if (e.code === 'EEXIST') return; - throw e; - } -} - -/** @param {string} path */ -export function rimraf(path) { - fs.rmSync(path, { force: true, recursive: true }); -} - /** @param {string} str */ export function posixify(str) { return str.replace(/\\/g, '/'); } - -/** - * Get a list of all files in a directory - * @param {string} cwd - the directory to walk - * @param {boolean} [dirs] - whether to include directories in the result - */ -export function walk(cwd, dirs = false) { - /** @type {string[]} */ - const all_files = []; - - /** @param {string} dir */ - function walk_dir(dir) { - const files = fs.readdirSync(path.join(cwd, dir)); - - for (const file of files) { - const joined = path.join(dir, file); - const stats = fs.statSync(path.join(cwd, joined)); - if (stats.isDirectory()) { - if (dirs) all_files.push(joined); - walk_dir(joined); - } else { - all_files.push(joined); - } - } - } - - return (walk_dir(''), all_files); -} - -/** - * @param {string} source - * @param {string} target - * @param {{ - * filter?: (basename: string) => boolean; - * replace?: Record; - * }} opts - */ -export function copy(source, target, opts = {}) { - if (!fs.existsSync(source)) return []; - - /** @type {string[]} */ - const files = []; - - const prefix = posixify(target) + '/'; - - const regex = opts.replace - ? new RegExp(`\\b(${Object.keys(opts.replace).join('|')})\\b`, 'g') - : null; - - /** - * @param {string} from - * @param {string} to - */ - function go(from, to) { - if (opts.filter && !opts.filter(path.basename(from))) return; - - const stats = fs.statSync(from); - - if (stats.isDirectory()) { - fs.readdirSync(from).forEach((file) => { - go(path.join(from, file), path.join(to, file)); - }); - } else { - mkdirp(path.dirname(to)); - - if (opts.replace) { - const data = fs.readFileSync(from, 'utf-8'); - fs.writeFileSync( - to, - data.replace( - /** @type {RegExp} */ (regex), - (_match, key) => /** @type {Record} */ (opts.replace)[key] - ) - ); - } else { - fs.copyFileSync(from, to); - } - - files.push(to === target ? posixify(path.basename(to)) : posixify(to).replace(prefix, '')); - } - } - - go(source, target); - - return files; -} diff --git a/packages/package/src/index.js b/packages/package/src/index.js index 337cabc18cf3..ef979bdedeb9 100644 --- a/packages/package/src/index.js +++ b/packages/package/src/index.js @@ -3,7 +3,7 @@ import * as path from 'node:path'; import { styleText } from 'node:util'; import chokidar from 'chokidar'; import { preprocess } from 'svelte/compiler'; -import { copy, mkdirp, posixify, rimraf } from './filesystem.js'; +import { posixify } from './filesystem.js'; import { analyze, resolve_aliases, @@ -35,8 +35,8 @@ async function do_build(options, analyse_code) { throw new Error(`${path.relative('.', input)} does not exist`); } - rimraf(temp); - mkdirp(temp); + fs.rmSync(temp, { force: true, recursive: true }); + fs.mkdirSync(temp, { recursive: true }); const files = scan(input, extensions); @@ -61,11 +61,11 @@ async function do_build(options, analyse_code) { } if (!options.preserve_output) { - rimraf(output); + fs.rmSync(output, { force: true, recursive: true }); } - mkdirp(output); - copy(temp, output); + fs.mkdirSync(output, { recursive: true }); + fs.cpSync(temp, output, { recursive: true, dereference: true }); console.log( styleText( @@ -326,7 +326,9 @@ async function process_file( analyse_code(file.name, contents); write(dest, contents); - } else { - copy(filename, dest); + } else if (fs.existsSync(filename)) { + // copyFileSync rather than cpSync: cpSync with dereference errors on symlinked sources + fs.mkdirSync(path.dirname(dest), { recursive: true }); + fs.copyFileSync(filename, dest); } } diff --git a/packages/package/src/typescript.js b/packages/package/src/typescript.js index c2de52159acc..61f15c151713 100644 --- a/packages/package/src/typescript.js +++ b/packages/package/src/typescript.js @@ -2,7 +2,7 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { createRequire } from 'node:module'; import semver from 'semver'; -import { posixify, mkdirp, rimraf, walk } from './filesystem.js'; +import { posixify } from './filesystem.js'; import { resolve_aliases, write } from './utils.js'; import { emitDts } from 'svelte2tsx'; import { load_pkg_json } from './config.js'; @@ -22,8 +22,8 @@ import { load_pkg_json } from './config.js'; */ export async function emit_dts(input, output, final_output, cwd, alias, files, tsconfig) { const tmp = `${output}/__package_types_tmp__`; - rimraf(tmp); - mkdirp(tmp); + fs.rmSync(tmp, { force: true, recursive: true }); + fs.mkdirSync(tmp, { recursive: true }); const require = createRequire(import.meta.url); const pkg = load_pkg_json(cwd); @@ -53,8 +53,12 @@ export async function emit_dts(input, output, final_output, cwd, alias, files, t } } + const generated = fs + .readdirSync(tmp, { encoding: 'utf-8', recursive: true }) + .filter((file) => fs.statSync(path.join(tmp, file)).isFile()); + // resolve $lib alias (TODO others), copy into package dir - for (const file of walk(tmp)) { + for (const file of generated) { const normalized = posixify(file); if (handwritten.has(normalized)) { @@ -85,7 +89,7 @@ export async function emit_dts(input, output, final_output, cwd, alias, files, t write(path.join(output, normalized), source); } - rimraf(tmp); + fs.rmSync(tmp, { force: true, recursive: true }); } /** diff --git a/packages/package/src/utils.js b/packages/package/src/utils.js index bdf3f92e82f4..2f75a83b00bb 100644 --- a/packages/package/src/utils.js +++ b/packages/package/src/utils.js @@ -1,7 +1,7 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { VERSION } from 'svelte/compiler'; -import { posixify, mkdirp, walk } from './filesystem.js'; +import { posixify } from './filesystem.js'; const is_svelte_5_plus = Number(VERSION.split('.')[0]) >= 5; @@ -132,7 +132,7 @@ export function strip_lang_tags(content) { * @param {Parameters[1]} contents */ export function write(file, contents) { - mkdirp(path.dirname(file)); + fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, contents); } @@ -142,7 +142,10 @@ export function write(file, contents) { * @returns {import('./types.js').File[]} */ export function scan(input, extensions) { - return walk(input).map((file) => analyze(file, extensions)); + return fs + .readdirSync(input, { encoding: 'utf-8', recursive: true }) + .filter((file) => fs.statSync(path.join(input, file)).isFile()) + .map((file) => analyze(file, extensions)); } /** diff --git a/packages/package/test/index.spec.js b/packages/package/test/index.spec.js index 6ee504171a08..f9629c9124c9 100644 --- a/packages/package/test/index.spec.js +++ b/packages/package/test/index.spec.js @@ -7,7 +7,6 @@ import { test, expect } from 'vitest'; import { build, watch } from '../src/index.js'; import { load_config } from '../src/config.js'; -import { rimraf, walk } from '../src/filesystem.js'; import { _create_validator } from '../src/validate.js'; import { resolve_aliases } from '../src/utils.js'; @@ -38,8 +37,8 @@ async function test_make_package(path, options) { ...options }); - const expected_files = walk(ewd, true); - const actual_files = walk(output, true); + const expected_files = fs.readdirSync(ewd, { encoding: 'utf-8', recursive: true }).sort(); + const actual_files = fs.readdirSync(output, { encoding: 'utf-8', recursive: true }).sort(); expect(actual_files).toEqual(expected_files); @@ -118,7 +117,7 @@ for (const dir of fs.readdirSync(join(import.meta.dirname, 'errors'))) { throw new Error('All error test must be handled', { cause: error }); } } finally { - rimraf(output); + fs.rmSync(output, { force: true, recursive: true }); } }); } @@ -534,7 +533,7 @@ test('does not warn about server files that import a .ts file which imports $app test('create package with preserved output', async () => { const output = join(import.meta.dirname, 'fixtures', 'preserve-output', 'dist'); - rimraf(output); + fs.rmSync(output, { force: true, recursive: true }); fs.mkdirSync(join(output, 'assets'), { recursive: true }); fs.writeFileSync(join(output, 'assets', 'theme.css'), ':root { color: red }'); await test_make_package('preserve-output', { preserve_output: true });