UNPKG

@sveltejs/package

Version:

The fastest way to build Svelte packages

139 lines (121 loc) 4.28 kB
import * as fs from 'node:fs'; import * as path from 'node:path'; import { VERSION } from 'svelte/compiler'; import { posixify, mkdirp, walk } from './filesystem.js'; const is_svelte_5_plus = Number(VERSION.split('.')[0]) >= 5; /** * Resolves aliases * * @param {string} input * @param {string} file Relative to the input * @param {string} content * @param {Record<string, string>} aliases * @returns {string} */ export function resolve_aliases(input, file, content, aliases) { /** * @param {string} match * @param {string} quote * @param {string} import_path */ const replace_import_path = (match, quote, import_path) => { for (const [alias, value] of Object.entries(aliases)) { if ( import_path !== alias && !import_path.startsWith(alias + (alias.endsWith('/') ? '' : '/')) ) { continue; } const full_path = path.join(input, file); const full_import_path = path.join(value, import_path.slice(alias.length)); let resolved = posixify(path.relative(path.dirname(full_path), full_import_path)); resolved = resolved.startsWith('.') ? resolved : './' + resolved; return match.replace(quote + import_path + quote, quote + resolved + quote); } return match; }; // import/export (type) (xxx | xxx,) { ... } from ... content = content.replace( /\b(?:import|export)(?:\s+type)?(?:(?:\s+\p{L}[\p{L}0-9]*\s+)|(?:(?:\s+\p{L}[\p{L}0-9]*\s*,\s*)?\s*\{[^}]*\}\s*))from\s*(['"])([^'";]+)\1/gmu, (match, quote, import_path) => replace_import_path(match, quote, import_path) ); // import/export (type) * as xxx from ... content = content.replace( /\b(?:import|export)(?:\s+type)?\s*\*\s*as\s+\p{L}[\p{L}0-9]*\s+from\s*(['"])([^'";]+)\1/gmu, (match, quote, import_path) => replace_import_path(match, quote, import_path) ); // export (type) * from ... content = content.replace( /\b(?:export)(?:\s+type)?\s*\*\s*from\s*(['"])([^'";]+)\1/gmu, (match, quote, import_path) => replace_import_path(match, quote, import_path) ); // import(...) content = content.replace( /\bimport\s*\(\s*(['"])([^'";]+)\1\s*\)/g, (match, quote, import_path) => replace_import_path(match, quote, import_path) ); // import '...' content = content.replace(/\bimport\s+(['"])([^'";]+)\1/g, (match, quote, import_path) => replace_import_path(match, quote, import_path) ); return content; } /** * Strip out lang="X" or type="text/X" tags. Doing it here is only a temporary solution. * See https://github.com/sveltejs/kit/issues/2450 for ideas for places where it's handled better. * * @param {string} content */ export function strip_lang_tags(content) { return content .replace( /(<!--[^]*?-->)|(<script[^>]*?)\s(?:type|lang)=(["'])(.*?)\3/g, // Things like application/ld+json should be kept as-is. Preprocessed languages are "ts" etc. // Svelte 5 deals with TypeScript natively, and in the template, too, therefore keep it in. // Not removing it would mean Svelte parses without its TS plugin and then runs into errors. (match, comment, tag_open, _, type) => type?.startsWith('application/') || (is_svelte_5_plus && type === 'ts') ? match : (comment ?? '') + (tag_open ?? '') ) .replace(/(<!--[^]*?-->)|(<style[^>]*?)\s(?:type|lang)=(["']).*?\3/g, '$1$2'); } /** * @param {string} file * @param {Parameters<typeof fs.writeFileSync>[1]} contents */ export function write(file, contents) { mkdirp(path.dirname(file)); fs.writeFileSync(file, contents); } /** * @param {string} input * @param {string[]} extensions * @returns {import('./types.js').File[]} */ export function scan(input, extensions) { return walk(input).map((file) => analyze(file, extensions)); } /** * @param {string} file * @param {string[]} extensions * @returns {import('./types.js').File} */ export function analyze(file, extensions) { const name = posixify(file); const svelte_extension = extensions.find((ext) => name.endsWith(ext)); const base = svelte_extension ? name : name.slice(0, -path.extname(name).length); const dest = svelte_extension ? name.slice(0, -svelte_extension.length) + '.svelte' : name.endsWith('.d.ts') ? name : name.endsWith('.ts') ? name.slice(0, -3) + '.js' : name; return { name, dest, base, is_svelte: !!svelte_extension }; }