diff --git a/packages/next/src/build/webpack/config/blocks/css/index.ts b/packages/next/src/build/webpack/config/blocks/css/index.ts index 198c35cbf0021..2b1b30f865126 100644 --- a/packages/next/src/build/webpack/config/blocks/css/index.ts +++ b/packages/next/src/build/webpack/config/blocks/css/index.ts @@ -254,18 +254,22 @@ export const css = curry(async function css( const shouldIncludeExternalCSSImports = !!ctx.experimental.craCompat || !!ctx.transpilePackages - // CSS modules & SASS modules support. They are allowed to be imported in anywhere. + /** + * CSS modules & SASS modules support. + * They are allowed to be imported in anywhere. + * CSS Modules must NOT be restricted by package.json `sideEffects` due to a webpack bug. + * See https://github.com/webpack/webpack/issues/7094. + * Allows for unused stylesheets to be excluded from production builds. + */ fns.push( - // CSS Modules should never have side effects. This setting will - // allow unused CSS to be removed from the production build. - // We ensure this by disallowing `:global()` CSS at the top-level - // via the `pure` mode in `css-loader`. + /** + * CSS Modules + */ loader({ oneOf: [ // For app dir, we need to match the specific app layer. ctx.hasAppDir ? markRemovable({ - sideEffects: true, test: regexCssModules, issuerLayer: APP_LAYER_RULE, use: [ @@ -285,7 +289,6 @@ export const css = curry(async function css( }) : null, markRemovable({ - sideEffects: true, test: regexCssModules, issuerLayer: PAGES_LAYER_RULE, use: getCssModuleLoader( @@ -295,17 +298,14 @@ export const css = curry(async function css( }), ].filter(nonNullable), }), - // Opt-in support for Sass (using .scss or .sass extensions). - // Sass Modules should never have side effects. This setting will - // allow unused Sass to be removed from the production build. - // We ensure this by disallowing `:global()` Sass at the top-level - // via the `pure` mode in `css-loader`. + /** + * Sass Modules (.scss or .sass) + */ loader({ oneOf: [ // For app dir, we need to match the specific app layer. ctx.hasAppDir ? markRemovable({ - sideEffects: true, test: regexSassModules, issuerLayer: APP_LAYER_RULE, use: [ @@ -326,7 +326,6 @@ export const css = curry(async function css( }) : null, markRemovable({ - sideEffects: true, test: regexSassModules, issuerLayer: PAGES_LAYER_RULE, use: getCssModuleLoader( diff --git a/test/e2e/app-dir/css-order/app/nav.tsx b/test/e2e/app-dir/css-order/app/nav.tsx index 64d9813b0d759..b4122801e3f13 100644 --- a/test/e2e/app-dir/css-order/app/nav.tsx +++ b/test/e2e/app-dir/css-order/app/nav.tsx @@ -85,6 +85,69 @@ export default function Nav() { Vendor +
  • + + Vendor Side Effects All CSS Array + +
  • +
  • + + Vendor Side Effects All CSS Array - Client Components + +
  • +
  • + + Vendor Side Effects All CSS Array - Server Component With Client + Subcomponent + +
  • +
  • + + Vendor Side Effects True + +
  • +
  • + + Vendor Side Effects True - Client Components + +
  • +
  • + + Vendor Side Effects True - Server Component With Client Subcomponent + +
  • +
  • + + Vendor Side Effects False - Client Components + +
  • +
  • + + Vendor Side Effects False + +
  • +
  • + + Vendor Side Effects False - Server Component With Client + Subcomponent + +
  • +
  • + + Vendor Side Effects Global CSS Only Array + +
  • +
  • + + Vendor Side Effects Global CSS Only Array - Client Components + +
  • +
  • + + Vendor Side Effects Global CSS Only Array - Server Component With + Client Subcomponent + +
  • Pages

    ) diff --git a/test/e2e/app-dir/css-order/app/vendor/a/page.tsx b/test/e2e/app-dir/css-order/app/vendor/a/page.tsx new file mode 100644 index 0000000000000..58189f69c10ec --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/a/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsArrayComponent } from 'side-effects-array-dep' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: array + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/b/page.tsx b/test/e2e/app-dir/css-order/app/vendor/b/page.tsx new file mode 100644 index 0000000000000..7f49d5863ca58 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/b/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsComponent } from 'side-effects-dep' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: true + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/c/page.tsx b/test/e2e/app-dir/css-order/app/vendor/c/page.tsx new file mode 100644 index 0000000000000..2c3f720e1f1fe --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/c/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsFalseComponent } from 'side-effects-false-dep' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: false + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/d/page.tsx b/test/e2e/app-dir/css-order/app/vendor/d/page.tsx new file mode 100644 index 0000000000000..cf0604cd6f37b --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/d/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsArrayGlobalComponentClient } from 'side-effects-array-global-only-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: global css array - client + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/e/page.tsx b/test/e2e/app-dir/css-order/app/vendor/e/page.tsx new file mode 100644 index 0000000000000..d4c593707b1e4 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/e/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsArrayComponentClient } from 'side-effects-array-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: array - client components + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/f/page.tsx b/test/e2e/app-dir/css-order/app/vendor/f/page.tsx new file mode 100644 index 0000000000000..25fc0beb2dcb7 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/f/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsArrayComponentWithClientSubcomponent } from 'side-effects-array-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: array - server component with client subcomponent + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/g/page.tsx b/test/e2e/app-dir/css-order/app/vendor/g/page.tsx new file mode 100644 index 0000000000000..bddb33b94b49c --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/g/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsComponentClient } from 'side-effects-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: true - client + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/h/page.tsx b/test/e2e/app-dir/css-order/app/vendor/h/page.tsx new file mode 100644 index 0000000000000..abe4380ca0626 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/h/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsComponentWithClientSubcomponent } from 'side-effects-dep/index-server-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: true - server component with client subcomponent + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/i/page.tsx b/test/e2e/app-dir/css-order/app/vendor/i/page.tsx new file mode 100644 index 0000000000000..355723628f1d1 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/i/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsFalseComponentClient } from 'side-effects-false-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: false - client + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/j/page.tsx b/test/e2e/app-dir/css-order/app/vendor/j/page.tsx new file mode 100644 index 0000000000000..be97f41c92a21 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/j/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsFalseComponentWithClientSubcomponent } from 'side-effects-false-dep/index-server-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: false - server component with client subcomponent + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/k/page.tsx b/test/e2e/app-dir/css-order/app/vendor/k/page.tsx new file mode 100644 index 0000000000000..deda75b243eee --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/k/page.tsx @@ -0,0 +1,13 @@ +import { SideEffectsArrayGlobalComponentClient } from 'side-effects-array-global-only-dep/index-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: global css array + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/l/page.tsx b/test/e2e/app-dir/css-order/app/vendor/l/page.tsx new file mode 100644 index 0000000000000..053d7f32fac82 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/l/page.tsx @@ -0,0 +1,14 @@ +import { SideEffectsArrayGlobalComponentWithClientSubcomponent } from 'side-effects-array-global-only-dep/index-server-client' +import Nav from '../../nav' + +export default function Page() { + return ( +
    + + side effects: global css array - server component with client + subcomponent + +
    + ) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.css new file mode 100644 index 0000000000000..68ffd6236a0b3 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.css @@ -0,0 +1,4 @@ +.side-effects-array-client { + background-color: rgb(254, 254, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.js new file mode 100644 index 0000000000000..92e4db28b28bb --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.js @@ -0,0 +1,18 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponentClient } from './subcomponent-client.js' +import './index-client.css' +import styles from './index-client.module.css' + +export function SideEffectsArrayComponentClient({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(ArraySubcomponentClient, { + ...props, + className: `${styles.array_dep_client} side-effects-array-client ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.module.css new file mode 100644 index 0000000000000..8c163ac8e6f62 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-client.module.css @@ -0,0 +1,3 @@ +.array_dep_client { + color: rgb(254, 254, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-server-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-server-client.js new file mode 100644 index 0000000000000..ccdad3599ce6a --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index-server-client.js @@ -0,0 +1,16 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponentClient } from './subcomponent-client.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsArrayComponentWithClientSubcomponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(ArraySubcomponentClient, { + ...props, + className: `${styles.array_dep} side-effects-array ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.css new file mode 100644 index 0000000000000..a527ad4826888 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.css @@ -0,0 +1,4 @@ +.side-effects-array { + background-color: rgb(0, 254, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.js new file mode 100644 index 0000000000000..37a717b55f2c8 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.js @@ -0,0 +1,12 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponent } from './subcomponent.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsArrayComponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx(ArraySubcomponent, { + ...props, + className: `${styles.array_dep} side-effects-array ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.module.css new file mode 100644 index 0000000000000..08e745329ba80 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/index.module.css @@ -0,0 +1,3 @@ +.array_dep { + color: rgb(254, 0, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/package.json b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/package.json new file mode 100644 index 0000000000000..58612984321ad --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/package.json @@ -0,0 +1,7 @@ +{ + "name": "side-effects-array-dep", + "sideEffects": [ + "*.css" + ], + "version": "1.0.0" +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.css new file mode 100644 index 0000000000000..89ef2fe3f9d1e --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.css @@ -0,0 +1,4 @@ +.side-effects-array-client { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.js new file mode 100644 index 0000000000000..ffb885f30b8e7 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.js @@ -0,0 +1,13 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent-client.css' +import styles from './subcomponent-client.module.css' + +export function ArraySubcomponentClient({ children, className, ...props }) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.array_dep_subcomponent_client} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.module.css new file mode 100644 index 0000000000000..37f234fdaddbf --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent-client.module.css @@ -0,0 +1,3 @@ +.array_dep_subcomponent_client { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.css new file mode 100644 index 0000000000000..11c7723b6c4bf --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.css @@ -0,0 +1,4 @@ +.side-effects-array { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.js new file mode 100644 index 0000000000000..bf14bcdf1a92a --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.js @@ -0,0 +1,11 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent.css' +import styles from './subcomponent.module.css' + +export function ArraySubcomponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.array_dep_subcomponent} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.module.css new file mode 100644 index 0000000000000..8e089d3d09912 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-dep/subcomponent.module.css @@ -0,0 +1,3 @@ +.array_dep_subcomponent { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.css new file mode 100644 index 0000000000000..82da50e5df69e --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.css @@ -0,0 +1,4 @@ +.side-effects-array-global-only-client { + background-color: rgb(250, 250, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.js new file mode 100644 index 0000000000000..9e0fff29288f7 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.js @@ -0,0 +1,18 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponentClient } from './subcomponent-client.js' +import './index-client.css' +import styles from './index-client.module.css' + +export function SideEffectsArrayGlobalComponentClient({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(ArraySubcomponentClient, { + ...props, + className: `${styles.array_global_dep_client} side-effects-array-global-only-client ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.module.css new file mode 100644 index 0000000000000..86ce54d221c46 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-client.module.css @@ -0,0 +1,3 @@ +.array_global_dep_client { + color: rgb(250, 250, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-server-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-server-client.js new file mode 100644 index 0000000000000..df1326eecd50e --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index-server-client.js @@ -0,0 +1,16 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponentClient } from './subcomponent-client.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsArrayGlobalComponentWithClientSubcomponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(ArraySubcomponentClient, { + ...props, + className: `${styles.array_global_dep_client} side-effects-array-global-only ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.css new file mode 100644 index 0000000000000..43e3fab7fa7c6 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.css @@ -0,0 +1,4 @@ +.side-effects-array-global-only { + background-color: rgb(0, 250, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.js new file mode 100644 index 0000000000000..2f48db61dbf99 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.js @@ -0,0 +1,16 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { ArraySubcomponent } from './subcomponent.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsArrayGlobalComponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(ArraySubcomponent, { + ...props, + className: `${styles.array_global_dep} side-effects-array-global-only ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.module.css new file mode 100644 index 0000000000000..d906a4b637c93 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/index.module.css @@ -0,0 +1,3 @@ +.array_global_dep { + color: rgb(250, 0, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/package.json b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/package.json new file mode 100644 index 0000000000000..1961e461be84d --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/package.json @@ -0,0 +1,8 @@ +{ + "name": "side-effects-array-global-only-dep", + "sideEffects": [ + "index.css", + "subcomponent.css" + ], + "version": "1.0.0" +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.css new file mode 100644 index 0000000000000..66bf30d65af6a --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.css @@ -0,0 +1,4 @@ +.side-effects-array-global-only-client { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.js new file mode 100644 index 0000000000000..446603d7acb54 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.js @@ -0,0 +1,13 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent-client.css' +import styles from './subcomponent-client.module.css' + +export function ArraySubcomponentClient({ children, className, ...props }) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.array_global_dep_subcomponent_client} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.module.css new file mode 100644 index 0000000000000..be36b2f83efcf --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent-client.module.css @@ -0,0 +1,3 @@ +.array_global_dep_subcomponent_client { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.css new file mode 100644 index 0000000000000..b0b454de99268 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.css @@ -0,0 +1,4 @@ +.side-effects-array-global-only { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.js new file mode 100644 index 0000000000000..9b3477773c3bf --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.js @@ -0,0 +1,11 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent.css' +import styles from './subcomponent.module.css' + +export function ArraySubcomponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.array_global_dep_subcomponent} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.module.css new file mode 100644 index 0000000000000..8cc7ca3544ed3 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-array-global-only-dep/subcomponent.module.css @@ -0,0 +1,3 @@ +.array_global_dep_subcomponent { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.css new file mode 100644 index 0000000000000..0b37e2a7946e5 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.css @@ -0,0 +1,4 @@ +.side-effects-true-client { + background-color: rgb(253, 253, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.js new file mode 100644 index 0000000000000..f5f10713fed4e --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.js @@ -0,0 +1,14 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsSubcomponentClient } from './subcomponent-client.js' +import './index-client.css' +import styles from './index-client.module.css' + +export function SideEffectsComponentClient({ children, className, ...props }) { + return /*#__PURE__*/ _jsx(SideEffectsSubcomponentClient, { + ...props, + className: `${styles.side_effects_dep_client} side-effects-true-client ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.module.css new file mode 100644 index 0000000000000..8cc4177782f42 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-client.module.css @@ -0,0 +1,3 @@ +.side_effects_dep_client { + color: rgb(253, 253, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-server-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-server-client.js new file mode 100644 index 0000000000000..34d096cbfab9a --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index-server-client.js @@ -0,0 +1,16 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsSubcomponentClient } from './subcomponent-client.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsComponentWithClientSubcomponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(SideEffectsSubcomponentClient, { + ...props, + className: `${styles.side_effects_dep} side-effects-true ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.css new file mode 100644 index 0000000000000..88c74b467893b --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.css @@ -0,0 +1,4 @@ +.side-effects-true { + background-color: rgb(0, 253, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.js new file mode 100644 index 0000000000000..ae220a75b0f4e --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.js @@ -0,0 +1,12 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsSubcomponent } from './subcomponent' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsComponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx(SideEffectsSubcomponent, { + ...props, + className: `${styles.side_effects_dep} side-effects-true ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.module.css new file mode 100644 index 0000000000000..220f6d9e25d16 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/index.module.css @@ -0,0 +1,3 @@ +.side_effects_dep { + color: rgb(253, 0, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/package.json b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/package.json new file mode 100644 index 0000000000000..9d9124ba63ae3 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/package.json @@ -0,0 +1,5 @@ +{ + "name": "side-effects-dep", + "sideEffects": true, + "version": "1.0.0" +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.css new file mode 100644 index 0000000000000..3804ba1fc2651 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.css @@ -0,0 +1,4 @@ +.side-effects-true-client { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.js new file mode 100644 index 0000000000000..3c85e44e05a35 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.js @@ -0,0 +1,17 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent-client.css' +import styles from './subcomponent-client.module.css' + +export function SideEffectsSubcomponentClient({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.side_effects_dep_subcomponent_client} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.module.css new file mode 100644 index 0000000000000..612e1989e73b8 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent-client.module.css @@ -0,0 +1,3 @@ +.side_effects_dep_subcomponent_client { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.css new file mode 100644 index 0000000000000..0ab0827961124 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.css @@ -0,0 +1,4 @@ +.side-effects-true { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.js new file mode 100644 index 0000000000000..1a39bf11fb578 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.js @@ -0,0 +1,11 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent.css' +import styles from './subcomponent.module.css' + +export function SideEffectsSubcomponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.side_effects_dep_subcomponent} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.module.css new file mode 100644 index 0000000000000..e632833b56e9b --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-dep/subcomponent.module.css @@ -0,0 +1,3 @@ +.side_effects_dep_subcomponent { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.css new file mode 100644 index 0000000000000..568dc5f8b7d08 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.css @@ -0,0 +1,4 @@ +.side-effects-false-client { + background-color: rgb(252, 252, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.js new file mode 100644 index 0000000000000..95fcb7a1e5df4 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.js @@ -0,0 +1,18 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsFalseSubcomponentClient } from './subcomponent-client.js' +import './index-client.css' +import styles from './index-client.module.css' + +export function SideEffectsFalseComponentClient({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(SideEffectsFalseSubcomponentClient, { + ...props, + className: `${styles.side_effects_false_dep_client} side-effects-false-client ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.module.css new file mode 100644 index 0000000000000..46de3edf3e8ae --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-client.module.css @@ -0,0 +1,3 @@ +.side_effects_false_dep_client { + color: rgb(252, 252, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-server-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-server-client.js new file mode 100644 index 0000000000000..2b0a369f43ce3 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index-server-client.js @@ -0,0 +1,16 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsFalseSubcomponentClient } from './subcomponent-client.js' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsFalseComponentWithClientSubcomponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx(SideEffectsFalseSubcomponentClient, { + ...props, + className: `${styles.side_effects_false_dep} side-effects-false ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.css new file mode 100644 index 0000000000000..e54d94826d79a --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.css @@ -0,0 +1,4 @@ +.side-effects-false { + background-color: rgb(0, 252, 0); + color: rgb(0, 255, 255); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.js new file mode 100644 index 0000000000000..d364194ad84e0 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.js @@ -0,0 +1,12 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import { SideEffectsFalseSubcomponent } from './subcomponent' +import './index.css' +import styles from './index.module.css' + +export function SideEffectsFalseComponent({ children, className, ...props }) { + return /*#__PURE__*/ _jsx(SideEffectsFalseSubcomponent, { + ...props, + className: `${styles.side_effects_false_dep} side-effects-false ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.module.css new file mode 100644 index 0000000000000..d462706d192ff --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/index.module.css @@ -0,0 +1,3 @@ +.side_effects_false_dep { + color: rgb(252, 0, 0); +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/package.json b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/package.json new file mode 100644 index 0000000000000..0c5b33f636765 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/package.json @@ -0,0 +1,5 @@ +{ + "name": "side-effects-false-dep", + "sideEffects": false, + "version": "1.0.0" +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.css new file mode 100644 index 0000000000000..24e9603485bff --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.css @@ -0,0 +1,4 @@ +.side-effects-false-client { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.js new file mode 100644 index 0000000000000..291c7f73e8ee8 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.js @@ -0,0 +1,17 @@ +'use client' + +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent-client.css' +import styles from './subcomponent-client.module.css' + +export function SideEffectsFalseSubcomponentClient({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.side_effects_false_dep_subcomponent_client} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.module.css new file mode 100644 index 0000000000000..4b68665dfe3ad --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent-client.module.css @@ -0,0 +1,3 @@ +.side_effects_false_dep_subcomponent_client { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.css new file mode 100644 index 0000000000000..20c038971813b --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.css @@ -0,0 +1,4 @@ +.side-effects-false { + background-color: teal; + color: teal; +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.js b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.js new file mode 100644 index 0000000000000..f5c1663d8bb5c --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.js @@ -0,0 +1,15 @@ +import { jsx as _jsx } from 'react/jsx-runtime' +import './subcomponent.css' +import styles from './subcomponent.module.css' + +export function SideEffectsFalseSubcomponent({ + children, + className, + ...props +}) { + return /*#__PURE__*/ _jsx('a', { + ...props, + className: `${styles.side_effects_false_dep_subcomponent} ${className ?? ''}`, + children: children, + }) +} diff --git a/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.module.css b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.module.css new file mode 100644 index 0000000000000..adecee6459545 --- /dev/null +++ b/test/e2e/app-dir/css-order/app/vendor/node_modules/side-effects-false-dep/subcomponent.module.css @@ -0,0 +1,3 @@ +.side_effects_false_dep_subcomponent { + color: blue; +} diff --git a/test/e2e/app-dir/css-order/css-order.test.ts b/test/e2e/app-dir/css-order/css-order.test.ts index 2ef5fb9c487b7..dd1ce13bac7b8 100644 --- a/test/e2e/app-dir/css-order/css-order.test.ts +++ b/test/e2e/app-dir/css-order/css-order.test.ts @@ -136,7 +136,6 @@ const PAGES: Record< selector: '#hello3', color: 'rgb(0, 128, 128)', }, - 'pages-interleaved-a': { group: 'pages-interleaved', brokenLoadingDev: true, @@ -205,6 +204,210 @@ const PAGES: Record< }, } +const SIDE_EFFECTS_PAGES: Record< + string, + { + url: string + selector: string + color: string + background?: string + skip?: Array<'turbo' | 'loose' | 'strict'> + } +> = { + 'vendor-side-effects-array': { + url: '/vendor/a', + selector: '#vendor-side-effects-array', + background: 'rgb(0, 254, 0)', + color: 'rgb(254, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'vendor-side-effects-array-client': { + url: '/vendor/e', + selector: '#vendor-side-effects-array-client', + background: 'rgb(254, 254, 0)', + color: 'rgb(254, 254, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'vendor-side-effects-array-server-client': { + url: '/vendor/f', + selector: '#vendor-side-effects-array-server-client-subcomponent', + background: 'rgb(0, 254, 0)', + color: 'rgb(254, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'vendor-side-effects-true': { + url: '/vendor/b', + selector: '#vendor-side-effects-true', + background: 'rgb(0, 253, 0)', + color: 'rgb(253, 0, 0)', + }, + 'vendor-side-effects-true-client': { + url: '/vendor/g', + selector: '#vendor-side-effects-true-client', + background: 'rgb(253, 253, 0)', + color: 'rgb(253, 253, 0)', + }, + 'vendor-side-effects-true-server-client': { + url: '/vendor/h', + selector: '#vendor-side-effects-true-server-client-subcomponent', + background: 'rgb(0, 253, 0)', + color: 'rgb(253, 0, 0)', + }, + 'vendor-side-effects-false': { + url: '/vendor/c', + selector: '#vendor-side-effects-false', + background: 'rgb(0, 252, 0)', + color: 'rgb(252, 0, 0)', + /** + * Turbopack has buttoned up a webpack bug. + * Packages *should* side-effect css modules, but webpack doesn't retain + * the proper import order context of css modules in libraries within + * node_modules when side-effects is set to true. + * Related webpack bug: https://github.com/webpack/webpack/issues/7094 + */ + skip: ['turbo'], + }, + 'vendor-side-effects-false-client': { + url: '/vendor/i', + selector: '#vendor-side-effects-false-client', + background: 'rgb(252, 252, 0)', + color: 'rgb(252, 252, 0)', + /** + * Turbopack has buttoned up a webpack bug. + * Packages *should* side-effect css modules, but webpack doesn't retain + * the proper import order context of css modules in libraries within + * node_modules when side-effects is set to true. + * Related webpack bug: https://github.com/webpack/webpack/issues/7094 + */ + skip: ['turbo'], + }, + 'vendor-side-effects-false-server-client': { + url: '/vendor/j', + selector: '#vendor-side-effects-false-server-client-subcomponent', + background: 'rgb(0, 253, 0)', + color: 'rgb(253, 0, 0)', + /** + * Turbopack has buttoned up a webpack bug. + * Packages *should* side-effect css modules, but webpack doesn't retain + * the proper import order context of css modules in libraries within + * node_modules when side-effects is set to true. + * Related webpack bug: https://github.com/webpack/webpack/issues/7094 + */ + skip: ['turbo'], + }, + 'vendor-side-effects-global-array': { + url: '/vendor/d', + selector: '#vendor-side-effects-global-array', + background: 'rgb(0, 250, 0)', + color: 'rgb(250, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'vendor-side-effects-global-array-client': { + url: '/vendor/k', + selector: '#vendor-side-effects-global-array-client', + background: 'rgb(250, 250, 0)', + color: 'rgb(250, 250, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'vendor-side-effects-global-array-server-client': { + url: '/vendor/k', + selector: '#vendor-side-effects-global-array-server-client', + background: 'rgb(0, 250, 0)', + color: 'rgb(250, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, + 'pages-vendor-side-effects-array': { + url: 'pages/vendor/a', + selector: '#vendor-side-effects-array', + background: 'rgb(0, 254, 0)', + color: 'rgb(254, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + * + * WEBPACK: css modules are inconsistent when included as sideEffects + * when not Boolean `true` or `false` + */ + skip: ['turbo', 'loose', 'strict'], + }, + 'pages-vendor-side-effects-true': { + url: 'pages/vendor/b', + selector: '#vendor-side-effects-true', + background: 'rgb(0, 253, 0)', + color: 'rgb(253, 0, 0)', + }, + 'pages-vendor-side-effects-false': { + url: 'pages/vendor/c', + selector: '#vendor-side-effects-false', + /** + * with side-effects=false set in a library, global css no longer loads + * in the correct order. + * `background` assertions will be unstable in turbo AND webpack + */ + // background: 'rgb(0, 252, 0), + color: 'rgb(252, 0, 0)', + /** + * Turbopack has buttoned up a webpack bug. + * Packages *should* side-effect css modules, but webpack doesn't retain + * the proper import order context of css modules in libraries within + * node_modules when side-effects is set to true. + * Related webpack bug: https://github.com/webpack/webpack/issues/7094 + */ + skip: ['turbo'], + }, + 'pages-vendor-side-effects-global-array': { + url: '/vendor/d', + selector: '#vendor-side-effects-global-array', + background: 'rgb(0, 250, 0)', + color: 'rgb(250, 0, 0)', + /** + * TURBOPACK: This should be supported by turbo but does not appear to be today, + * because the emitted rules are not in the correct order when this is set. + * Results are inconsistent so we cannot reliably test against without + * removing this skip... + */ + skip: ['turbo'], + }, +} + const allPairs = getPairs(Object.keys(PAGES)) const options = (mode: string) => ({ @@ -226,6 +429,7 @@ const options = (mode: string) => ({ }, skipDeployment: true, }) + describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( 'css-order %s', (mode: string) => { @@ -320,6 +524,14 @@ describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( .waitForElementByCss(pageInfo.selector) .getComputedCss('color') ).toBe(pageInfo.color) + + if (pageInfo.background) { + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('background-color') + ).toBe(pageInfo.background) + } } const navigate = async (page) => { await browser.waitForElementByCss('#' + page).click() @@ -351,6 +563,43 @@ describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( .waitForElementByCss(pageInfo.selector) .getComputedCss('color') ).toBe(pageInfo.color) + if (pageInfo.background) { + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('background-color') + ).toBe(pageInfo.background) + } + await browser.close() + }) + } + } +) + +describe.each(process.env.TURBOPACK ? ['turbo'] : ['strict', 'loose'])( + 'css-order %s', + (mode: 'turbo' | 'strict' | 'loose') => { + const { next } = nextTestSetup(options(mode)) + for (const [page, pageInfo] of Object.entries(SIDE_EFFECTS_PAGES)) { + const name = `should load correct styles on ${page}` + if (pageInfo.skip?.includes(mode)) { + // Allow skip for valid (and documented) reasons. + continue + } + it(name, async () => { + const browser = await next.browser(pageInfo.url) + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('color') + ).toBe(pageInfo.color) + if (pageInfo.background) { + expect( + await browser + .waitForElementByCss(pageInfo.selector) + .getComputedCss('background-color') + ).toBe(pageInfo.background) + } await browser.close() }) } diff --git a/test/e2e/app-dir/css-order/pages/pages/vendor/a.js b/test/e2e/app-dir/css-order/pages/pages/vendor/a.js new file mode 100644 index 0000000000000..14541649313c9 --- /dev/null +++ b/test/e2e/app-dir/css-order/pages/pages/vendor/a.js @@ -0,0 +1 @@ +export { default } from '../../../app/vendor/a/page' diff --git a/test/e2e/app-dir/css-order/pages/pages/vendor/b.js b/test/e2e/app-dir/css-order/pages/pages/vendor/b.js new file mode 100644 index 0000000000000..d8a6eee6eb8ce --- /dev/null +++ b/test/e2e/app-dir/css-order/pages/pages/vendor/b.js @@ -0,0 +1 @@ +export { default } from '../../../app/vendor/b/page' diff --git a/test/e2e/app-dir/css-order/pages/pages/vendor/c.js b/test/e2e/app-dir/css-order/pages/pages/vendor/c.js new file mode 100644 index 0000000000000..80b87c5265f6f --- /dev/null +++ b/test/e2e/app-dir/css-order/pages/pages/vendor/c.js @@ -0,0 +1 @@ +export { default } from '../../../app/vendor/c/page' diff --git a/test/e2e/app-dir/css-order/pages/pages/vendor/d.js b/test/e2e/app-dir/css-order/pages/pages/vendor/d.js new file mode 100644 index 0000000000000..670a5083acec4 --- /dev/null +++ b/test/e2e/app-dir/css-order/pages/pages/vendor/d.js @@ -0,0 +1 @@ +export { default } from '../../../app/vendor/d/page'