From 9456e139d28a4a1ca60af931a6e1713e56459c10 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Sat, 2 Dec 2023 21:12:02 +1100 Subject: [PATCH 01/11] Fix style compilation for file paths containing webpack template strings --- .changeset/eleven-oranges-collect.md | 7 +++++++ package.json | 3 ++- packages/webpack-plugin/src/compiler.ts | 6 +++++- tsconfig.json | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .changeset/eleven-oranges-collect.md diff --git a/.changeset/eleven-oranges-collect.md b/.changeset/eleven-oranges-collect.md new file mode 100644 index 000000000..38435b5f1 --- /dev/null +++ b/.changeset/eleven-oranges-collect.md @@ -0,0 +1,7 @@ +--- +'@vanilla-extract/webpack-plugin': patch +--- + +Fixes a bug that was causing style compilation to fail on paths containing [webpack template strings] such as `[id]`. + +[webpack template strings]: https://webpack.js.org/configuration/output/#template-strings diff --git a/package.json b/package.json index 46499eea0..260e701ab 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ } }, "volta": { - "node": "20.9.0" + "node": "20.9.0", + "pnpm": "8.10.2" } } diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index 48e90a639..6da95bb15 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -65,7 +65,11 @@ function compileVanillaSource( ); const compat = createCompat(isWebpack5); // Child compiler will compile vanilla-extract files to be evaled during compilation - const outputOptions = { filename: loader.resourcePath }; + const outputOptions = { + filename: loader.resourcePath + .replaceAll('[', '[\\') + .replaceAll(']', '\\]'), + }; const compilerName = getCompilerName(loader.resourcePath); const childCompiler = getRootCompilation(loader).createChildCompiler( diff --git a/tsconfig.json b/tsconfig.json index f879ab2c7..a3a82483f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, - "lib": ["es2019", "es2017", "dom"], + "lib": ["es2021", "dom"], "noEmit": true, "noImplicitAny": true, "noUnusedLocals": true, From 558714ef80ace0334c6c0679e3e39bfe10c37436 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Sat, 2 Dec 2023 21:29:05 +1100 Subject: [PATCH 02/11] Comments --- packages/webpack-plugin/src/compiler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index 6da95bb15..6178ab585 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -64,13 +64,15 @@ function compileVanillaSource( loader._compiler.webpack && loader._compiler.webpack.version, ); const compat = createCompat(isWebpack5); - // Child compiler will compile vanilla-extract files to be evaled during compilation + + // Escape webpack template strings in output files so they don't get replaced const outputOptions = { filename: loader.resourcePath .replaceAll('[', '[\\') .replaceAll(']', '\\]'), }; + // Child compiler will compile vanilla-extract files to be evaled during compilation const compilerName = getCompilerName(loader.resourcePath); const childCompiler = getRootCompilation(loader).createChildCompiler( compilerName, From f86994fc69877a1d7841cd2112c2dfcc52873fff Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Mon, 29 Jan 2024 10:37:07 +1100 Subject: [PATCH 03/11] Remove volta pnpm config --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 2e5441740..515433e90 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,6 @@ } }, "volta": { - "node": "20.9.0", - "pnpm": "8.10.2" + "node": "20.9.0" } } From 9944c18be363e46247e1c0b7133265ff69fcd9ae Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Mon, 29 Jan 2024 10:45:32 +1100 Subject: [PATCH 04/11] Add comment about non-standard escape syntax --- packages/webpack-plugin/src/compiler.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index 6178ab585..e5202e814 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -66,6 +66,7 @@ function compileVanillaSource( const compat = createCompat(isWebpack5); // Escape webpack template strings in output files so they don't get replaced + // Non-standard escape syntax, see the docs https://webpack.js.org/configuration/output/#template-strings const outputOptions = { filename: loader.resourcePath .replaceAll('[', '[\\') From 883374b14ab1dfcd136de436c1fb7e87a19757b5 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:42:52 +1100 Subject: [PATCH 05/11] Update regex to cover more cases --- packages/webpack-plugin/src/compiler.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index 52872990a..711398688 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -55,6 +55,9 @@ function getRootCompilation(loader: LoaderContext) { return compilation; } +export const escapeWebpackTemplateString = (s: string) => + s.replaceAll(/\[([^\[\]\.]+)\]/g, '[\\$1\\]'); + function compileVanillaSource( loader: LoaderContext, externals: Externals | undefined, @@ -65,12 +68,10 @@ function compileVanillaSource( ); const compat = createCompat(isWebpack5); - // Escape webpack template strings in output files so they don't get replaced + // Escape webpack template strings and Next.js dynamic routes in output files so they don't get replaced // Non-standard escape syntax, see the docs https://webpack.js.org/configuration/output/#template-strings const outputOptions = { - filename: loader.resourcePath - .replaceAll('[', '[\\') - .replaceAll(']', '\\]'), + filename: escapeWebpackTemplateString(loader.resourcePath), }; // Child compiler will compile vanilla-extract files to be evaled during compilation From bcf189cfe722d464806a170d4b2896b3ee0ac0bf Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:43:16 +1100 Subject: [PATCH 06/11] Add unit test for escape function --- .../src/__snapshots__/compiler.test.ts.snap | 7 +++++++ packages/webpack-plugin/src/compiler.test.ts | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/webpack-plugin/src/__snapshots__/compiler.test.ts.snap create mode 100644 packages/webpack-plugin/src/compiler.test.ts diff --git a/packages/webpack-plugin/src/__snapshots__/compiler.test.ts.snap b/packages/webpack-plugin/src/__snapshots__/compiler.test.ts.snap new file mode 100644 index 000000000..1ca8f4787 --- /dev/null +++ b/packages/webpack-plugin/src/__snapshots__/compiler.test.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`escapeWebpackTemplateString() /some/path/[...slug].js pattern 1`] = `"/some/path/[...slug].js"`; + +exports[`escapeWebpackTemplateString() /some/path/[[...slug]]/index.js pattern 1`] = `"/some/path/[[...slug]]/index.js"`; + +exports[`escapeWebpackTemplateString() /some/path[]/[slug]/[[foo]]/index.js pattern 1`] = `"/some/path[]/[\\slug\\]/[[\\foo\\]]/index.js"`; diff --git a/packages/webpack-plugin/src/compiler.test.ts b/packages/webpack-plugin/src/compiler.test.ts new file mode 100644 index 000000000..82d845885 --- /dev/null +++ b/packages/webpack-plugin/src/compiler.test.ts @@ -0,0 +1,11 @@ +import { escapeWebpackTemplateString } from './compiler'; + +describe('escapeWebpackTemplateString()', () => { + test.each([ + '/some/path/[...slug].js', + '/some/path/[[...slug]]/index.js', + '/some/path[]/[slug]/[[foo]]/index.js', + ])('%s pattern', (filePath) => { + expect(escapeWebpackTemplateString(filePath)).toMatchSnapshot(); + }); +}); From 6f4b38d587177db0bf08e568ffea024efb58a5fe Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:43:37 +1100 Subject: [PATCH 07/11] Add fixture for testing string paths --- fixtures/template-string-paths/index.html | 12 +++++ fixtures/template-string-paths/package.json | 11 +++++ .../src/[...slug]/index.css.ts | 3 ++ .../src/[[...slug]]/index.css.ts | 3 ++ .../src/[[id]]/index.css.ts | 3 ++ .../template-string-paths/src/[]/index.css.ts | 3 ++ .../src/[id]/index.css.ts | 3 ++ fixtures/template-string-paths/src/index.ts | 20 ++++++++ pnpm-lock.yaml | 9 ++++ test-helpers/package.json | 1 + tests/e2e/template-string-paths.playwright.ts | 43 ++++++++++++++++++ ...string-paths-Desktop---Chromium-darwin.png | Bin 0 -> 14614 bytes ...-string-paths-Mobile---Chromium-darwin.png | Bin 0 -> 10426 bytes ...ng-paths-mini-css-extract--development.css | 15 ++++++ ...ing-paths-mini-css-extract--production.css | 15 ++++++ tests/e2e/testCases.ts | 6 ++- 16 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 fixtures/template-string-paths/index.html create mode 100644 fixtures/template-string-paths/package.json create mode 100644 fixtures/template-string-paths/src/[...slug]/index.css.ts create mode 100644 fixtures/template-string-paths/src/[[...slug]]/index.css.ts create mode 100644 fixtures/template-string-paths/src/[[id]]/index.css.ts create mode 100644 fixtures/template-string-paths/src/[]/index.css.ts create mode 100644 fixtures/template-string-paths/src/[id]/index.css.ts create mode 100644 fixtures/template-string-paths/src/index.ts create mode 100644 tests/e2e/template-string-paths.playwright.ts create mode 100644 tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Desktop---Chromium-darwin.png create mode 100644 tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Mobile---Chromium-darwin.png create mode 100644 tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--development.css create mode 100644 tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--production.css diff --git a/fixtures/template-string-paths/index.html b/fixtures/template-string-paths/index.html new file mode 100644 index 000000000..4ede1709c --- /dev/null +++ b/fixtures/template-string-paths/index.html @@ -0,0 +1,12 @@ + + + + + + Vite App + + +
+ + + diff --git a/fixtures/template-string-paths/package.json b/fixtures/template-string-paths/package.json new file mode 100644 index 000000000..74d0146cc --- /dev/null +++ b/fixtures/template-string-paths/package.json @@ -0,0 +1,11 @@ +{ + "name": "@fixtures/template-string-paths", + "version": "0.0.1", + "main": "src/index.ts", + "sideEffects": true, + "author": "SEEK", + "private": true, + "dependencies": { + "@vanilla-extract/css": "1.14.1" + } +} diff --git a/fixtures/template-string-paths/src/[...slug]/index.css.ts b/fixtures/template-string-paths/src/[...slug]/index.css.ts new file mode 100644 index 000000000..f25e11d5b --- /dev/null +++ b/fixtures/template-string-paths/src/[...slug]/index.css.ts @@ -0,0 +1,3 @@ +import { style } from '@vanilla-extract/css'; + +export const catchAllSegment = style({ color: 'lime' }); diff --git a/fixtures/template-string-paths/src/[[...slug]]/index.css.ts b/fixtures/template-string-paths/src/[[...slug]]/index.css.ts new file mode 100644 index 000000000..193a5e36e --- /dev/null +++ b/fixtures/template-string-paths/src/[[...slug]]/index.css.ts @@ -0,0 +1,3 @@ +import { style } from '@vanilla-extract/css'; + +export const optionalCatchAllSegment = style({ color: 'orchid' }); diff --git a/fixtures/template-string-paths/src/[[id]]/index.css.ts b/fixtures/template-string-paths/src/[[id]]/index.css.ts new file mode 100644 index 000000000..70a8e9d58 --- /dev/null +++ b/fixtures/template-string-paths/src/[[id]]/index.css.ts @@ -0,0 +1,3 @@ +import { style } from '@vanilla-extract/css'; + +export const doubleSquareBracketId = style({ color: 'darkkhaki' }); diff --git a/fixtures/template-string-paths/src/[]/index.css.ts b/fixtures/template-string-paths/src/[]/index.css.ts new file mode 100644 index 000000000..5e179bac2 --- /dev/null +++ b/fixtures/template-string-paths/src/[]/index.css.ts @@ -0,0 +1,3 @@ +import { style } from '@vanilla-extract/css'; + +export const emptySquareBrackets = style({ color: 'blue' }); diff --git a/fixtures/template-string-paths/src/[id]/index.css.ts b/fixtures/template-string-paths/src/[id]/index.css.ts new file mode 100644 index 000000000..abdf7c0dc --- /dev/null +++ b/fixtures/template-string-paths/src/[id]/index.css.ts @@ -0,0 +1,3 @@ +import { style } from '@vanilla-extract/css'; + +export const singleSquareBracketsId = style({ color: 'tomato' }); diff --git a/fixtures/template-string-paths/src/index.ts b/fixtures/template-string-paths/src/index.ts new file mode 100644 index 000000000..c70358ac9 --- /dev/null +++ b/fixtures/template-string-paths/src/index.ts @@ -0,0 +1,20 @@ +import { emptySquareBrackets } from './[]/index.css'; +import { singleSquareBracketsId } from './[id]/index.css'; +import { doubleSquareBracketId } from './[[id]]/index.css'; +import { catchAllSegment } from './[...slug]/index.css'; +import { optionalCatchAllSegment } from './[[...slug]]/index.css'; + +// Fixture for testing escaping of webpack template strings and Next.js dyanmic routes +// https://webpack.js.org/configuration/output/#template-strings +// https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes +function render() { + document.body.innerHTML = ` +
[] path
+
[id] path
+
[[id]] path
+
[...slug] path
+
[[...slug]] path
+ `; +} + +render(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a587263c..edce7ef5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -220,6 +220,12 @@ importers: specifier: 1.6.1 version: link:../../packages/sprinkles + fixtures/template-string-paths: + dependencies: + '@vanilla-extract/css': + specifier: 1.14.1 + version: link:../../packages/css + fixtures/themed: dependencies: '@vanilla-extract/css': @@ -682,6 +688,9 @@ importers: '@fixtures/sprinkles': specifier: '*' version: link:../fixtures/sprinkles + '@fixtures/template-string-paths': + specifier: '*' + version: link:../fixtures/template-string-paths '@fixtures/themed': specifier: '*' version: link:../fixtures/themed diff --git a/test-helpers/package.json b/test-helpers/package.json index 036eb5d9a..97ec67182 100644 --- a/test-helpers/package.json +++ b/test-helpers/package.json @@ -12,6 +12,7 @@ "@fixtures/low-level": "*", "@fixtures/recipes": "*", "@fixtures/sprinkles": "*", + "@fixtures/template-string-paths": "*", "@fixtures/themed": "*", "@fixtures/thirdparty": "*", "@fixtures/unused-modules": "*", diff --git a/tests/e2e/template-string-paths.playwright.ts b/tests/e2e/template-string-paths.playwright.ts new file mode 100644 index 000000000..621bc02ee --- /dev/null +++ b/tests/e2e/template-string-paths.playwright.ts @@ -0,0 +1,43 @@ +import { expect } from '@playwright/test'; +import { + getStylesheet, + startFixture, + TestServer, +} from '@vanilla-extract-private/test-helpers'; + +import test from './fixture'; +import { webpack as testCases } from './testCases'; + +testCases.forEach(({ type, mode, snapshotCss = true }) => { + test.describe(`template-string-paths - ${type} (${mode})`, () => { + let server: TestServer; + + test.beforeAll(async ({ port }) => { + server = await startFixture('template-string-paths', { + type, + mode, + basePort: port, + }); + }); + + test('screenshot', async ({ page }) => { + await page.goto(server.url); + + expect(await page.screenshot()).toMatchSnapshot( + 'template-string-paths.png', + ); + }); + + if (snapshotCss) { + test('CSS @agnostic', async () => { + expect( + await getStylesheet(server.url, server.stylesheet), + ).toMatchSnapshot(`template-string-paths-${type}--${mode}.css`); + }); + } + + test.afterAll(async () => { + await server.close(); + }); + }); +}); diff --git a/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Desktop---Chromium-darwin.png b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Desktop---Chromium-darwin.png new file mode 100644 index 0000000000000000000000000000000000000000..bb37654b7367d7b33bee7090227bb62f07bbb857 GIT binary patch literal 14614 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 OLC?DUTJ=ltZ~qS!_7|i8 literal 0 HcmV?d00001 diff --git a/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Mobile---Chromium-darwin.png b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-Mobile---Chromium-darwin.png new file mode 100644 index 0000000000000000000000000000000000000000..d0dc710b6045c52d127663b72693c854c4c908ff GIT binary patch literal 10426 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 literal 0 HcmV?d00001 diff --git a/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--development.css b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--development.css new file mode 100644 index 000000000..ea948545d --- /dev/null +++ b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--development.css @@ -0,0 +1,15 @@ +.\[\]_emptySquareBrackets__13abg9g0 { + color: blue; +} +.\[id\]_singleSquareBracketsId__1d2wsrw0 { + color: tomato; +} +.\[\[id\]\]_doubleSquareBracketId__1aosxxv0 { + color: darkkhaki; +} +.\[\.\.\.slug\]_catchAllSegment__169etlp0 { + color: lime; +} +.\[\[\.\.\.slug\]\]_optionalCatchAllSegment__1kvknas0 { + color: orchid; +} diff --git a/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--production.css b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--production.css new file mode 100644 index 000000000..8327813bf --- /dev/null +++ b/tests/e2e/template-string-paths.playwright.ts-snapshots/template-string-paths-mini-css-extract--production.css @@ -0,0 +1,15 @@ +._13abg9g0 { + color: blue; +} +._1d2wsrw0 { + color: tomato; +} +._1aosxxv0 { + color: darkkhaki; +} +._169etlp0 { + color: lime; +} +._1kvknas0 { + color: orchid; +} diff --git a/tests/e2e/testCases.ts b/tests/e2e/testCases.ts index 5c698d331..6f7486ebc 100644 --- a/tests/e2e/testCases.ts +++ b/tests/e2e/testCases.ts @@ -1,7 +1,11 @@ -export const all = [ +export const webpack = [ { type: 'mini-css-extract', mode: 'development', snapshotCss: true }, { type: 'mini-css-extract', mode: 'production', snapshotCss: true }, { type: 'style-loader', mode: 'development', snapshotCss: false }, +] as const; + +export const all = [ + ...webpack, { type: 'esbuild', mode: 'development', snapshotCss: true }, { type: 'esbuild', mode: 'production', snapshotCss: true }, { type: 'esbuild-runtime', mode: 'development', snapshotCss: false }, From 9c5ecbf606c161925599071d11a00d1efc012134 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:45:32 +1100 Subject: [PATCH 08/11] Define regexp as constant --- packages/webpack-plugin/src/compiler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index 711398688..a38b1933b 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -55,8 +55,10 @@ function getRootCompilation(loader: LoaderContext) { return compilation; } +const templateStringRegexp = /\[([^\[\]\.]+)\]/g; + export const escapeWebpackTemplateString = (s: string) => - s.replaceAll(/\[([^\[\]\.]+)\]/g, '[\\$1\\]'); + s.replaceAll(templateStringRegexp, '[\\$1\\]'); function compileVanillaSource( loader: LoaderContext, From 8860a19cf8d5ba4f2c329c593aca305038fc3500 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:48:42 +1100 Subject: [PATCH 09/11] Add link to next docs --- packages/webpack-plugin/src/compiler.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/webpack-plugin/src/compiler.ts b/packages/webpack-plugin/src/compiler.ts index a38b1933b..59be9c44c 100644 --- a/packages/webpack-plugin/src/compiler.ts +++ b/packages/webpack-plugin/src/compiler.ts @@ -71,7 +71,8 @@ function compileVanillaSource( const compat = createCompat(isWebpack5); // Escape webpack template strings and Next.js dynamic routes in output files so they don't get replaced - // Non-standard escape syntax, see the docs https://webpack.js.org/configuration/output/#template-strings + // Non-standard escape syntax, see https://webpack.js.org/configuration/output/#template-strings + // and https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes const outputOptions = { filename: escapeWebpackTemplateString(loader.resourcePath), }; From f32b2982b7040ad9ea75282dfce244e476f6164e Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:54:48 +1100 Subject: [PATCH 10/11] Update changeset --- .changeset/eleven-oranges-collect.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/eleven-oranges-collect.md b/.changeset/eleven-oranges-collect.md index 38435b5f1..a380a91a0 100644 --- a/.changeset/eleven-oranges-collect.md +++ b/.changeset/eleven-oranges-collect.md @@ -2,6 +2,7 @@ '@vanilla-extract/webpack-plugin': patch --- -Fixes a bug that was causing style compilation to fail on paths containing [webpack template strings] such as `[id]`. +Fixes a bug that was causing style compilation to fail on paths containing [webpack template strings] such as `[id]` or [Next.js dynamic paths] such as `[slug]`. [webpack template strings]: https://webpack.js.org/configuration/output/#template-strings +[next.js dynamic paths]: https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes From fd59ed0388c5498a893f0f24b3e694a7e1ef4743 Mon Sep 17 00:00:00 2001 From: Adam Skoufis Date: Tue, 30 Jan 2024 15:55:35 +1100 Subject: [PATCH 11/11] Update changeset --- .changeset/eleven-oranges-collect.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/eleven-oranges-collect.md b/.changeset/eleven-oranges-collect.md index a380a91a0..eb1e3c9dc 100644 --- a/.changeset/eleven-oranges-collect.md +++ b/.changeset/eleven-oranges-collect.md @@ -2,7 +2,7 @@ '@vanilla-extract/webpack-plugin': patch --- -Fixes a bug that was causing style compilation to fail on paths containing [webpack template strings] such as `[id]` or [Next.js dynamic paths] such as `[slug]`. +Fixes a bug that was causing style compilation to fail on paths containing [webpack template strings] such as `[id]` or [Next.js dynamic routes] such as `[slug]`. [webpack template strings]: https://webpack.js.org/configuration/output/#template-strings -[next.js dynamic paths]: https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes +[next.js dynamic routes]: https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes