Yii2: AMD support for out-of-box JavaScript modules

Created on 2 Dec 2013  路  9Comments  路  Source: yiisoft/yii2

For now it's impossible to use default ActiveForm and GridView widgets at project which uses AMD/RequireJS for javascript insertion into page.

For example:
yii\grid\GridView::run() now has line

$view->registerJs("jQuery('#$id').yiiGridView($options);");

The solution from the outside should look like:

// Somewhere in layout:
$view->amd = true;
...
// At yii\grid\GridView::run()
$view->registerJs("$('#{$id}').yiiGridView({$options});", [
    'jquery'=>'$',
    'jquery.yiiGridView'=>'yiiGridView'
]);

The second method argument accepts code dependencies. The generated code for example above would be:

require(['jquery', 'jquery.yiiGridView'], function($, yiiGridView) {
    $('#my-grid-view').yiiGridView({'foo':'bar'});
});

You may sight $view->amd = true; line, this signals the View object of having to use AMD-like way of JavaScript insertion into page. When it set to false, View uses default way of JS insertion (jQuery-spaghetti, as for current realisation), also the listed code dependencies would be loaded using registerScriptFile().

under discussion enhancement

Most helpful comment

I can explain more on this topic...

  • There are Single Page Applications (SPA's), where frontend part is written using only Javascript. Usually, they use server-side API as a data source (REST or something like that). At this case, Yii is only needed for server-side API development. This method doesn't fits for all applications since it has problems with SEO.
  • There are spaghetti-written applications, where Javascript code is written inside PHP files (remember Yii1 validators...), the developers are discussing which way of writting Javascript inside PHP code is better:
$js = <<<JS
var obj = {};
JS;

This is the default way for Yii, the framework even stimulates usage of this way.

  • There is also an itermediate way of app development, where JS code is strongly separated from PHP and even HTML. Server still generates some part of HTML, other part is rendered via JS (using data which is fetched via API or just inserted as JSON object into the page code), also JS is used for interaction with user (JQueryUI widgets and so on). This way usually uses same tools as at SPA, like JS frameworks (Angular, Backbone, Knockout, Ember) together with heavy JS module usage like AMD or CommonJS. Yii is not ready for this, I had to rewrite a lot of code of framework widgets like GridView to make it work together to RequireJS.

All 9 comments

Will this be touched or just discussed before release? Milestone is RC

I can explain more on this topic...

  • There are Single Page Applications (SPA's), where frontend part is written using only Javascript. Usually, they use server-side API as a data source (REST or something like that). At this case, Yii is only needed for server-side API development. This method doesn't fits for all applications since it has problems with SEO.
  • There are spaghetti-written applications, where Javascript code is written inside PHP files (remember Yii1 validators...), the developers are discussing which way of writting Javascript inside PHP code is better:
$js = <<<JS
var obj = {};
JS;

This is the default way for Yii, the framework even stimulates usage of this way.

  • There is also an itermediate way of app development, where JS code is strongly separated from PHP and even HTML. Server still generates some part of HTML, other part is rendered via JS (using data which is fetched via API or just inserted as JSON object into the page code), also JS is used for interaction with user (JQueryUI widgets and so on). This way usually uses same tools as at SPA, like JS frameworks (Angular, Backbone, Knockout, Ember) together with heavy JS module usage like AMD or CommonJS. Yii is not ready for this, I had to rewrite a lot of code of framework widgets like GridView to make it work together to RequireJS.

@alpharder the issue is that there are multiple JavaScript loaders: http://microjs.com/#loader so it's not wise to support one of these while not supporting others. Do you have any idea about more generic fix?

@samdark There are only three module types which are used widely - AMD, CommonJS and ES6 modules. One can read more on this topic here: http://addyosmani.com/writing-modular-js/

There are https://github.com/umdjs/umd, "UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere."

https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js , for example.

AMD is the most used standart when we talk about async module loading, a lot of different loaders just implement it.

Still, I don't think it's good to stick to AMD and make it impossible to use others.

Postponed to future releases. I don't think we have time or will do this for 2.0 release.

out of the scope of Yii2. You can create your own Assets if you want your own custom JS implementation

Without modular, it's difficult to manage my frontend (js,css) . Yii's AssetBundle is not quit enough. Frontend tech develops fast, can Yii provide some support?

Was this page helpful?
0 / 5 - 0 ratings