How do I include a Javascript Library from a Twig Extension in Drupal 8? I have a custom Twig Extension that needs to add a Javascript library ONLY when the Twig Extension is used.

Here is my modules/custom/MY_MODULE/MY_MODULE.libraries.yml:

my-twig-extension:
  version: VERSION
  js:
    js/myTwigExtension.js: {}
  dependencies:
    - core/jquery


Here is my modules/custom/MY_MODULE/js/myTwigExtension.js (just for testing):

console.log("Hello World!!! at " + Date.now());  


In my modules/custom/MY_MODULE/src/TwigExtension.php I define the extension here:


public function getFunctions() {
    return [
        new \Twig_SimpleFunction('MY_MODULE_widget', [$this, 'MY_MODULEWidget']),
    ];
}


and then it's function:


public function MY_MODULEWidget($MY_VARIABLE)
{
    return array(
            '#theme' =&gt; 'twig_extension_MY_MODULE_widget',
            '#MY_VARIABLE' =&gt; $MY_VARIABLE,
            );
}


The #theme above is correctly loading my file here modules/custom/MY_MODULE/templates/twig_extension_MY_MODULE_widget.html.twig:

&lt;div class="MY_CLASS" data-MY_VARIABLE="{{ MY_VARIABLE | url_encode }}"&gt;Loading Widget...&lt;/div&gt;


Attempt 0:

Added the following twig function to modules/custom/MY_MODULE/templates/twig_extension_MY_MODULE_widget.html.twig:

{{ attach_library('MY_MODULE/my-twig-extension') }}


but that did not work.

Attempt 1:

Tried adding the library in the render array:

public function MY_MODULEWidget($MY_VARIABLE)
{
    return array(
            '#theme' =&gt; 'twig_extension_MY_MODULE_widget',
            '#MY_VARIABLE' =&gt; $MY_VARIABLE,
            '#attached' =&gt; array(
                'library' =&gt; array(
                    'MY_MODULE/my-twig-extension',
                    ),
                ),
            );
}


but it doesn't look like BlockBase logic is supported here to load the library.

Attempt 2:

I looked at how the Twig function attach_library works and saw how in Drupal\Core\Template\TwigExtension::attachLibrary($library) worked and tried to implement it here like this:

public function MY_MODULEWidget($job_name)
{
    static $doOnce = true;
    if ($doOnce) {
        $doOnce = false;

        /* @var $renderer Drupal\Core\Render\Renderer */
        $renderer = \Drupal::service('renderer');
        $template_attached = ['#attached' =&gt; ['library' =&gt; ['MY_MODULE/my-twig-extension']]];
        $renderer-&gt;render($template_attached);
    }

    return array(
            '#theme' =&gt; 'twig_extension_adicio_rated_job_widget',
            '#job_name' =&gt; $job_name,
            );
}


... with the idea of including the library the first time the Twig Extension was called.  But no go.

IMPORTANT: yeah I know I can add the following to my module/custom/MY_MODULE/MY_MODULE.info.yml:

libraries:
  - MY_MODULE/my-twig-extension


but I do not want to load this library (very expensive logic), to every page.

Any assistance would be greatly appreciated.  Thank you.
Partial Answer that works

... but I don't like it because the list of paths in the config never gets reset.  I think I need to figure out how to do Cache Contexts for a proper answer.

In my modules/custom/MY_MODULE/src/TwigExtension.php file:

class TwigExtension extends \Twig_Extension 
{
   const CONFIG_KEY_NAME = 'MY_CONFIG_NAME';
...
    public function MY_MODULEWidget($MY_VARIABLE)
    {
        /* @var $config Drupal\Core\Config\Config */
        $config = $this-&gt;configFactory-&gt;getEditable($this-&gt;getName() . '.settings');

        $paths = (array)$config-&gt;get(self::CONFIG_KEY_NAME);

        /* @var $currentPath string */
        $currentPath = \Drupal::service('path.current')-&gt;getPath();        // returns '/node/47446' not the alias

        if (in_array($currentPath, $paths)) {
            // Good
        } else {
            // Add $currentPath to config
            $paths[] = $currentPath;
            $config-&gt;set(self::CONFIG_KEY_NAME, $paths)-&gt;save();
        }

        return array(
                '#type' =&gt; 'inline_template',
                '#template' =&gt; '&lt;div class="MY_CLASS" data-MY_DATA="{{ MY_VARIABLE }}"&gt;Loading Widget ...&lt;/div&gt;',
                '#context' =&gt; array(
                    'MY_VARIABLE' =&gt; $MY_VARIABLE,
                    ),
                );
    }
}


The above code will add the current path to a config.  Unknown if there's an upper limit to the size of the data in the config; however, in my implementation the number of pages that this is on will be small (&lt; 100).  

Then once the path is added to the module's config setting then we read it to conditionally add a library like this using hook_page_bottom() like this in my modules/custom/MY_MODULE/MY_MODULE.module file:

/**
 * Implements hook_page_bottom
 */
function MY_MODULE_page_bottom(array &amp;$page_bottom)
{
    /* @var $paths array of strings */
    $paths = (array)\Drupal::config('MY_MODULE.settings')-&gt;get(Drupal\MY_MODULE\TwigExtension::CONFIG_KEY_NAME);

    /* @var $currentPath string */
    $currentPath = \Drupal::service('path.current')-&gt;getPath();     // like '/node/47446', not the Alias

    if (in_array($currentPath, $paths)) {
        // Include the library that will modify jQuery(".MY_CLASS")
       $page_bottom['MY_MODULE']['#attached']['library'][] = 'MY_MODULE/my-twig-extension';
    }     

}


EDIT 0

Added a hook_build() to my module like this so I could clear the setting manually:

function MY_MODULE_rebuild()
{
    /* @var $config Drupal\Core\Config\Config */
    $config = \Drupal::service('config.factory')-&gt;getEditable('MY_MODULE.settings');

    $config-&gt;clear(Drupal\MY_MODULE\TwigExtension::CONFIG_KEY_NAME);

    $config-&gt;save();

}


Note: $config support fluid interface (e.g. $config->clear(...). 

I will still not accept my answer because I still believe I should be using Cache Context for this.