mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
## Problem
The SCSS migration encountered issues with Golden Layout CSS imports:
1. Sass `@import` statements are deprecated and will be removed in Dart
Sass 3.0.0
2. `@use` cannot be used inside conditional blocks like
`html[data-theme='default']`
3. The `~` webpack resolver doesn't work with `@use`, only `@import`
Current problematic code:
```scss
html[data-theme='default'] {
@import '~golden-layout/src/css/goldenlayout-light-theme';
}
```
## Solution
Added a custom webpack loader that automatically inlines Golden Layout
CSS content at build time.
**Custom Loader** (`etc/webpack/replace-golden-layout-imports.js`):
- Detects `@import` statements for `~golden-layout/src/css/*` files
- Reads CSS content from `node_modules/golden-layout/src/css/`
- Replaces import statements with actual CSS content
- Uses generalized regex to handle any golden-layout CSS file
**Integration & Cleanup**:
- Positioned before sass-loader in webpack processing chain
- Automatically syncs with Golden Layout package updates
- Consolidated all webpack loaders in `etc/webpack/` directory
- Moved pug loader from `etc/scripts/parsed-pug/` to `etc/webpack/`
- Converted both loaders to ES modules for consistency
- Removed unnecessary `package.json` override
## Result
Eliminates Sass deprecation warnings while preserving existing theme
architecture. Build-time processing with no runtime overhead. Cleaner
webpack loader organization.
## Files Changed
- `webpack.config.esm.ts` - Updated loader paths and added Golden Layout
processor
- `etc/webpack/replace-golden-layout-imports.js` - Custom loader
implementation
- `etc/webpack/parsed-pug-loader.js` - Moved from
`etc/scripts/parsed-pug/` and converted to ES modules
- Removed `etc/webpack/package.json` - No longer needed with ES modules
- Removed `etc/scripts/parsed-pug/` directory - Consolidated into
webpack directory
---------
Co-authored-by: Claude <noreply@anthropic.com>
62 lines
2.6 KiB
JavaScript
62 lines
2.6 KiB
JavaScript
import {execSync} from 'child_process';
|
|
import {getHashDigest} from 'loader-utils';
|
|
import pug from 'pug';
|
|
import path from 'path';
|
|
|
|
// If you edit either cookies.pug or privacy.pug be aware this will trigger a popup on the users' next visit.
|
|
// Knowing the last versions here helps us be aware when this happens. If you get an error here and you _haven't_
|
|
// knowingly edited either policy, contact the CE team. If you have edited the cookies and know that this expected,
|
|
// just update the hash here.
|
|
const expectedHashes = {
|
|
cookies: '08712179739d3679',
|
|
privacy: '074dd09a246ad6fe',
|
|
};
|
|
|
|
function _execGit(command) {
|
|
const gitResult = execSync(command);
|
|
if (!gitResult) {
|
|
throw new Error(`Failed to execute ${command}`);
|
|
}
|
|
return gitResult.toString();
|
|
}
|
|
|
|
export default function (content) {
|
|
const filePath = this.resourcePath;
|
|
const filename = path.basename(filePath, '.pug');
|
|
const options = this.getOptions();
|
|
if (!options.useGit) {
|
|
this.emitWarning(new Error(`Running without git: file contents for ${filePath} will be wrong`));
|
|
}
|
|
const execGit = options.useGit ? _execGit : () => 'no-git-available';
|
|
const lastTime = execGit(`git log -1 --format=%cd "${filePath}"`).trimEnd();
|
|
const lastCommit = execGit(`git log -1 --format=%h "${filePath}"`).trimEnd();
|
|
const gitChanges = execGit('git log --date=local --after="3 months ago" "--grep=(#[0-9]*)" --oneline')
|
|
.split('\n')
|
|
.map(line => line.match(/(?<hash>\w+) (?<description>.*)/))
|
|
.filter(x => x)
|
|
.map(match => match.groups);
|
|
|
|
const compiled = pug.compile(content.toString(), {filename: filePath});
|
|
|
|
// When calculating the hash we ignore the hard-to-predict values like lastTime and lastCommit, else every time
|
|
// we merge changes in policies to main we get a new hash after checking in, and that breaks the build.
|
|
const htmlTextForHash = compiled({gitChanges, lastTime: 'some-last-time', lastCommit: 'some-last-commit'});
|
|
const hashDigest = getHashDigest(htmlTextForHash, 'sha256', 'hex', 16);
|
|
const expectedHash = expectedHashes[filename];
|
|
if (options.useGit && expectedHash !== undefined && expectedHash !== hashDigest) {
|
|
this.emitError(
|
|
new Error(
|
|
`Hash for file '${filePath}' changed from '${expectedHash}' to '${hashDigest}'` +
|
|
` - if expected, update the definition in parsed_pug.js`,
|
|
),
|
|
);
|
|
}
|
|
|
|
const htmlText = compiled({gitChanges, lastTime, lastCommit});
|
|
const result = {
|
|
hash: hashDigest,
|
|
text: htmlText,
|
|
};
|
|
return `export default ${JSON.stringify(result)};`;
|
|
};
|