1
votes

We are running a setup where React components that are written in CommonJS/ES5 on the backend need to be available on the front-end also for React rendering on both server and client.

I am trying to figure out how to transpile the React components from JSX to JS as well as from CommonJS to AMD.

Now, it's quite possible that there is no real way to "transpile" from CommonJS to AMD. So we could write it in ES6. If we write the React component code in ES6, how can we transpile that to AMD? I am having trouble finding a gulp plugin that does this.

I tried this:

http://www.sitepoint.com/transpiling-es6-modules-to-amd-commonjs-using-babel-gulp/

but I believe the babel({modules:'AMD'}) style is old, I don't think Babel knows what the modules property is anymore.

4
Do you have an existing AMD system or are you starting out? CommonJS works client-side too as long as you have the proper tooling set up. AMD is much less common these days. - loganfsmyth
thanks, yeah I have more experience with AMD, works fine for me, Browserify looks like a nightmare and is being superceded by Webpack anyway, so holding out strong - Alexander Mills
@loganfsmyth browserify does not support hot-reloading but requirejs makes it easy => medium.com/@the1mills/… - Alexander Mills
Yup, use whatever tool works, I just usually try to mention that AMD is not the only option. - loganfsmyth

4 Answers

2
votes

You can use Browserify's standalone mode to create Universal Module Definitions.

browserify module-name.js -o bundle.js --standalone moduleName

This will wrap the bundled module in a block of code that will export it as a CommonJS module, an AMD module and a fallback to a global variable called moduleName.

If you want to write your modules in ES6 and JSX too, then remember to include the appropriate transforms.

browserify module-name.js -o bundle.js --standalone moduleName -t [ babelify --presets [ es2015 react ] ]
2
votes

If you have all ES6 modules, you can tell Babel 6 to compile to AMD by adding

plugins: [
  "babel-plugin-transform-es2015-modules-amd"
}

to whatever Babel config for presets/plugins you already have. If you have some CommonJS modules though, the other answers are better.

0
votes

The way I have solved it for the moment is with these Gulp tasks

in my project we have

//root
  /lib-es5
  /lib-es6
  /public/js/react-components

we want to do two things:

  1. convert from (es6 and jsx) to (commonjs/plain JS)
  2. convert the commonjs react component files from above into AMD and place them in the public folder so that they can be used for React front-end as well as back-end.

here is what works for the moment:

 gulp.task('transpile-lib', [ ], function () {
    return gulp.src(['server/lib-es6/**/*.js'])
        .pipe(babel({
            presets: ['react']
        }))
        .pipe(gulp.dest('server/lib-es5'));
 });


gulp.task('convert', ['transpile-lib'], function (cb) {   //convert commonjs to amd

    cp.exec('r.js -convert server/lib-es5/react-components server/public/js/react-components', function (err, stdout, stderr) {
        if (err) {
            cb(err)
        }
        else if (err = (String(stdout).match(/error/i) || String(stderr).match(/error/i))) {
            console.error(stdout + stderr);
            cb(err);
        }
        else {
            cb(null);
        }

    });

});
0
votes

Babel env preset seems does the job

.babelrc example

{
    "presets": [
        ["env", {
          "modules": "amd"
        }]
      ]
}