Skip to content

Commit 8421f98

Browse files
committed
[AssetMapper] Various changes based on feedback:
* Adding all common web mime types * Allowing alternative mime type for JavaScript files * Do not modify the contents of JavaScript files to add the ".js" to import statements * Adding strict mode to error if imports can't be found * Removing readonly properties that caused trouble with psalm * Escaping single quote in entry name
1 parent 39e11ce commit 8421f98

24 files changed

+389
-202
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,10 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
864864
->info('The public path where the assets will be written to (and served from when "server" is true)')
865865
->defaultValue('/assets/')
866866
->end()
867+
->booleanNode('strict_mode')
868+
->info('If true, an exception will be thrown if an asset cannot be found when imported from JavaScript or CSS files - e.g. "import \'./non-existent.js\'"')
869+
->defaultValue(true)
870+
->end()
867871
->arrayNode('extensions')
868872
->info('Key-value pair of file extensions set to their mime type.')
869873
->normalizeKeys(false)

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,12 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
12731273
$container->removeDefinition('asset_mapper.dev_server_subscriber');
12741274
}
12751275

1276+
$container->getDefinition('asset_mapper.compiler.css_asset_url_compiler')
1277+
->setArgument(0, $config['strict_mode']);
1278+
1279+
$container->getDefinition('asset_mapper.compiler.javascript_import_path_compiler')
1280+
->setArgument(0, $config['strict_mode']);
1281+
12761282
$container
12771283
->getDefinition('asset_mapper.importmap.manager')
12781284
->replaceArgument(1, $config['importmap_path'])

src/Symfony/Bundle/FrameworkBundle/Resources/config/asset_mapper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,18 @@
7676
])
7777

7878
->set('asset_mapper.compiler.css_asset_url_compiler', CssAssetUrlCompiler::class)
79+
->args([
80+
abstract_arg('strict mode'),
81+
])
7982
->tag('asset_mapper.compiler')
8083

8184
->set('asset_mapper.compiler.source_mapping_urls_compiler', SourceMappingUrlsCompiler::class)
8285
->tag('asset_mapper.compiler')
8386

8487
->set('asset_mapper.compiler.javascript_import_path_compiler', JavaScriptImportPathCompiler::class)
88+
->args([
89+
abstract_arg('strict mode'),
90+
])
8591
->tag('asset_mapper.compiler')
8692

8793
->set('asset_mapper.importmap.manager', ImportMapManager::class)

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@
192192
<xsd:element name="path" type="asset_mapper_path" minOccurs="0" maxOccurs="unbounded" />
193193
<xsd:element name="server" type="xsd:boolean" minOccurs="0" />
194194
<xsd:element name="public_prefix" type="xsd:string" minOccurs="0" />
195+
<xsd:element name="strict-mode" type="xsd:boolean" minOccurs="0" />
195196
<xsd:element name="extension" type="asset_mapper_extension" minOccurs="0" maxOccurs="unbounded" />
196-
<xsd:element name="importmap_path" type="xsd:string" minOccurs="0" />
197-
<xsd:element name="importmap_polyfill" type="xsd:string" minOccurs="0" nillable="true" />
198-
<xsd:element name="importmap_script_attribute" type="asset_mapper_attribute" minOccurs="0" maxOccurs="unbounded" />
197+
<xsd:element name="importmap-path" type="xsd:string" minOccurs="0" />
198+
<xsd:element name="importmap-polyfill" type="xsd:string" minOccurs="0" nillable="true" />
199+
<xsd:element name="importmap-script-attribute" type="asset_mapper_attribute" minOccurs="0" maxOccurs="unbounded" />
199200
<xsd:element name="vendor_dir" type="xsd:string" minOccurs="0" />
200201
<xsd:element name="provider" type="xsd:string" minOccurs="0" />
201202
</xsd:sequence>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function testAssetMapperCanBeEnabled()
106106
'paths' => [],
107107
'server' => true,
108108
'public_prefix' => '/assets/',
109+
'strict_mode' => true,
109110
'extensions' => [],
110111
'importmap_path' => '%kernel.project_dir%/importmap.php',
111112
'importmap_polyfill' => null,
@@ -616,6 +617,7 @@ protected static function getBundleDefaultConfig()
616617
'paths' => [],
617618
'server' => true,
618619
'public_prefix' => '/assets/',
620+
'strict_mode' => true,
619621
'extensions' => [],
620622
'importmap_path' => '%kernel.project_dir%/importmap.php',
621623
'importmap_polyfill' => null,

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/asset_mapper.xml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
<framework:path namespace="my_namespace">assets2/</framework:path>
1313
<framework:server>true</framework:server>
1414
<framework:public_prefix>/assets_path/</framework:public_prefix>
15+
<framework:strict-mode>true</framework:strict-mode>
1516
<framework:extension extension="zip">application/zip</framework:extension>
16-
<framework:importmap_path>%kernel.project_dir%/importmap.php</framework:importmap_path>
17-
<framework:importmap_polyfill>https://cdn.example.com/polyfill.js</framework:importmap_polyfill>
18-
<framework:importmap_script_attribute key="data-turbo-track">reload</framework:importmap_script_attribute>
17+
<framework:importmap-path>%kernel.project_dir%/importmap.php</framework:importmap-path>
18+
<framework:importmap-polyfill>https://cdn.example.com/polyfill.js</framework:importmap-polyfill>
19+
<framework:importmap-script-attribute key="data-turbo-track">reload</framework:importmap-script-attribute>
1920
<framework:vendor_dir>%kernel.project_dir%/assets/vendor</framework:vendor_dir>
2021
<framework:provider>jspm</framework:provider>
2122
</framework:asset-mapper>

