Magento 2: Work Around for Loading Static Assets from Symlinks?
-
13-12-2019 - |
Question
I just discovered that the official Magento 2.0 release (post public beta) doesn't support loading static assets from a symlinked folder. The root of the problem appears to be here
#File: vendor/magento/framework/View/Design/FileResolution/Fallback/Resolver/Simple.php
if ($this->rootDirectory->isExist($this->rootDirectory->getRelativePath($path))) {
return $path;
}
The call to $this->rootDirectory->getRelativePath
fails if the file doesn't exist under the root Magento directory. So, if you've created a symlink for your module folder
lns app/code/My/Module /path/to/my/other/repository/My/Module
the static file loader application won't be able to find your file.
Does anyone know a workaround for this that doesn't involve
- running
php bin/magento setup:static-content:deploy
whenever you change a file - hacking some code directly into
vendor/magento/framework/View/Design/FileResolution/Fallback/Resolver/Simple.php
to specifically handle your symlink-ed files
Solution 2
Found an ugly, but temporary workaround for the static assets problem. For reasons that aren't 100% clear, for symlinked files Magento will pass an already absolute $path
the getAbsolutePath
method in the Magento\Framework\Filesystem\Driver\File
class
#File: vendor/magento/framework/Filesystem/Driver/File.php
public function getAbsolutePath($basePath, $path, $scheme = null)
{
return $this->getScheme($scheme) . $basePath . ltrim($this->fixSeparator($path), '/');
}
Since $path
is already absolute, this method ends up generating an incorrect absolute path.
My fix is to temporarily hack in some code to detect this situation
public function getAbsolutePath($basePath, $path, $scheme = null)
{
if(time() > strToTime('2016-01-25'))
{
throw new \Exception("Don't forget this hack: " . __FILE__);
}
if(strlen($path) > 0 && $path[0] === '/' && file_exists($path) )
{
return $path;
}
return $this->getScheme($scheme) . $basePath . ltrim($this->fixSeparator($path), '/');
}
The first if
clause is something I've started doing with all my temporary hacks to ensure if they somehow end up on an important system, they have a time bomb explosion that will point to them clearly.
The second if
clause detects if the method's been passed an already absolute path, and if so returns the correct path (assuming the file actually exists).
Why a hack instead of a plugin? Because it looks like the static asset serving application at pub/static.php
does not allow you to plugin to classes.
OTHER TIPS
there are still some places in Magento 2, which are not compatible with components outside of Magento root. We're working on fixing them. Thanks for reporting, so we would not miss any such place (this one is already in our list).
Unfortunately, I can't suggest any workaround for it now.