вторник, 28 февраля 2017 г.

RequireJS with Babel-standalone 6 and React

Структура расположения папок и файлов

/index.html
/js/index/js
/js/lib/babel-standalone/babel.js
/js/lib/es6/es6.js
/js/lib/loader/loader.js
/js/lib/react/react.js
/js/lib/react/react-dom.js
/js/lib/requirejs/requires.js
/js/config/require-config.js
/js/app/main/main.js
/js/app/class/class.js
/js/app/sum/sum.js

Файл es6.js

// For Browser

// Define paths:

// require.config({
//       'es6': 'node_modules/requirejs-es6/index'
//     , 'babel-core': 'node_modules/requirejs-es6/node_modules/babel-core/browser.min'
// });

// Then use as a normal RequireJS plugin:

// require(['es6!path/to/MyEs6File'], function (MyEs6File) {
//     var myfile = new MyEs6File();
//     ...
// });

// For Server

// To use your existing client-side AMD modules in node, use global-define and set the path to the requirejs-es6 module.
// This so that when RequireJS tries to resolve the module name, it maps to the correct package.

// require('global-define')({
//       basePath: __dirname
//     , paths: {
//         'es6': 'requirejs-es6'
//       }
// });

;(function () {

    var fetchText
        , _buildMap = {}
        , fs;

    function isBrowser () {return typeof window !== 'undefined' && window.navigator && window.document;}
    function isNode () {return typeof process !== 'undefined' && process.versions && !!process.versions.node;}
    function isRequireBuildProcess () {return isNode() && require.nodeRequire;}

    if (isBrowser()) {
        fetchText = function (url, callback) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.onreadystatechange = function () {
                // Do not explicitly handle errors, those should be visible via console output in the browser.
                if (xhr.readyState === 4) {callback(xhr.responseText);}
            };
            xhr.send(null);
        };
    } else if (isRequireBuildProcess()) {
        fs = require.nodeRequire('fs'); // nodeRequire is a method added by r.js
        fetchText = function (path, callback) {
            callback(fs.readFileSync(path, 'utf8'));
        };
    } else if (isNode()) {
        fs = require('fs');
        fetchText = function (path, callback) {
            callback(fs.readFileSync(path, 'utf8'));
        };
    }

    define(['babel', 'module'], function(babel, _module) {
        return {
              load: function (name, req, onload, config) {
                function applyOptions (options) {
                    var defaults = {
                          plugins: ['transform-es2015-modules-amd', 'transform-react-jsx'] // modules: 'amd' <-- for Babel 5 || plugins: ['transform-es2015-modules-amd'] <-- for Babel 6
                        , sourceMap: config.isBuild ? false : 'inline'
                        , sourceFileName: name + '.js'
                    };
                    for (var key in options) {
                        if (options.hasOwnProperty(key)) {defaults[key] = options[key];}
                    }
                    return defaults;
                }
                var url = req.toUrl(name + '.js');
                fetchText(url, function (text) {
                    var babelConfig = _module.config ? _module.config() : {};
                    var code = babel.transform(text, applyOptions(babelConfig)).code;
                    if (config.isBuild) {_buildMap[name] = code;}
                    if (isNode() && !config.isBuild) {
                        var fileName = name + '.tmp';
                        fs.writeFileSync(fileName, code);
                        onload(req(fileName));
                        fs.unlink(fileName);
                    } else {
                        onload.fromText(code);
                    }
                });
              }
            , write: function (pluginName, moduleName, write) {
                if (moduleName in _buildMap) {write.asModule(pluginName + '!' + moduleName, _buildMap[moduleName]);}
              }
        };
    });

})();

Файл loader.js

define(['babel'], function(Babel) {
    return {
        load: function (name, req, onload, config) {

            var url = req.toUrl(name + '.js');

            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    var code = Babel.transform(xhr.responseText, {
                          presets: ['es2015', 'react']
                        , filename: 'embedded'
                        , sourceMaps: 'inline'
                    }).code;
                    onload.fromText(code);
                }
            };
            xhr.send(null);

        }
    };
});

Файл index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="js/lib/requirejs/require.js"></script>
    <script src="js/config/require-config.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script src="js/index.js"></script>
  </body>
</html>

Файл require-config.js

requirejs.config({
      config: {
          es6: {
              resolveModuleSource: function (source) {return 'es6!' + source;}
          }
      }
    , paths: {
          es6: 'js/lib/es6/es6'
        , loader: 'js/lib/loader/loader'
        , babel: 'js/lib/babel-standalone/babel'
        , react: 'js/lib/react/react'
        , react_dom: 'js/lib/react/react-dom'

        , 'main': 'js/app/main/main'
        , 'class': 'js/app/class/class'
        , 'sum': 'js/app/sum/sum'
      }
});

Файл index.js

require(['loader!main'], function (Main) {
    Main();
});

Файл main.js

define(function (require) {
    var React = require('react')
        , ReactDOM = require('react_dom');
    require('es6!class');
    var Main = function () {
        ReactDOM.render(<span>Hello World 123</span>, document.getElementById('root'));
    };
    return Main;
});

Файл class.js

import sum from 'sum';

console.log(sum(1, 2));

class A {
    constructor (a) {
        console.log('Hello ' + a);
    }
}

new A('world!');

Файл sum.js

export default (a, b) => a + b;

Комментариев нет:

Отправить комментарий