Skip to content
Snippets Groups Projects
Verified Commit fd739016 authored by Eduardo Sanz García's avatar Eduardo Sanz García :zero: Committed by GitLab
Browse files

Merge branch 'leipert-embed-scss-new-compiler' into 'master'

parents 48004e9c da73bb39
No related branches found
No related tags found
2 merge requests!144312Change service start (cut-off) date for code suggestions to March 15th,!142978Integrate new CSS compilation with webpack and vite
Pipeline #1159379317 passed
......@@ -10,7 +10,7 @@
"internal:eslint": "eslint --cache --max-warnings 0 --report-unused-disable-directives --ext .js,.vue,.graphql",
"internal:stylelint": "stylelint -q --rd '{ee/,}app/assets/stylesheets/**/*.{css,scss}'",
"prejest": "yarn check-dependencies",
"build:css": "node ./scripts/frontend/compile_css.mjs",
"build:css": "node scripts/frontend/build_css.mjs",
"jest": "jest --config jest.config.js",
"jest-debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
"jest:ci": "jest --config jest.config.js --ci --coverage --testSequencer ./scripts/frontend/parallel_ci_sequencer.js",
......
#!/usr/bin/env node
import process from 'node:process';
/* eslint-disable import/extensions */
import { compileAllStyles } from './lib/compile_css.mjs';
/* eslint-enable import/extensions */
const fileWatcher = await compileAllStyles({ shouldWatch: process.argv?.includes('--watch') });
process.on('SIGTERM', () => {
console.info('SIGTERM signal received.');
fileWatcher?.close();
});
#!/usr/bin/env node
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { mkdir, writeFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import { argv } from 'node:process';
import { env } from 'node:process';
import { compile, Logger } from 'sass';
import glob from 'glob';
/* eslint-disable import/extensions */
import IS_EE from '../../config/helpers/is_ee_env.js';
import IS_JH from '../../config/helpers/is_jh_env.js';
import IS_EE from '../../../config/helpers/is_ee_env.js';
import IS_JH from '../../../config/helpers/is_jh_env.js';
/* eslint-enable import/extensions */
// Note, in node > 21.2 we could replace the below with import.meta.dirname
const ROOT_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../');
const ROOT_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../');
const OUTPUT_PATH = path.join(ROOT_PATH, 'app/assets/builds/');
const BASE_PATH = 'app/assets/stylesheets';
......@@ -166,14 +164,7 @@ function resolveCompilationTargets() {
return Object.fromEntries([...result.entries()].map((entry) => entry.reverse()));
}
function writeContentToFile(content, srcFile, outputFile) {
if (!existsSync(path.dirname(outputFile))) {
mkdirSync(path.dirname(outputFile), { recursive: true });
}
writeFileSync(outputFile, content.css);
}
async function compileAllStyles() {
export async function compileAllStyles({ shouldWatch = false }) {
const reverseDependencies = {};
const compilationTargets = resolveCompilationTargets();
......@@ -184,38 +175,81 @@ async function compileAllStyles() {
};
let fileWatcher = null;
if (argv?.includes('--watch')) {
if (shouldWatch) {
const { watch } = await import('chokidar');
fileWatcher = watch([]);
}
function compileSCSSFile(source, dest) {
async function compileSCSSFile(source, dest) {
console.log(`\tcompiling source ${source} to ${dest}`);
const content = compile(source, sassCompilerOptions);
if (fileWatcher) {
for (const dependency of content.loadedUrls) {
if (dependency.protocol === 'file:') {
reverseDependencies[dependency.pathname] ||= new Set();
reverseDependencies[dependency.pathname].add(source);
fileWatcher.add(dependency.pathname);
const dependencyPath = fileURLToPath(dependency);
reverseDependencies[dependencyPath] ||= new Set();
reverseDependencies[dependencyPath].add(source);
fileWatcher.add(dependencyPath);
}
}
}
writeContentToFile(content, source, dest);
// Create target folder if it doesn't exist
await mkdir(path.dirname(dest), { recursive: true });
return writeFile(dest, content.css, 'utf-8');
}
if (fileWatcher) {
fileWatcher.on('change', (changedFile) => {
fileWatcher.on('change', async (changedFile) => {
console.warn(`${changedFile} changed, recompiling`);
const recompile = [];
for (const source of reverseDependencies[changedFile]) {
compileSCSSFile(source, compilationTargets[source]);
recompile.push(compileSCSSFile(source, compilationTargets[source]));
}
await Promise.all(recompile);
});
}
for (const [source, dest] of Object.entries(compilationTargets)) {
compileSCSSFile(source, dest);
const initialCompile = Object.entries(compilationTargets).map(([source, dest]) =>
compileSCSSFile(source, dest),
);
await Promise.all(initialCompile);
return fileWatcher;
}
function shouldUseNewPipeline() {
return /^(true|t|yes|y|1|on)$/i.test(`${env.USE_NEW_CSS_PIPELINE}`);
}
export function viteCSSCompilerPlugin() {
if (!shouldUseNewPipeline()) {
return null;
}
let fileWatcher = null;
return {
name: 'gitlab-css-compiler',
async configureServer() {
fileWatcher = await compileAllStyles({ shouldWatch: true });
},
buildEnd() {
return fileWatcher?.close();
},
};
}
await compileAllStyles();
export function simplePluginForNodemon({ shouldWatch = true }) {
if (!shouldUseNewPipeline()) {
return null;
}
let fileWatcher = null;
return {
async start() {
await fileWatcher?.close();
fileWatcher = await compileAllStyles({ shouldWatch });
},
stop() {
return fileWatcher?.close();
},
};
}
......@@ -47,6 +47,8 @@ else {
});
}
let plugin = false;
// print useful messages for nodemon events
nodemon
.on('start', () => {
......@@ -56,11 +58,20 @@ nodemon
console.log('The JavaScript assets are recompiled only if they change');
console.log('If you change them often, you might want to unset DEV_SERVER_STATIC');
}
/* eslint-disable import/extensions, promise/catch-or-return */
import('./lib/compile_css.mjs').then(({ simplePluginForNodemon }) => {
plugin = simplePluginForNodemon({ shouldWatch: !STATIC_MODE });
return plugin?.start();
});
/* eslint-enable import/extensions, promise/catch-or-return */
})
.on('quit', () => {
console.log('Shutting down CSS compilation process');
plugin?.stop();
console.log('Shutting down webpack process');
process.exit();
})
.on('restart', (files) => {
console.log('Restarting webpack process due to: ', files);
plugin?.start();
});
......@@ -14,6 +14,9 @@ import {
SOURCEGRAPH_PUBLIC_PATH,
GITLAB_WEB_IDE_PUBLIC_PATH,
} from './config/webpack.constants';
/* eslint-disable import/extensions */
import { viteCSSCompilerPlugin } from './scripts/frontend/lib/compile_css.mjs';
/* eslint-enable import/extensions */
let viteGDKConfig;
try {
......@@ -104,6 +107,7 @@ export default defineConfig({
],
},
plugins: [
viteCSSCompilerPlugin(),
viteGDKConfig.enabled ? autoRestartPlugin : null,
fixedRubyPlugin,
vue({
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment