Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@
"@types/query-string": "~6.2",
"@types/react": "^16",
"@types/react-dom": "^16",
"@types/styled-components": "~4.1",
"@types/react-loadable": "~5.5",
"@types/react-redux": "~7.1",
"@types/react-test-renderer": "~16.9",
"@types/serve-static": "~1.15",
"@types/styled-components": "~4.1",
"@types/tiny-async-pool": "~1.0",
"@types/uuid": "^9",
"@types/yargs": "~13.0",
Expand All @@ -148,8 +148,8 @@
"http-proxy-middleware": "<3",
"ignore-styles": "~5.0",
"jest-image-snapshot": "^6",
"jest-styled-components": "^6",
"jest-puppeteer": "^6",
"jest-styled-components": "^6",
"less": "^4.1.3",
"lighthouse": "^9",
"node-fetch": "~2.6",
Expand Down Expand Up @@ -211,11 +211,6 @@
"lcovonly"
]
},
"babelMacros": {
"styledComponents": {
"pure": true
}
},
"resolutions": {
"crypto-browserify": "npm:crypto-browserify@^3.12.0"
}
Expand Down
2 changes: 1 addition & 1 deletion script/prerender/contentPages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { renderToString } from 'react-dom/server';
import Loadable from 'react-loadable';
import { EnumChangefreq } from 'sitemap';
import { SitemapItemOptions } from 'sitemap';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components/macro';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
import asyncPool from 'tiny-async-pool';
import createApp from '../../src/app';
import { AppOptions } from '../../src/app';
Expand Down
4 changes: 0 additions & 4 deletions src/app/components/ScrollLock.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,6 @@ describe('MobileScrollLock', () => {
resetModules();
({React, renderToDom, renderer} = reactAndFriends());

const styled = require('styled-components');
// this is broken when unmounting without a dom
styled.createGlobalStyle = () => () => null;

MobileScrollLock = require('./ScrollLock').default;
});

Expand Down
3 changes: 0 additions & 3 deletions src/app/components/ScrollOffset.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ describe('ScrollOffset', () => {
delete (global as any).window;
resetModules();
({React, renderer, ReactDOM, renderToDom} = reactAndFriends());
const styled = require('styled-components');
// this is broken when unmounting without a dom
styled.createGlobalStyle = () => () => null;
ScrollOffset = require('./ScrollOffset').default;
});

Expand Down
56 changes: 56 additions & 0 deletions src/noStyledComponents.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as fs from 'fs';
import * as path from 'path';

/*
* The styled-components migration (CORE-1685) is finished as far as rex-web's own code
* goes, but the package cannot be uninstalled yet: @openstax/ui-components declares it
* as a peer dependency and we render Footer, NavBar and ConfirmationToast from that
* library. See CORE-1777 / CORE-2286.
*
* That leaves styled-components resolvable from every file in the repo for as long as
* ui-components takes to migrate, with nothing stopping a new import from appearing.
* This test is the thing that stops it. When ui-components ships a styled-components-free
* release, the allowlist below goes to empty, the package comes out of package.json, and
* this file can be deleted along with it.
*/
const allowedImporters = new Set([
// Collects the CSS that ui-components' styled components emit during prerendering, so
// the prerendered markup ships with the styles for the class names it references.
// Remove once ui-components no longer uses styled-components.
'script/prerender/contentPages.tsx',
]);

const searchRoots = ['src', 'script'];
const sourceExtensions = ['.ts', '.tsx'];
const skipDirectories = new Set(['node_modules', 'build', 'coverage']);

/*
* Matches an import or a require of the package or any of its subpaths (the /macro entry
* being the one we used to use). Deliberately written not to match itself, so that this
* file does not show up in its own results.
*/
const importPattern = /(?:from|require\()\s*['"]styled-components(?:\/[^'"]*)?['"]/;

const repoRoot = path.resolve(__dirname, '..');

const findSourceFiles = (directory: string): string[] => fs
.readdirSync(path.join(repoRoot, directory), {withFileTypes: true})
.reduce<string[]>((found, entry) => {
const relativePath = path.join(directory, entry.name);

if (entry.isDirectory()) {
return skipDirectories.has(entry.name) ? found : found.concat(findSourceFiles(relativePath));
}

return sourceExtensions.indexOf(path.extname(entry.name)) === -1 ? found : found.concat(relativePath);
}, []);

describe('styled-components', () => {
it('is imported only by the files that still need it', () => {
const importers = searchRoots
.reduce<string[]>((found, root) => found.concat(findSourceFiles(root)), [])
.filter((relativePath) => importPattern.test(fs.readFileSync(path.join(repoRoot, relativePath), 'utf8')));

expect(importers.sort()).toEqual(Array.from(allowedImporters).sort());
});
});
Loading