src/Symfony/Component/AssetMapper/AssetMapper.php

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,75 @@
2121
class AssetMapper implements AssetMapperInterface
2222
{
2323
public const MANIFEST_FILE_NAME = 'manifest.json';
24+
// source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
2425
private const EXTENSIONS_MAP = [
25-
'js' => 'application/javascript',
26-
'css' => 'text/css',
27-
'svg' => 'image/svg+xml',
28-
'png' => 'image/png',
29-
'jpg' => 'image/jpeg',
30-
'jpeg' => 'image/jpeg',
31-
'gif' => 'image/gif',
32-
'webp' => 'image/webp',
33-
'ico' => 'image/vnd.microsoft.icon',
34-
'woff' => 'font/woff',
35-
'woff2' => 'font/woff2',
36-
'ttf' => 'font/ttf',
37-
'otf' => 'font/otf',
38-
'eot' => 'font/eot',
39-
'json' => 'application/json',
40-
'xml' => 'application/xml',
41-
'txt' => 'text/plain',
42-
'csv' => 'text/csv',
43-
'pdf' => 'application/pdf',
26+
'aac' => 'audio/aac',
27+
'abw' => 'application/x-abiword',
28+
'arc' => 'application/x-freearc',
29+
'avif' => 'image/avif',
30+
'avi' => 'video/x-msvideo',
31+
'azw' => 'application/vnd.amazon.ebook',
32+
'bin' => 'application/octet-stream',
33+
'bmp' => 'image/bmp',
34+
'bz' => 'application/x-bzip',
35+
'bz2' => 'application/x-bzip2',
36+
'cda' => 'application/x-cdf',
37+
'csh' => 'application/x-csh',
38+
'css' => 'text/css',
39+
'csv' => 'text/csv',
40+
'doc' => 'application/msword',
41+
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
42+
'eot' => 'application/vnd.ms-fontobject',
43+
'epub' => 'application/epub+zip',
44+
'gz' => 'application/gzip',
45+
'gif' => 'image/gif',
46+
'htm' => 'text/html',
47+
'html' => 'text/html',
48+
'ico' => 'image/vnd.microsoft.icon',
49+
'ics' => 'text/calendar',
50+
'jar' => 'application/java-archive',
51+
'jpeg' => 'image/jpeg',
52+
'jpg' => 'image/jpeg',
53+
'js' => 'text/javascript',
54+
'json' => 'application/json',
55+
'jsonld' => 'application/ld+json',
56+
'mid' => 'audio/midi',
57+
'midi' => 'audio/midi',
58+
'mjs' => 'text/javascript',
59+
'mp3' => 'audio/mpeg',
60+
'mp4' => 'video/mp4',
61+
'mpeg' => 'video/mpeg',
62+
'mpkg' => 'application/vnd.apple.installer+xml',
63+
'odp' => 'application/vnd.oasis.opendocument.presentation',
64+
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
65+
'odt' => 'application/vnd.oasis.opendocument.text',
66+
'oga' => 'audio/ogg',
67+
'ogv' => 'video/ogg',
68+
'ogx' => 'application/ogg',
69+
'opus' => 'audio/opus',
70+
'otf' => 'font/otf',
71+
'png' => 'image/png',
72+
'pdf' => 'application/pdf',
73+
'php' => 'application/x-httpd-php',
74+
'ppt' => 'application/vnd.ms-powerpoint',
75+
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
76+
'rar' => 'application/vnd.rar',
77+
'rtf' => 'application/rtf',
78+
'sh' => 'application/x-sh',
79+
'svg' => 'image/svg+xml',
80+
'tar' => 'application/x-tar',
81+
'tif' => 'image/tiff',
82+
'tiff' => 'image/tiff',
83+
'ts' => 'video/mp2t',
84+
'ttf' => 'font/ttf',
85+
'txt' => 'text/plain',
86+
'vsd' => 'application/vnd.visio',
87+
'wav' => 'audio/wav',
88+
'weba' => 'audio/webm',
89+
'webm' => 'video/webm',
90+
'webp' => 'image/webp',
91+
'woff' => 'font/woff',
92+
'woff2' => 'font/woff2',
4493
];
4594
private const PREDIGESTED_REGEX = '/-([0-9a-zA-Z]{7,128}\.digested)/';
4695

@@ -203,7 +252,7 @@ private function calculateContent(MappedAsset $asset): string
203252
return $this->fileContentsCache[$asset->logicalPath];
204253
}
205254

