From ef1522075f6fcc7412abb65c1d9c9e1af347ebcc Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Wed, 29 Dec 2021 19:18:55 +0100 Subject: [PATCH 1/7] Test website CSS ordering --- website/_dogfooding/clientModuleCSS.css | 11 +++ website/_dogfooding/dogfooding.config.js | 12 +++ website/docusaurus.config.js | 1 - website/package.json | 5 +- website/src/css/custom.css | 5 ++ website/src/pages/styles.module.css | 5 ++ website/src/theme/Layout/index.tsx | 17 ++++ website/src/theme/Layout/styles.module.css | 12 +++ website/testCSSOrder.js | 92 ++++++++++++++++++++++ 9 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 website/_dogfooding/clientModuleCSS.css create mode 100644 website/src/theme/Layout/index.tsx create mode 100644 website/src/theme/Layout/styles.module.css create mode 100644 website/testCSSOrder.js diff --git a/website/_dogfooding/clientModuleCSS.css b/website/_dogfooding/clientModuleCSS.css new file mode 100644 index 000000000000..f67bf88354bc --- /dev/null +++ b/website/_dogfooding/clientModuleCSS.css @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* Used to test CSS insertion order */ +.test-marker-site-client-module { + content: "site-client-module"; +} diff --git a/website/_dogfooding/dogfooding.config.js b/website/_dogfooding/dogfooding.config.js index 89eb42620bba..84832cbfc935 100644 --- a/website/_dogfooding/dogfooding.config.js +++ b/website/_dogfooding/dogfooding.config.js @@ -55,6 +55,18 @@ const dogfoodingPluginInstances = [ routeBasePath: '/tests/pages', }), ], + + /** @type {import('@docusaurus/types').Plugin} */ + function clientModuleTestPlugin() { + return { + getClientModules() { + return [ + require.resolve('./clientModuleExample.ts'), + require.resolve('./clientModuleCSS.css'), + ]; + }, + }; + }, ]; exports.dogfoodingPluginInstances = dogfoodingPluginInstances; diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 97fa7cb81e49..3a7771fcac38 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -118,7 +118,6 @@ const config = { 'static', path.join(__dirname, '_dogfooding/_asset-tests'), ], - clientModules: [require.resolve('./_dogfooding/clientModuleExample.ts')], themes: ['live-codeblock'], plugins: [ FeatureRequestsPlugin, diff --git a/website/package.json b/website/package.json index fe12088a585c..b238649abb58 100644 --- a/website/package.json +++ b/website/package.json @@ -10,6 +10,7 @@ "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", + "test:css-order": "node testCSSOrder.js", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "start:baseUrl": "cross-env BASE_URL='/build/' yarn start", @@ -17,8 +18,8 @@ "start:blogOnly": "cross-env yarn start --config=docusaurus.config-blog-only.js", "build:blogOnly": "cross-env yarn build --config=docusaurus.config-blog-only.js", "build:fast": "cross-env BUILD_FAST=true yarn build --locale en", - "netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build", - "netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build", + "netlify:build:production": "yarn docusaurus write-translations && yarn netlify:crowdin:delay && yarn netlify:crowdin:uploadSources && yarn netlify:crowdin:downloadTranslations && yarn build && yarn test:css-order", + "netlify:build:deployPreview": "yarn docusaurus write-translations --locale fr --messagePrefix '(fr) ' && yarn build && yarn test:css-order", "netlify:crowdin:delay": "node delayCrowdin.js", "netlify:crowdin:wait": "node waitForCrowdin.js", "netlify:crowdin:downloadTranslations": "yarn netlify:crowdin:wait && yarn --cwd .. crowdin:download:website", diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 38afeb295fc0..ce2b9611a546 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -171,3 +171,8 @@ div[class^='announcementBar_'] { width: 1px; white-space: nowrap; } + +/* Used to test CSS insertion order */ +.test-marker-site-custom-css { + content: "site-custom-css"; +} diff --git a/website/src/pages/styles.module.css b/website/src/pages/styles.module.css index 3366f9779c8e..76c8e98728cc 100644 --- a/website/src/pages/styles.module.css +++ b/website/src/pages/styles.module.css @@ -153,3 +153,8 @@ display: none; } } + +/* Used to test CSS insertion order */ +.test-marker-site-index-page { + content: "site-index-page"; +} diff --git a/website/src/theme/Layout/index.tsx b/website/src/theme/Layout/index.tsx new file mode 100644 index 000000000000..78f03a793f88 --- /dev/null +++ b/website/src/theme/Layout/index.tsx @@ -0,0 +1,17 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import type {Props} from '@theme/Layout'; +import Layout from '@theme-original/Layout'; + +// This component is only used to test for CSS insertion order +import './styles.module.css'; + +export default function LayoutWrapper(props: Props): JSX.Element { + return ; +} diff --git a/website/src/theme/Layout/styles.module.css b/website/src/theme/Layout/styles.module.css new file mode 100644 index 000000000000..c3c0ab8bdb06 --- /dev/null +++ b/website/src/theme/Layout/styles.module.css @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* Used to test CSS insertion order */ +.test-marker-theme-layout { + content: "theme-layout"; +} + diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js new file mode 100644 index 000000000000..78f267fd6f97 --- /dev/null +++ b/website/testCSSOrder.js @@ -0,0 +1,92 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const path = require('path'); +const fs = require('fs'); + +/* +This verifies CSS ordering on the Docusaurus site itself, + +There are multiple ways to provide some CSS to Docusaurus +and Docusaurus should guarantee a consistent CSS ordering over time + +See also +- https://github.com/facebook/docusaurus/issues/3678 +- https://github.com/facebook/docusaurus/pull/5987 + +TODO we should probably add a real e2e test in core instead of using our own website? +Current solution looks good-enough for now + + */ + +// TODO temporary, the current order is bad and we should change that +const EXPECTED_MARKER_CLASSES = [ + '.test-marker-site-custom-css', + '.test-marker-site-client-module', + '.test-marker-theme-layout', + '.test-marker-site-index-page', +]; + +const cssDirName = path.join(__dirname, 'build', 'assets', 'css'); + +const cssFileNames = fs + .readdirSync(cssDirName) + .filter((file) => file.endsWith('.css')); + +if (cssFileNames.length !== 1) { + throw new Error('unexpected: more than 1 css file'); +} +const cssFile = path.join(cssDirName, cssFileNames[0]); + +console.log('Inspecting CSS file for test CSS markers', cssFile); + +const cssFileContent = fs.readFileSync(cssFile, 'utf8'); + +const cssMarkersWithPositions = EXPECTED_MARKER_CLASSES.map((marker) => { + const position = cssFileContent.indexOf(marker); + return {marker, position}; +}); + +const missingCSSMarkers = cssMarkersWithPositions.filter( + (m) => m.position === -1, +); + +if (missingCSSMarkers.length > 0) { + throw new Error( + `Some expected CSS marker classes could not be found in file ${cssFile}: \n- ${missingCSSMarkers.join( + '\n- ', + )}`, + ); +} + +// https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_sortby-and-_orderby +const sortBy = (key) => (a, b) => + // eslint-disable-next-line no-nested-ternary + a[key] > b[key] ? 1 : b[key] > a[key] ? -1 : 0; + +const sortedCSSMarkers = cssMarkersWithPositions + .concat() + .sort(sortBy('position')) + .map(({marker}) => marker); + +if ( + JSON.stringify(sortedCSSMarkers) === JSON.stringify(EXPECTED_MARKER_CLASSES) +) { + console.log(`Test CSS markers were found in the expected order: +- ${sortedCSSMarkers.join('\n- ')}`); +} else { + throw new Error(`Test CSS markers were found in an incorrect order. + +Expected order: +- ${EXPECTED_MARKER_CLASSES.join('\n- ')}; + +Actual order: +- ${sortedCSSMarkers.join('\n- ')}; + +CSS file: ${cssFile} + `); +} From bd2947b4ea07285b7d2b6e8213b392028dfcfaec Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 10:27:20 +0100 Subject: [PATCH 2/7] Add some infima classes to the CSS order test --- website/testCSSOrder.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js index 78f267fd6f97..71835a086f59 100644 --- a/website/testCSSOrder.js +++ b/website/testCSSOrder.js @@ -25,6 +25,17 @@ Current solution looks good-enough for now // TODO temporary, the current order is bad and we should change that const EXPECTED_MARKER_CLASSES = [ + // Some class from Infima, in the order Infima declares them + // this ensures we don't mess-up and re-order css from other libs + '.navbar__title', + ".col[class*='col--']", // TODO Should be after paddings + '.padding-vert--xl', + '.footer__link-item', // TODO should be last + '.pagination__item', + '.pills__item', + '.tabs__item', + + // Test markers '.test-marker-site-custom-css', '.test-marker-site-client-module', '.test-marker-theme-layout', From 1684b0707fae7683269d823e01b61a53dac5f89e Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 10:40:45 +0100 Subject: [PATCH 3/7] fix error message --- website/testCSSOrder.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js index 71835a086f59..ddf48cf2f172 100644 --- a/website/testCSSOrder.js +++ b/website/testCSSOrder.js @@ -62,9 +62,9 @@ const cssMarkersWithPositions = EXPECTED_MARKER_CLASSES.map((marker) => { return {marker, position}; }); -const missingCSSMarkers = cssMarkersWithPositions.filter( - (m) => m.position === -1, -); +const missingCSSMarkers = cssMarkersWithPositions + .filter((m) => m.position === -1) + .map((m) => m.marker); if (missingCSSMarkers.length > 0) { throw new Error( From b08783b709c0e85e5d74f34d13c59c8e3ce318a3 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 10:42:48 +0100 Subject: [PATCH 4/7] fix infima classname --- website/testCSSOrder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js index ddf48cf2f172..1885bbc89c22 100644 --- a/website/testCSSOrder.js +++ b/website/testCSSOrder.js @@ -28,7 +28,7 @@ const EXPECTED_MARKER_CLASSES = [ // Some class from Infima, in the order Infima declares them // this ensures we don't mess-up and re-order css from other libs '.navbar__title', - ".col[class*='col--']", // TODO Should be after paddings + '.col[class*=col--]', // TODO Should be after paddings '.padding-vert--xl', '.footer__link-item', // TODO should be last '.pagination__item', From 3bbe21d76405f6eb1fa5aff18e30c75ac562e5c7 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 10:59:14 +0100 Subject: [PATCH 5/7] Add more CSS order test classes --- website/src/css/custom.css | 5 ++++- website/testCSSOrder.js | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/website/src/css/custom.css b/website/src/css/custom.css index ce2b9611a546..3a892c83831d 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -173,6 +173,9 @@ div[class^='announcementBar_'] { } /* Used to test CSS insertion order */ -.test-marker-site-custom-css { +.test-marker-site-custom-css-unique-rule { content: "site-custom-css"; } +.test-marker-site-custom-css-shared-rule { + max-width: 100%; +} diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js index 1885bbc89c22..87be5ebb5379 100644 --- a/website/testCSSOrder.js +++ b/website/testCSSOrder.js @@ -27,8 +27,13 @@ Current solution looks good-enough for now const EXPECTED_MARKER_CLASSES = [ // Some class from Infima, in the order Infima declares them // this ensures we don't mess-up and re-order css from other libs + '.markdown>h2', + '.button--outline.button--active', + ':root', // TODO should be first + '.DocSearch-Hit-content-wrapper', // TODO should not be there? '.navbar__title', - '.col[class*=col--]', // TODO Should be after paddings + '.test-marker-site-custom-css-shared-rule', // TODO should not be there! + '.col[class*=col--]', // TODO should be after paddings '.padding-vert--xl', '.footer__link-item', // TODO should be last '.pagination__item', @@ -36,10 +41,11 @@ const EXPECTED_MARKER_CLASSES = [ '.tabs__item', // Test markers - '.test-marker-site-custom-css', + '.test-marker-site-custom-css-unique-rule', '.test-marker-site-client-module', '.test-marker-theme-layout', '.test-marker-site-index-page', + '.DocSearch-Modal', ]; const cssDirName = path.join(__dirname, 'build', 'assets', 'css'); From 74f3e64a973fb327340a5f444fa3647ce7659617 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 10:59:39 +0100 Subject: [PATCH 6/7] Add more CSS order test classes --- website/src/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 3a892c83831d..a19f239fcab7 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -174,7 +174,7 @@ div[class^='announcementBar_'] { /* Used to test CSS insertion order */ .test-marker-site-custom-css-unique-rule { - content: "site-custom-css"; + content: "site-custom-css-unique-rule"; } .test-marker-site-custom-css-shared-rule { max-width: 100%; From 4f4f571da2e724752a8051aa5c4f08f2410b4358 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 30 Dec 2021 12:31:30 +0100 Subject: [PATCH 7/7] cleanup css order test --- website/testCSSOrder.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/website/testCSSOrder.js b/website/testCSSOrder.js index 87be5ebb5379..6acee5b7f1d5 100644 --- a/website/testCSSOrder.js +++ b/website/testCSSOrder.js @@ -23,19 +23,20 @@ Current solution looks good-enough for now */ -// TODO temporary, the current order is bad and we should change that -const EXPECTED_MARKER_CLASSES = [ - // Some class from Infima, in the order Infima declares them - // this ensures we don't mess-up and re-order css from other libs +// TODO temporary, the current order is bad and we should change/fix that +const EXPECTED_CSS_MARKERS = [ + // Note, Infima and site classes are optimized/deduplicated and put at the top + // We don't agree yet on what should be the order for those classes + // See https://github.com/facebook/docusaurus/pull/6222 '.markdown>h2', '.button--outline.button--active', - ':root', // TODO should be first - '.DocSearch-Hit-content-wrapper', // TODO should not be there? + '.DocSearch-Hit-content-wrapper', '.navbar__title', - '.test-marker-site-custom-css-shared-rule', // TODO should not be there! - '.col[class*=col--]', // TODO should be after paddings + '--ifm-color-scheme:light', + '.test-marker-site-custom-css-shared-rule', + '.col[class*=col--]', '.padding-vert--xl', - '.footer__link-item', // TODO should be last + '.footer__link-item', '.pagination__item', '.pills__item', '.tabs__item', @@ -45,6 +46,8 @@ const EXPECTED_MARKER_CLASSES = [ '.test-marker-site-client-module', '.test-marker-theme-layout', '.test-marker-site-index-page', + + // lazy loaded lib '.DocSearch-Modal', ]; @@ -63,7 +66,7 @@ console.log('Inspecting CSS file for test CSS markers', cssFile); const cssFileContent = fs.readFileSync(cssFile, 'utf8'); -const cssMarkersWithPositions = EXPECTED_MARKER_CLASSES.map((marker) => { +const cssMarkersWithPositions = EXPECTED_CSS_MARKERS.map((marker) => { const position = cssFileContent.indexOf(marker); return {marker, position}; }); @@ -90,16 +93,14 @@ const sortedCSSMarkers = cssMarkersWithPositions .sort(sortBy('position')) .map(({marker}) => marker); -if ( - JSON.stringify(sortedCSSMarkers) === JSON.stringify(EXPECTED_MARKER_CLASSES) -) { +if (JSON.stringify(sortedCSSMarkers) === JSON.stringify(EXPECTED_CSS_MARKERS)) { console.log(`Test CSS markers were found in the expected order: - ${sortedCSSMarkers.join('\n- ')}`); } else { throw new Error(`Test CSS markers were found in an incorrect order. Expected order: -- ${EXPECTED_MARKER_CLASSES.join('\n- ')}; +- ${EXPECTED_CSS_MARKERS.join('\n- ')}; Actual order: - ${sortedCSSMarkers.join('\n- ')};