Magento 2 Use Symlink In Default or Production Mode for Pub Static Files

app/etc/di.xml: add new item to stategiesList:

<virtualType name="developerMaterialization" type="Magento\Framework\App\View\Asset\MaterializationStrategy\Factory">
    <arguments>
        <argument name="strategiesList" xsi:type="array">
            <item name="view_preprocessed" xsi:type="object">Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink</item>
            <item name="default" xsi:type="object">Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink</item>
/* ++ */    <item name="asset" xsi:type="object">Magento\Framework\App\View\Asset\MaterializationStrategy\Copy</item>
        </argument>
    </arguments>
</virtualType>

Assuming you are in developer mode just delete the contents of pub/static and go to your page in the browser - magento will regenerate the static content.

worked for me in Magento 2.1.4 (styles-m.css got generated and other files got symlinked).

all the magic happens in vendor/magento/framework/App/View/Asset/MaterializationStrategy/Factory.php:

public function create(Asset\LocalInterface $asset)
{   
    if (empty($this->strategiesList)) {
        $this->strategiesList[] = $this->objectManager->get(self::DEFAULT_STRATEGY);
    }   

    foreach ($this->strategiesList as $strategy) {
        if ($strategy->isSupported($asset)) {
            return $strategy;
        }   
    }   

    throw new \LogicException('No materialization strategy is supported');
}   

Magento just loops through stategiesList items and use the first stategy that supports the asset.

How to make it work in production mode?

Disclaimer: this hack contains core file editing. beware.

all tested on magento 2.1.4

  1. remove version number from static files in Stores > Configuration > Advanced > Developer > Static Files Settings > No
  2. edit vendor/magento/framework/App/StaticResource.php and make launch function look like this:

    public function launch()
    {   
    // disabling profiling when retrieving static resource
    \Magento\Framework\Profiler::reset();
    $appMode = $this->state->getMode();
    /*if ($appMode == \Magento\Framework\App\State::MODE_PRODUCTION) {
        $this->response->setHttpResponseCode(404);
    } else {*/
        $path = $this->request->get('resource');
        $params = $this->parsePath($path);
        $this->state->setAreaCode($params['area']);
        $this->objectManager->configure($this->configLoader->load($params['area']));
        $file = $params['file'];
        unset($params['file']);
        $asset = $this->assetRepo->createAsset($file, $params);
        $this->response->setFilePath($asset->getSourceFile());
        $this->publisher->publish($asset);
    /*}*/
    return $this->response;
    }   
    
  3. delete contents of pub/static and visit your store url in a browser.

Tags:

Magento 2.1