206-
$content = file_get_contents($asset->sourcePath);
255+
$content = file_get_contents($asset->getSourcePath());
207256
$content = $this->compiler->compile($content, $asset, $this);
208257

209258
$this->fileContentsCache[$asset->logicalPath] = $content;

src/Symfony/Component/AssetMapper/AssetMapperDevServerSubscriber.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ public function onKernelRequest(RequestEvent $event): void
4949
throw new NotFoundHttpException(sprintf('Asset "%s" not found.', $assetPath));
5050
}
5151

52-
if ($asset->digest !== $digest) {
52+
if ($asset->getDigest() !== $digest) {
5353
throw new NotFoundHttpException(sprintf('Asset "%s" was found but the digest does not match.', $assetPath));
5454
}
5555

5656
$response = (new Response(
57-
$asset->content,
58-
headers: $asset->mimeType ? ['Content-Type' => $asset->mimeType] : [],
57+
$asset->getContent(),
58+
headers: $asset->getMimeType() ? ['Content-Type' => $asset->getMimeType()] : [],
5959
))
6060
->setPublic()
6161
->setMaxAge(604800)
6262
->setImmutable()
63-
->setEtag($asset->digest)
63+
->setEtag($asset->getDigest())
6464
;
6565

6666
$event->setResponse($response);

src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7878
$io->comment(sprintf('Compiling <info>%d</info> assets to <info>%s%s</info>', \count($allAssets), $publicDir, $this->assetMapper->getPublicPrefix()));
7979
$manifest = [];
8080
foreach ($allAssets as $asset) {
81-
// $asset->publicPath will start with a "/"
82-
$targetPath = $publicDir.$asset->publicPath;
81+
// $asset->getPublicPath() will start with a "/"
82+
$targetPath = $publicDir.$asset->getPublicPath();
8383

8484
if (!is_dir($dir = \dirname($targetPath))) {
8585
$this->filesystem->mkdir($dir);
8686
}
8787

88-
$this->filesystem->dumpFile($targetPath, $asset->content);
89-
$manifest[$asset->logicalPath] = $asset->publicPath;
88+
$this->filesystem->dumpFile($targetPath, $asset->getContent());
89+
$manifest[$asset->logicalPath] = $asset->getPublicPath();
9090
}
9191

9292
$manifestPath = $publicDir.$this->assetMapper->getPublicPrefix().AssetMapper::MANIFEST_FILE_NAME;

src/Symfony/Component/AssetMapper/Command/ImportMapRequireCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8484
$application = $this->getApplication();
8585
if ($application instanceof Application) {
8686
$projectDir = $application->getKernel()->getProjectDir();
87-
$downloadedPath = $downloadedAsset->sourcePath;
87+
$downloadedPath = $downloadedAsset->getSourcePath();
8888
if (str_starts_with($downloadedPath, $projectDir)) {
8989
$downloadedPath = substr($downloadedPath, \strlen($projectDir) + 1);
9090
}

0 commit comments

Comments
 (0)