diff --git a/crates/pack-schema/src/lib.rs b/crates/pack-schema/src/lib.rs index 0dd8b7db21..c84b615e58 100644 --- a/crates/pack-schema/src/lib.rs +++ b/crates/pack-schema/src/lib.rs @@ -1186,9 +1186,12 @@ pub struct SchemaStyleConfig { #[schemars(description = "CSS Modules configuration")] pub css_modules: Option, - /// Inline PostCSS configuration passed directly to the PostCSS transform + /// Inline PostCSS configuration. Its plugins run after plugins from a discovered config file + /// in the same PostCSS pass. #[serde(skip_serializing_if = "Option::is_none")] - #[schemars(description = "Inline PostCSS configuration")] + #[schemars( + description = "Inline PostCSS configuration appended after a discovered config file" + )] pub postcss: Option, /// Sass configuration diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/config.json b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/config.json new file mode 100644 index 0000000000..43836025f3 --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/config.json @@ -0,0 +1,31 @@ +{ + "config": { + "entry": [ + { + "import": "input/index.js", + "name": "main" + } + ], + "sourceMaps": false, + "styles": { + "postcss": { + "plugins": [ + [ + "postcss-plugin-px2rem", + { + "rootValue": 16, + "unitPrecision": 5, + "replace": true, + "mediaQuery": false, + "minPixelValue": 0 + } + ] + ] + } + }, + "optimization": { + "minify": false, + "moduleIds": "named" + } + } +} diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/index.js b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/index.js new file mode 100644 index 0000000000..a4e51bdb78 --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/index.js @@ -0,0 +1,3 @@ +import "./style.css"; + +console.log("merged postcss config test"); diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/style.css b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/style.css new file mode 100644 index 0000000000..04c2b2c9ee --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/input/style.css @@ -0,0 +1,7 @@ +.merged-postcss { + width: 32px; + + .child { + height: 16px; + } +} diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_index_a847b181.js b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_index_a847b181.js new file mode 100644 index 0000000000..49ab9cb94c --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_index_a847b181.js @@ -0,0 +1,9 @@ +(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([typeof document === "object" ? document.currentScript : undefined, +"[project]/style/merged_postcss_config/input/index.js [client] (ecmascript)", ((__turbopack_context__) => { +"use strict"; + +; +console.log("merged postcss config test"); +__turbopack_context__.s([]); +}), +]); \ No newline at end of file diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_style_e0853100.css b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_style_e0853100.css new file mode 100644 index 0000000000..b724976aae --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/input_style_e0853100.css @@ -0,0 +1,8 @@ +/* [project]/style/merged_postcss_config/input/style.css [client] (css) */ +.merged-postcss { + width: 2rem; +} + +.merged-postcss .child { + height: 1rem; +} \ No newline at end of file diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/main.js b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/main.js new file mode 100644 index 0000000000..95a6df7545 --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/output/main.js @@ -0,0 +1,5 @@ +(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([ + typeof document === "object" ? document.currentScript : undefined, + {"otherChunks":["input_style_e0853100.css","input_index_a847b181.js"],"runtimeModuleIds":["[project]/style/merged_postcss_config/input/index.js [client] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/crates/pack-tests/tests/snapshot/style/merged_postcss_config/postcss.config.js b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/postcss.config.js new file mode 100644 index 0000000000..458cb8c70a --- /dev/null +++ b/crates/pack-tests/tests/snapshot/style/merged_postcss_config/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + "postcss-nested": {}, + }, +}; diff --git a/examples/with-postcss/README.md b/examples/with-postcss/README.md index 420897f271..2d1e9e5796 100644 --- a/examples/with-postcss/README.md +++ b/examples/with-postcss/README.md @@ -1,10 +1,10 @@ # with-postcss -This example demonstrates utoopack's inline `styles.postcss` configuration in -`utoopack.config.mjs`. +This example demonstrates utoopack's merged PostCSS configuration. -It passes `postcss-plugin-px2rem` directly through `utoopack.config.mjs` instead of -using a separate `postcss.config.js` file. +`postcss.config.js` supplies `postcss-nested`, while `styles.postcss.plugins` +supplies `postcss-plugin-px2rem`. Utoopack runs the file plugins first and +appends the inline plugins in the same PostCSS pass. To verify it locally: @@ -13,5 +13,5 @@ npm install npm run dev ``` -Then inspect the emitted CSS and confirm `px` values like `40px`, `32px`, and -`24px` are transformed into `rem` values. +Then inspect the emitted CSS and confirm nested selectors are flattened and `px` +values like `40px`, `32px`, and `24px` are transformed into `rem` values. diff --git a/examples/with-postcss/package.json b/examples/with-postcss/package.json index 939e4ff90f..f41cd1969c 100644 --- a/examples/with-postcss/package.json +++ b/examples/with-postcss/package.json @@ -15,6 +15,7 @@ "@types/react-dom": "^18.2.0", "@utoo/pack-cli": "*", "postcss": "^8.4.31", + "postcss-nested": "^6.2.0", "postcss-plugin-px2rem": "^0.8.1" } } diff --git a/examples/with-postcss/postcss.config.js b/examples/with-postcss/postcss.config.js new file mode 100644 index 0000000000..458cb8c70a --- /dev/null +++ b/examples/with-postcss/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + "postcss-nested": {}, + }, +}; diff --git a/examples/with-postcss/src/index.jsx b/examples/with-postcss/src/index.jsx index b0a20a7bbb..9389558cda 100644 --- a/examples/with-postcss/src/index.jsx +++ b/examples/with-postcss/src/index.jsx @@ -6,13 +6,13 @@ function App() { return (
- PostCSS Inline Config -

px2rem Example

+ PostCSS Merged Config +

postcss-nested + px2rem

- This example uses styles.postcss.plugins in - utoopack.json to pass the{" "} - postcss-plugin-px2rem - plugin directly into utoopack. + This example loads postcss-nested from + postcss.config.js, then appends + postcss-plugin-px2rem from + styles.postcss.plugins.

diff --git a/examples/with-postcss/src/main.css b/examples/with-postcss/src/main.css index e9d40fd972..266200f351 100644 --- a/examples/with-postcss/src/main.css +++ b/examples/with-postcss/src/main.css @@ -51,10 +51,12 @@ code { text-transform: uppercase; } -.hero-card h1 { - margin: 0 0 16px; - font-size: 40px; - line-height: 48px; +.hero-card { + h1 { + margin: 0 0 16px; + font-size: 40px; + line-height: 48px; + } } .lede { @@ -110,9 +112,11 @@ code { padding: 24px; } - .hero-card h1 { - font-size: 32px; - line-height: 38px; + .hero-card { + h1 { + font-size: 32px; + line-height: 38px; + } } .stats-row { diff --git a/next.js b/next.js index 2ed2153232..4e779b42fe 160000 --- a/next.js +++ b/next.js @@ -1 +1 @@ -Subproject commit 2ed21532324f4b6943373ad0f920d2bbdd390b8e +Subproject commit 4e779b42fe9aa4cba7676723b2d42193903fd150 diff --git a/packages/pack-shared/src/config.ts b/packages/pack-shared/src/config.ts index 45598da0c6..b079d1878c 100644 --- a/packages/pack-shared/src/config.ts +++ b/packages/pack-shared/src/config.ts @@ -337,6 +337,10 @@ export interface ConfigComplete { localIdentName?: string; }; emotion?: boolean | EmotionOptions; + /** + * Inline PostCSS configuration. Its plugins run after plugins from a + * discovered postcss.config.* file in the same PostCSS pass. + */ postcss?: JSONValue; less?: { loader?: string; diff --git a/packages/pack/config_schema.json b/packages/pack/config_schema.json index 9ddad127b6..5f4804f4f5 100644 --- a/packages/pack/config_schema.json +++ b/packages/pack/config_schema.json @@ -1960,7 +1960,7 @@ "description": "Less configuration" }, "postcss": { - "description": "Inline PostCSS configuration" + "description": "Inline PostCSS configuration appended after a discovered config file" }, "sass": { "description": "Sass configuration"