5

I have Yii2 project setup and I've decided to use Facebook's JavaScript framework React.js which provided a convenient way to declare HTML templates inside JavaScript code, called JSX.

My JavaScript looks as following:

(function () {
    'use strict';

    MyBlock = React.createClass({
        getInitialState: function () {
            return {data: []};
        },
        componentDidMount: function () {
            $.ajax({
                url: '/api/',
                dataType: 'json',

                success: function (data) {
                    this.setState({ data: data });
                }.bind(this)
            });
        },

        render: function () {
            <div class="block">
                {this.props.variable}
            </div>
        }
    });

    React.render(
        <ProfileQuestion />,
        document.getElementById('profile_question_wrapper')
    );
}());

AssetBundle helps me to include required libraries in my view, so I added React.JS and JSX file from CDN into my AssetBundle:

class MyAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
    ];
    public $js = [
        '//fb.me/react-0.13.1.min.js',
        '//fb.me/JSXTransformer-0.13.1.js',
        'js/app.jsx',
    ];
    public $depends = [
        'app\assets\AppAsset'
    ];
}

However, when it adds the script in the bottom of my page it shows it as

<script src="/js/app.jsx"></script>

and doesn't mark the type of the script as text/jsx therefore JSX Transform library doesn't recognize JSX syntax and the .jsx file interprets as simple JavaScript, throwing syntax error message on JSX style.

SyntaxError: Unexpected token '<'

Is there any way to specify in AssetBundle that .jsx file should have type of text/jsx in script element, when rendered?

Dmitry Shvedov
  • 3,169
  • 4
  • 39
  • 51
George Borunov
  • 1,562
  • 1
  • 15
  • 14
  • 1
    Note that JSXTransformer isn't intended for production use; it's large and slowish. Also in development you should use the development build (not .min) because there are helpful warnings and errors that are stripped out in production. – Brigand Apr 06 '15 at 00:47
  • Valuable notice! Thanks, I've changed react to development version in my asset bundle – George Borunov Apr 06 '15 at 01:38

1 Answers1

2

You will need to use two assets for doing this You can pass attributes to the script tag for js files. However it will be passed to all the files in the JS array, therefore you will need to have two asset classes. Like this

class MyAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
    ];
    public $js = [
        '//fb.me/react-0.13.1.min.js',
        '//fb.me/JSXTransformer-0.13.1.js',
    ];
    public $depends = [
        'app\assets\AppAsset'
    ];
}

second class

class JSXAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';

    public $js = [
        'js/app.jsx',
    ];
    public jsOptions = ['type'=>'text/jsx'];
    public $depends = [
        'app\assets\MyAsset'
    ];
}

And include the second class in your Views. The jsOptions calls the View::registerjsFile function which in turn calls the jsFile helper function in Html class Here. The options if not specially defined will be passed as the script tag attribute

Brigand
  • 84,529
  • 20
  • 165
  • 173
Manquer
  • 7,390
  • 8
  • 42
  • 69
  • 1
    It looks a little bit weird to have 2 assets for single view, even more to have a separate asset bundle for single jsx file. But it solved my problem, though. If no other more appropriate solutions exists, I'm good with this. Thanks a lot! – George Borunov Apr 06 '15 at 01:30
  • you can only include the second asset as this depends on the first class it will be also automatically included. As for multiple classes until Yii core adds support for jsOptions at each file level nothing much we can do.. – Manquer Apr 06 '15 at 01:32
  • 1
    Yeah, I added only JSX asset, I meant to have 2 classes for a single view in an assets folder feels a bit frustrated to me. But your truth, not much we can do about Yii framework features. – George Borunov Apr 06 '15 at 01:44
  • 1
    shouldn't JSX be compiled on the server instead of the client? – saada Apr 20 '15 at 16:12