Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JSX file in Yii2 Asset Bundle

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?

like image 401
George Borunov Avatar asked Oct 31 '22 07:10

George Borunov


1 Answers

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

like image 90
Manquer Avatar answered Nov 14 '22 19:11

Manquer