Skip to content

Commit

Permalink
[BUGFIX] Source mapping is now public path agnostic (#1352)
Browse files Browse the repository at this point in the history
The source maps are no longer inlined in the compiled CSS file.
There‘s a .css.map file for the compiled CSS file instead. Sources
are now included in the map file. This means that sources can now
be moved to non-public folders without losing the possibility
to debug your code.

Related: #1263
  • Loading branch information
cumuru committed Jun 6, 2023
1 parent bdd775c commit 5c26d81
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
9 changes: 9 additions & 0 deletions Classes/Parser/AbstractParser.php
Expand Up @@ -101,6 +101,15 @@ protected function getCacheFileMeta(string $filename)
return $filename . '.meta';
}

/**
* @param string $filename
* @return string
*/
protected function getCacheFileMap(string $filename)
{
return $filename . '.map';
}

/**
* @param string $file
* @param array $settings
Expand Down
24 changes: 19 additions & 5 deletions Classes/Parser/ScssParser.php
Expand Up @@ -51,6 +51,7 @@ public function compile(string $file, array $settings): string
$cacheIdentifier = $this->getCacheIdentifier($file, $settings);
$cacheFile = $this->getCacheFile($cacheIdentifier, $settings['cache']['tempDirectory']);
$cacheFileMeta = $this->getCacheFileMeta($cacheFile);
$cacheFileMap = $this->getCacheFileMap($cacheFile);
$compile = false;

if (!$this->isCached($file, $settings)
Expand All @@ -60,7 +61,18 @@ public function compile(string $file, array $settings): string

if ($compile) {
$result = $this->parseFile($file, $settings);
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFile), $result['css']);
if ($settings['options']['sourceMap']) {
// Write css file and append reference to source map file
GeneralUtility::writeFile(
GeneralUtility::getFileAbsFileName($cacheFile),
sprintf('%s /*# sourceMappingURL=%s */', $result['css'], basename($cacheFileMap))
);
// Write map file
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFileMap), $result['sourceMap']);
} else {
// Write css file
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFile), $result['css']);
}
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFileMeta), serialize($result['cache']));
$this->clearPageCaches();
}
Expand All @@ -79,10 +91,11 @@ protected function parseFile(string $file, array $settings): array
$scss->setOutputStyle(OutputStyle::COMPRESSED);
$scss->addVariables($settings['variables']);
if ($settings['options']['sourceMap']) {
$scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
$scss->setSourceMap(Compiler::SOURCE_MAP_FILE);
$scss->setSourceMapOptions([
'sourceMapRootpath' => $settings['cache']['tempDirectoryRelativeToRoot'],
'sourceMapBasepath' => '<PATH DOES NOT EXIST BUT SUPRESSES WARNINGS>'
'sourceMapBasepath' => Environment::getProjectPath(),
'outputSourceFiles' => true,
]);
}
$absoluteFilename = $settings['file']['absolute'];
Expand Down Expand Up @@ -145,8 +158,8 @@ function ($args) use (
}
);

// Compile file
$compilationResult = $scss->compileString('@import "' . $absoluteFilename . '"');
// Compile file. Second parameter is needed for source mapping
$compilationResult = $scss->compileString('@import "' . $absoluteFilename . '"', $absoluteFilename);
$css = $compilationResult->getCss();

// Fix paths in url() statements to be relative to temp directory
Expand All @@ -157,6 +170,7 @@ function ($args) use (

return [
'css' => $css,
'sourceMap' => $compilationResult->getSourceMap(),
'cache' => [
'version' => Version::VERSION,
'date' => date('r'),
Expand Down
28 changes: 27 additions & 1 deletion Tests/Functional/Parser/ScssParserTest.php
Expand Up @@ -63,7 +63,7 @@ public function scssParserCanCompileTest(string $inputFile): void
/**
* @return array
*/
public function scssParserCanCompileTestDataProvider(): array
public static function scssParserCanCompileTestDataProvider(): array
{
return [
'direct include' => [
Expand Down Expand Up @@ -126,4 +126,30 @@ public function sitepackageImagesAreUsedTest(): void
'url("../../../../typo3conf/ext/demo_package/Resources/Public/Images/PhotoSwipe/preloader.gif")'
);
}

/**
* @test
* @return void
* @dataProvider scssParserCanCompileTestDataProvider
*/
public function sourceMapsAreIncluded(string $file): void
{
$compileService = GeneralUtility::makeInstance(CompileService::class);
$tsfeBackup = $GLOBALS['TSFE'];
$GLOBALS['TSFE'] = $this->mockTSFEWithSourceMappingEnabled();
$compiledFile = $compileService->getCompiledFile($file);
$mapFile = $compiledFile . '.map';
$GLOBALS['TSFE'] = $tsfeBackup;
self::assertFileExists(Environment::getPublicPath() . '/' . $mapFile);
self::assertFileContains(Environment::getPublicPath() . '/' . $compiledFile, '/*# sourceMappingURL=' . basename($mapFile));
}

protected function mockTSFEWithSourceMappingEnabled(): \stdClass
{
$tsfe = new \stdClass();
$tmpl = new \stdClass();
$tmpl->setup = ['plugin.' => ['tx_bootstrappackage.' => ['settings.' => ['cssSourceMapping' => true]]]];
$tsfe->tmpl = $tmpl;
return $tsfe;
}
}

0 comments on commit 5c26d81

Please sign in to comment.