From 5412f65b221421168e54c361d9b214685d42473f Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 20 Mar 2022 14:30:35 -0400 Subject: [PATCH] Update @parcel/css and add diagnostic for url dependencies in custom properties (#7845) --- packages/core/integration-tests/test/css.js | 53 ++++++++++- .../css-url-custom-property/index.css | 3 + .../sourcemap-css-import/style.css | 5 +- packages/optimizers/css/package.json | 2 +- packages/transformers/css/package.json | 3 +- .../transformers/css/src/CSSTransformer.js | 79 +++++++++++------ yarn.lock | 88 +++++++++---------- 7 files changed, 156 insertions(+), 77 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/css-url-custom-property/index.css diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index dcb3adab669..e4abcd6287e 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -258,7 +258,58 @@ describe('css', () => { let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); - assert(css.includes('url(#default#VML)')); + assert(css.includes('url("#default#VML")')); + }); + + it('should throw a diagnostic for relative url() dependencies in custom properties', async function () { + let fixture = path.join( + __dirname, + 'integration/css-url-custom-property/index.css', + ); + let code = await inputFS.readFileSync(fixture, 'utf8'); + // $FlowFixMe + await assert.rejects( + () => + bundle(fixture, { + defaultTargetOptions: { + shouldOptimize: true, + }, + }), + { + name: 'BuildError', + diagnostics: [ + { + message: + 'Ambiguous url() in custom property. Relative paths are resolved from the location the var() is used, not where the custom property is defined. Use an absolute URL instead.', + origin: '@parcel/transformer-css', + name: 'SyntaxError', + stack: undefined, + codeFrames: [ + { + filePath: fixture, + code, + codeHighlights: [ + { + start: { + line: 2, + column: 11, + }, + end: { + line: 2, + column: 11, + }, + }, + ], + }, + ], + hints: [ + 'Replace with: url(/integration/css-url-custom-property/foo.png)', + ], + documentationURL: 'https://parceljs.org/languages/css/#url()', + }, + ], + }, + ); }); it('should minify CSS when minify is set', async function () { diff --git a/packages/core/integration-tests/test/integration/css-url-custom-property/index.css b/packages/core/integration-tests/test/integration/css-url-custom-property/index.css new file mode 100644 index 00000000000..e64216d79ae --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-url-custom-property/index.css @@ -0,0 +1,3 @@ +.foo { + --test: url(foo.png); +} diff --git a/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css b/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css index 01ef4f07c71..5e2dc1491de 100644 --- a/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css +++ b/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css @@ -1,8 +1,7 @@ @import "./other-style.css"; +@import "./another-style.css"; body { background-color: red; -} - -@import "./another-style.css"; +} \ No newline at end of file diff --git a/packages/optimizers/css/package.json b/packages/optimizers/css/package.json index 873bf247fd1..666fa7411a3 100644 --- a/packages/optimizers/css/package.json +++ b/packages/optimizers/css/package.json @@ -20,7 +20,7 @@ "parcel": "^2.3.2" }, "dependencies": { - "@parcel/css": "^1.6.0", + "@parcel/css": "^1.7.1", "@parcel/diagnostic": "2.3.2", "@parcel/plugin": "2.3.2", "@parcel/source-map": "^2.0.0", diff --git a/packages/transformers/css/package.json b/packages/transformers/css/package.json index 43ac3330841..fdc7a83ad81 100644 --- a/packages/transformers/css/package.json +++ b/packages/transformers/css/package.json @@ -20,7 +20,8 @@ "parcel": "^2.3.2" }, "dependencies": { - "@parcel/css": "^1.6.0", + "@parcel/css": "^1.7.1", + "@parcel/diagnostic": "2.3.2", "@parcel/plugin": "2.3.2", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.3.2", diff --git a/packages/transformers/css/src/CSSTransformer.js b/packages/transformers/css/src/CSSTransformer.js index 58f1638f331..0cf252b731b 100644 --- a/packages/transformers/css/src/CSSTransformer.js +++ b/packages/transformers/css/src/CSSTransformer.js @@ -8,9 +8,10 @@ import { transformStyleAttribute, browserslistToTargets, } from '@parcel/css'; -import {remapSourceLocation} from '@parcel/utils'; +import {remapSourceLocation, relativePath} from '@parcel/utils'; import browserslist from 'browserslist'; import nullthrows from 'nullthrows'; +import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic'; export default (new Transformer({ async loadConfig({config, options}) { @@ -27,25 +28,48 @@ export default (new Transformer({ let targets = getTargets(asset.env.engines.browsers); let res; - if (asset.meta.type === 'attr') { - res = transformStyleAttribute({ - code, - analyzeDependencies: true, - targets, + try { + if (asset.meta.type === 'attr') { + res = transformStyleAttribute({ + code, + analyzeDependencies: true, + targets, + }); + } else { + res = transform({ + filename: path.relative(options.projectRoot, asset.filePath), + code, + cssModules: + config?.cssModules ?? + (asset.meta.cssModulesCompiled !== true && + /\.module\./.test(asset.filePath)), + analyzeDependencies: asset.meta.hasDependencies !== false, + sourceMap: !!asset.env.sourceMap, + drafts: config?.drafts, + pseudoClasses: config?.pseudoClasses, + targets, + }); + } + } catch (err) { + err.filePath = asset.filePath; + let diagnostic = errorToDiagnostic(err, { + origin: '@parcel/transformer-css', }); - } else { - res = transform({ - filename: path.relative(options.projectRoot, asset.filePath), - code, - cssModules: - config?.cssModules ?? - (asset.meta.cssModulesCompiled !== true && - /\.module\./.test(asset.filePath)), - analyzeDependencies: asset.meta.hasDependencies !== false, - sourceMap: !!asset.env.sourceMap, - drafts: config?.drafts, - pseudoClasses: config?.pseudoClasses, - targets, + if (err.data?.type === 'AmbiguousUrlInCustomProperty' && err.data.url) { + let p = + '/' + + relativePath( + options.projectRoot, + path.resolve(path.dirname(asset.filePath), err.data.url), + false, + ); + diagnostic[0].hints = [`Replace with: url(${p})`]; + diagnostic[0].documentationURL = + 'https://parceljs.org/languages/css/#url()'; + } + + throw new ThrowableDiagnostic({ + diagnostic, }); } @@ -108,14 +132,6 @@ export default (new Transformer({ let js = ''; let jsDeps = []; - for (let dep of asset.getDependencies()) { - if (dep.priority === 'sync') { - // TODO: Figure out how to treeshake this - let d = `dep_$${c++}`; - depjs += `import * as ${d} from ${JSON.stringify(dep.specifier)};\n`; - depjs += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`; - } - } for (let key in exports) { locals.set(exports[key].name, key); @@ -174,6 +190,15 @@ export default (new Transformer({ add(key); } + for (let dep of asset.getDependencies()) { + if (dep.priority === 'sync') { + // TODO: Figure out how to treeshake this + let d = `dep_$${c++}`; + depjs += `import * as ${d} from ${JSON.stringify(dep.specifier)};\n`; + depjs += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`; + } + } + assets.push({ type: 'js', content: depjs + js, diff --git a/yarn.lock b/yarn.lock index 6eb3ed62a85..569b055f0a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2141,61 +2141,61 @@ dependencies: "@octokit/openapi-types" "^6.2.0" -"@parcel/css-darwin-arm64@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-darwin-arm64/-/css-darwin-arm64-1.6.0.tgz#a1d821f023f59de10619ab0d0541866d5ca46ea8" - integrity sha512-bz6LQ4xVy3bzGXx9QPW5MB2oabwid03Lq/hS5/Od6cQyek2uKvBx6ExdofQswoLuUD3GVNxJPn8DQ0RaSIyTLA== +"@parcel/css-darwin-arm64@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-darwin-arm64/-/css-darwin-arm64-1.7.1.tgz#d146e6ce09c51f2083e88114505c40005118d3da" + integrity sha512-OlQ3iY2XA5tfQICHvH/1mgQOWoEpo9CWR3bZrlejoZmkrqyRe6ACXlyIwdecEHg0rfKy4c4x2WnGR7oY0wL0mg== -"@parcel/css-darwin-x64@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-darwin-x64/-/css-darwin-x64-1.6.0.tgz#feeec4661e656d022db0aa5dcd524446e441afd9" - integrity sha512-N90dwaY62i5chn/XSM6/txjqoOTM3mRO//yQ5eQfma3BLDJ/B6qjnzg7UUYfaq+NGwtgxaL+I0lHVcVGOr+/KA== +"@parcel/css-darwin-x64@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-darwin-x64/-/css-darwin-x64-1.7.1.tgz#a7c42fe9897d255e71b29ecb4a74396425929b48" + integrity sha512-1alpdEy56RD5ac3gaxYWruxqlxCw7W4yPVJmXkGc0emxGugtdCt5imlsrVHlwn40E3DYHgvTCiL6PDRlaQnLyA== -"@parcel/css-linux-arm-gnueabihf@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm-gnueabihf/-/css-linux-arm-gnueabihf-1.6.0.tgz#49884ed1cf6ae239c51a7d2751e7947f48f6b031" - integrity sha512-ZoodK+/bs6iZBHn2tzmTA7XDXh/w85EoVH1aQAriuzIA8c6iT2aYikz/skh0ccv9tHfVD8EQi/B73uzgb15J/A== +"@parcel/css-linux-arm-gnueabihf@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm-gnueabihf/-/css-linux-arm-gnueabihf-1.7.1.tgz#2a58e61a4258777df59e9710c307bb97f168a326" + integrity sha512-Ry7igSUSR6WO6z/FT99W8n0lH0+yxcKV+JVcIFIKYAiqFIZmNALeNQnhNKJYKrx/IMe45njn71sNB3+LGxK24A== -"@parcel/css-linux-arm64-gnu@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-gnu/-/css-linux-arm64-gnu-1.6.0.tgz#efa1546bf53970bfc0fdfec318cb2d7f1acf3fc3" - integrity sha512-G6rJy4FuXay9POG0xJBSh4zfOLGpwDSospbze/3s82mP5uvF7BsBFT29eLRr27yC3f3pOZs05LHh3dnh9VEK3w== +"@parcel/css-linux-arm64-gnu@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-gnu/-/css-linux-arm64-gnu-1.7.1.tgz#6b9707c30fcfe5ebf95daa0ff69bb14071306712" + integrity sha512-h5S/wCS8q6yZWpZJXVeom4G5hCIXSXH2l+3sCtxoaJoEOXufsyX0UsHTFQdRhSd97usPo5vmc2DlAFyILdp94w== -"@parcel/css-linux-arm64-musl@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-musl/-/css-linux-arm64-musl-1.6.0.tgz#290f51989788a91adc3c5ae609cd1c832b00517a" - integrity sha512-opef+mSexRcCjNolOs5ocxSALU0Trlht/7+2inmHL6kLj0hxSBwVtQ5IKr6o5OQqG6Q7SFUSM+LIVubOfb6uzA== +"@parcel/css-linux-arm64-musl@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-musl/-/css-linux-arm64-musl-1.7.1.tgz#f15dbaf680405815d3dc69178e6a0f5b6e6b6579" + integrity sha512-uax+ypsXNsaU9Q7iGwHxEe01TSRtImmFhKSwgOnyTITy56WBLY3F1M4gTwp/7OIuagJpj6MdGeWZiTazvKG7PQ== -"@parcel/css-linux-x64-gnu@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-gnu/-/css-linux-x64-gnu-1.6.0.tgz#62c6eb6f02f4986dac186cf78738cfad5dee2a6e" - integrity sha512-dNI8t9wHp5pJW1SSl+QyCgp0x4NXmHquiTvJC3hRMIMphzq82s0PN5aCtWbqeO3hU6aSOzN3OSOWgwIsE3T5Iw== +"@parcel/css-linux-x64-gnu@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-gnu/-/css-linux-x64-gnu-1.7.1.tgz#9a32c480b9e5173484876ed66e33f608025de3ec" + integrity sha512-2uaJnErBYD3JBoZ83KvnAGmXXYyKDAREjM7sWFGarIGPdfyk4XiVznpJ5ZKMEYVZ1c3lUZhwMX/9O20lAHDVjA== -"@parcel/css-linux-x64-musl@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-musl/-/css-linux-x64-musl-1.6.0.tgz#a0ca4d9666f716fad04f9263931d4d3122d82c1f" - integrity sha512-VJR8iZAJ00Y4vQda3uB2Dl+Lg29/e/9kYxDxYI7p83oZFV0ousdgNMn2Wlt7Q345BwGICvv4tocR/Nh2m+nD5g== +"@parcel/css-linux-x64-musl@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-musl/-/css-linux-x64-musl-1.7.1.tgz#9f520d13cc5b275a95a9a8017e6bf17c9443e16f" + integrity sha512-SDmt6fBYirvZdAx0SHr0pYrPcTGXPjcXSB/myy1hunsS9DN/B0IjpK9IqP/alztuPrzp3ywDTz8RVAY2n3Us5w== -"@parcel/css-win32-x64-msvc@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css-win32-x64-msvc/-/css-win32-x64-msvc-1.6.0.tgz#c13e91838ba87e349a75e4dad6fd9b7bc4ed4e57" - integrity sha512-TV4NWrRbjkbQ/iNIP24x0uDp/m28W9v/xT4ZYCH2CwiUfU+OYNNuUPgfpsBNS1grTmMkU2qy9bnZWvV8i8L3fg== +"@parcel/css-win32-x64-msvc@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css-win32-x64-msvc/-/css-win32-x64-msvc-1.7.1.tgz#50148c5775577626a55b1a412ad49d8f9d75356a" + integrity sha512-FmLxpO4VyGbWEdXimKrYKPgf42OwTWzHoJ6M6du9c4ww9M3dRi+c4kPFIpyw1vKj4Dwbqn0QhRm5bgj0o7Ow3w== -"@parcel/css@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@parcel/css/-/css-1.6.0.tgz#bd5b07946f834b36363e0ec10ce1da404a18e98b" - integrity sha512-MViIcvGh3JVw/HoAYnqD9OFob67p8JQeXF5sNsgwFxKqmHwUm79nOO6OZrQBPWcI9y5ZVSLk0iIgB8j+7Sg1+g== +"@parcel/css@^1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@parcel/css/-/css-1.7.1.tgz#b7f1a33274ebc6b1f274d2cf18d6dcf5aafd747e" + integrity sha512-PHlOumnSTpTLheA2gSvroos0LFbtttCaQdQRu+4GswN3teNh0L6vQkWRe6bDhNIzsym4Mt3oyoCkw8E5dbI51Q== dependencies: detect-libc "^1.0.3" optionalDependencies: - "@parcel/css-darwin-arm64" "1.6.0" - "@parcel/css-darwin-x64" "1.6.0" - "@parcel/css-linux-arm-gnueabihf" "1.6.0" - "@parcel/css-linux-arm64-gnu" "1.6.0" - "@parcel/css-linux-arm64-musl" "1.6.0" - "@parcel/css-linux-x64-gnu" "1.6.0" - "@parcel/css-linux-x64-musl" "1.6.0" - "@parcel/css-win32-x64-msvc" "1.6.0" + "@parcel/css-darwin-arm64" "1.7.1" + "@parcel/css-darwin-x64" "1.7.1" + "@parcel/css-linux-arm-gnueabihf" "1.7.1" + "@parcel/css-linux-arm64-gnu" "1.7.1" + "@parcel/css-linux-arm64-musl" "1.7.1" + "@parcel/css-linux-x64-gnu" "1.7.1" + "@parcel/css-linux-x64-musl" "1.7.1" + "@parcel/css-win32-x64-msvc" "1.7.1" "@parcel/source-map@^2.0.0": version "2.0.0"