From 6f72c547e02618e433f3a53deff8800fb39b29ca Mon Sep 17 00:00:00 2001 From: Jake Deichert Date: Sun, 19 Jan 2020 22:19:05 -0500 Subject: [PATCH] Prevent corruption of binary asset types during copy Because I was reading all non-js/svelte files as utf8 and then writing them to the dist dir, this completely corrupted images and binary assets. --- src/index.ts | 56 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index bff162f..041ac00 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,43 +13,45 @@ const exec = util.promisify(execSync); const IS_PRODUCTION_MODE = process.env.NODE_ENV === 'production'; -async function compile(file: string): Promise { +async function compile(srcPath: string): Promise { try { - const source = await fs.readFile(file, 'utf8'); - const isSvelte = file.endsWith('.svelte'); + const source = await fs.readFile(srcPath, 'utf8'); + const isSvelte = srcPath.endsWith('.svelte'); - // Don't compile non-svelte files - const compiled = isSvelte + // Only compile svelte files + const newSource = isSvelte ? svelte.compile(source, { dev: !IS_PRODUCTION_MODE, }).js.code : source; - // Create all ancestor directories for this file - const destPath = file + const destPath = srcPath .replace(/^src\//, 'dist/') .replace(/.svelte$/, '.js'); - + // Create all ancestor directories for this file await fs.mkdir(path.dirname(destPath), { recursive: true }); - await fs.writeFile(destPath, compiled); - - // Don't compile/transpile any non-js files - if (!destPath.endsWith('.js') && !destPath.endsWith('.mjs')) { - return null; - } + await fs.writeFile(destPath, newSource); console.info(`Svelte compiled ${destPath}`); return destPath; } catch (err) { console.log(''); - console.error(`Failed to compile with svelte: ${file}`); + console.error(`Failed to compile with svelte: ${srcPath}`); console.error(err); console.log(''); return null; } } +async function copyFile(srcPath: string): Promise { + const destPath = srcPath.replace(/^src\//, 'dist/'); + // Create all ancestor directories for this file + await fs.mkdir(path.dirname(destPath), { recursive: true }); + await fs.copyFile(srcPath, destPath); + console.info(`Copied asset ${destPath}`); +} + // Update the import paths to correctly point to web_modules. async function transform(destPath: string): Promise { try { @@ -109,29 +111,35 @@ const snowpack = async (): Promise => { async function initialBuild(): Promise { if (IS_PRODUCTION_MODE) console.info(`Building in production mode...`); - const concurrentCompilationLimit = pLimit(8); + const concurrencyLimit = pLimit(8); + const globConfig = { nodir: true }; + const svelteAndJsFiles = glob.sync('src/**/*.+(js|mjs|svelte)', globConfig); + const otherAssetFiles = glob.sync('src/**/*.!(js|mjs|svelte)', globConfig); - const srcFiles = glob.sync('src/**', { - nodir: true, - }); + // Just copy all other asset types, no point in reading them. + await Promise.all( + otherAssetFiles.map(srcPath => + concurrencyLimit(async () => copyFile(srcPath)) + ) + ); // Compile all source files with svelte. const destFiles = await Promise.all( - srcFiles.map(srcPath => - concurrentCompilationLimit(async () => { + svelteAndJsFiles.map(srcPath => + concurrencyLimit(async () => { const destPath = await compile(srcPath); return destPath; }) ) ); - // Need to run (only once) before transforming the import paths, or else it will fail. + // Need to run this (only once) before transforming the import paths, or else it will fail. await snowpack(); - // Transform all js files with babel. + // Transform all generated js files with babel. await Promise.all( destFiles.map(destPath => - concurrentCompilationLimit(async () => { + concurrencyLimit(async () => { if (!destPath) return; await transform(destPath); })