From eb94c084a26858aec1b635c832e032a57b7cf4e5 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 22 Jun 2024 14:21:40 -0400 Subject: [PATCH] bug/issue 1199 gracefully handle unresolvable asset URLs during CSS optimization (#1235) * feature/issue 1197 Lit v3 upgrade and SSR fixes and enhancements (#1201) * initial upgrade for test cases * upgrade CLI and www to Lit v3 * revert static router test case change * all tests passing * patch escodegen for better ESM support * test for lit element hydration script * refactor rollup config * update Lit renderer README and apply conditional Lit script hydration * comments and TODOs cleanup * minor rebase patches * WCC v0.12.0 upgrade and removing patches directory * hydration default documentation and testing for Lit renderer plugin * v0.30.0-alpha.1 * feature/issue 923 native import attributes for CSS and JSON (#1215) * intial draft of import attributes support for CSS and JSON * all test cases passing * need patch package * wcc patches for import attributes and CSSStylesheet shim * bump min NodeJS version for exp specs * temp disable ESLint * develop based import assertion specs * serve based import attributes specs * add preIntercept resource plugin lifecycle and refactor PostCSS to use it * all test cases passing for import attributes support * refactor built in CSS and JSON intercepting * demo code * raw plugin docs and package.json updates * update latest documentation for custom loaders support in NodeJS * update custom import docs * upgrade wcc v0.13.0 * only need Node 18 for github actions * css imports and raw plugin interop with test cases * lit renderer import attribute test cases and documentation * refactor matchers support for raw plugin instead of patching and add test cases * disable describe.only * update usage for custom resource plugins to showcase usage of import attributes * document preIntercept lifecycle and convert Babel to use it * restore ESLint * enable debug logging for failing specs * refactor theme pack specs * fix linting * remove CSS and JSON packages from being publishable * clean up console logs and comments * rename exp test cases to loadersnaming prefix * fix command in github actions * remove plugin-import-css callout from plugin-postcss README * remove demo code from website * refine PostCSS plugin intercepting * gracefully handle unresolvable assets during CSS optimization * refactor URL and fs usage * fix lint * missed rebase-a-ronis * missed rebase-a-ronis --- .../plugins/resource/plugin-standard-css.js | 31 +++++++++++-------- .../fixtures/expected.css | 6 +++- .../src/styles/main.css | 9 ++++++ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-standard-css.js b/packages/cli/src/plugins/resource/plugin-standard-css.js index b98e3bfb4..a7dfe1a6e 100644 --- a/packages/cli/src/plugins/resource/plugin-standard-css.js +++ b/packages/cli/src/plugins/resource/plugin-standard-css.js @@ -8,7 +8,6 @@ import fs from 'fs'; import path from 'path'; import { parse, walk } from 'css-tree'; import { ResourceInterface } from '../../lib/resource-interface.js'; -import { normalizePathnameForWindows } from '../../lib/resource-utils.js'; import { hashString } from '../../lib/hashing-utils.js'; function bundleCss(body, url, compilation) { @@ -38,7 +37,7 @@ function bundleCss(body, url, compilation) { optimizedCss += `@import url('${value}');`; } } else if (type === 'Url' && this.atrule?.name !== 'import') { - if (value.startsWith('http') || value.startsWith('//')) { + if (value.startsWith('http') || value.startsWith('//') || value.startsWith('data:')) { optimizedCss += `url('${value}')`; return; } @@ -53,20 +52,26 @@ function bundleCss(body, url, compilation) { const locationUrl = barePath.startsWith('node_modules') ? new URL(`./${barePath}`, projectDirectory) : new URL(`./${barePath}`, userWorkspace); - const hash = hashString(fs.readFileSync(locationUrl, 'utf-8')); - const ext = barePath.split('.').pop(); - const hashedRoot = barePath.replace(`.${ext}`, `.${hash}.${ext}`); - fs.mkdirSync(normalizePathnameForWindows(new URL(`./${path.dirname(barePath)}/`, outputDir)), { - recursive: true - }); + if (fs.existsSync(locationUrl)) { + const hash = hashString(fs.readFileSync(locationUrl, 'utf-8')); + const ext = barePath.split('.').pop(); + const hashedRoot = barePath.replace(`.${ext}`, `.${hash}.${ext}`); - fs.promises.copyFile( - locationUrl, - new URL(`./${hashedRoot}`, outputDir) - ); + fs.mkdirSync(new URL(`./${path.dirname(barePath)}/`, outputDir), { + recursive: true + }); - optimizedCss += `url('${basePath}${hashedRoot}')`; + fs.promises.copyFile( + locationUrl, + new URL(`./${hashedRoot}`, outputDir) + ); + + optimizedCss += `url('${basePath}${hashedRoot}')`; + } else { + console.warn(`Unable to locate ${value}. You may need to manually copy this file from its source location to the build output directory.`); + optimizedCss += `url('${value}')`; + } } else if (type === 'Atrule' && name !== 'import') { optimizedCss += `@${name} `; } else if (type === 'TypeSelector') { diff --git a/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css b/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css index 51eaddcf3..2c7e2eff2 100644 --- a/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css +++ b/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css @@ -60,4 +60,8 @@ h1:has(+h2){margin:0 0 0.25rem 0} :is(ol,ul,menu:unsupported) :is(ol,ul){color:green} -.snippet{margin:var(--size-4) 0;padding:0 var(--size-4);} \ No newline at end of file +.snippet{margin:var(--size-4) 0;padding:0 var(--size-4);} + +h1{background-image:url('/foo/bar.baz')} + +.has-success{background-image:url('data:image/svg+xml;...')} diff --git a/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css b/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css index 8877b8e21..8ebfcebf7 100644 --- a/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css +++ b/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css @@ -132,7 +132,16 @@ h1:has(+ h2) { color: green; } + .snippet { margin: var(--size-4) 0; padding: 0 var(--size-4); +} + +h1 { + background-image: url('/foo/bar.baz'); +} + +.has-success{ + background-image: url("data:image/svg+xml;..."); } \ No newline at end of file