What is JSX? – Simple transform



What is JSX? – Simple transform

0 0


react-build-jsx-talk

⚡️ Talk on building React and JSX with Browserify and Webpack

On Github claudiopro / react-build-jsx-talk

# Building React ## Intro to JSX build with Browserify and Webpack Claudio Procida [@claudiopro](https://github.com/claudiopro) Note: Nice to meet you, I'm going to cover a few basic concepts related to building React, and popular build tools that are used in conjunction with JSX

What is JSX?

  • It's an XML-like syntax to describe components
  • It is embedded into JavaScript code
  • It's syntactic sugar for React primitives
When Pete Hunt announced React at JSConf.EU 2013, the audience was probably already in a state of shock for the announcement that the framework re-renders everything when state or properties change, to understand the implications of embedding presentation in the JS module.
# JSX at a glance ```js // Declaration of a class var Avatar = React.createClass({ render: function() { return ( <div> <img src={'https://graph.facebook.com/' + this.props.userid + '/picture'} /> </div> ); } }); // Call to render a component ReactDOM.render(<Avatar userid="claudiopro" />, attachPoint); ``` Note: In a nutshell, this is you'll see React used most of the time. JSX elements are interleaved with code, mostly in the render() method and in the call to ReactDOM.render() -- previously React.render()
# Gotchas - React has a whitelist for HTML element names and attributes. If you pass elements or attribute names that are not in the list, React will not render them - You can pass JavaScript strings as content or attribute values. Note that React performs escaping on dynamic content Note: Attributes must be valid JS. For this reason, React uses `className` instead of `class`, and styles are literal objects whose keys are the JS property names of the `style` object e.g. `backgroundColor`.

Simple transform

React JSX transforms from XML-like syntax into JavaScript. XML elements, attributes and children are transformed into arguments passed to React.createElement

var Avatar = require('./Avatar');

// Input (JSX):
var app = <Avatar userid="claudiopro" />;
// Output (JS):
var app = React.createElement(Avatar, {
	userid : "claudiopro"
});

Nested transform

JSX also allows specifying children using XML syntax:

var Avatar = require('./Avatar'),
       Nav = require('./Nav');

// Input (JSX):
var app = <Nav><Avatar userid="claudiopro"/></Nav>;
// Output (JS):
var app = React.createElement(Nav,
	null,
	React.createElement(Avatar, {
		userid : "claudiopro"
	})
);

Build Tools

  • Babel
  • Browserify
  • Webpack
# Babel - A JavaScript compiler - Built out of composable plugins to create your own transformation pipeline - Ships with built-in support for JSX Note: Babel, formerly 6to5, is a powerful, extensible JavaScript compiler built out of plugins. You can compose your own transformation pipeline using existing plugins or write your own. Plugins are easily handled through presets: similarly to plugins, you can use existing presets or write your own. Babel has support for the latest version of JavaScript through syntax transformers. These allow you to use new syntax, right now without waiting for browser support. This helps test upcoming or experimental language syntax and shape the future of the language.
# Babel plugins - Syntax parsers for new or experimental syntax e.g. Object rest/spread operators - Transforms e.g. ES6 modules to RequireJS or AMD - Miscellaneous e.g. undeclared variable check Note: ...
# Babel presets Groups of plugins for common build profiles e.g. - React - ES6 - Experimental syntax, grouped by stage
# Babel config file - A `.babelrc` file at top level in your project - Supports all flags accepted by the `babel` binary Note: The `.babelrc` file is a JSON file that contains settings for babel, plugins and presets. The `.babelrc` is honored by babel when run in a directory that contains one. Mind that some options can be overridden via commandline arguments.
# Getting started - Install Babel and React preset to your project ```bash # Install with npm npm install babel-cli -g # Install the react preset and save to package.json npm install babel-preset-react --save-dev ``` - Configure `.babelrc` ```js { "presets": ["react"] } ``` Note: You may also want to install the babel-preset-es2015 if you want to use es6 syntax in your React components.
# Babel transforms - In browser transform - CLI Build - `babel-node` - Self-service REPL
# In browser transform - _Not for production use!_ - Use `browser.js` version that can run in a browser - Available as `babel-browser` npm module, or from a CDN - Transforms and runs scripts with type `text/ecmascript-6` and `text/babel`: ```html <script src="node_modules/babel-browser/browser.js"></script> <script type="text/babel"> class Test { test() { return "test"; } } new Test().test(); // "test" </script> ```
# CLI Build ```bash # Compile a file script.js and write to script-compiled.js babel script.js --out-file script-compiled.js # Watch an entire directory src for changes, and write to dist babel src --watch --out-dir dist # Uses the transform-react-jsx plugin babel --plugins transform-react-jsx script.js # Uses the react and es2015 presets babel --presets es2015,react script.js ``` Note: Babel can be used as a command line tool directly or in your Makefiles and shell scripts, on a single file or an entire directory. You can override options defined in the .babelrc file via command line flags. Additionally, babel can be launched in watch mode to perform a compilation every time files change.
# `babel-node` - Comes with `babel-cli` - _Do not use in production: very heavy because it stores the cache in memory_ - Compiles code on the fly before executing with `node` Note: babel-node should only be used to test programs that require babel. Always compile before distributing, and run with vanilla `node`.

Self service REPL

Try out JSX on the online Babel REPL

The self service Read-Eval-Print-Loop console allows to try out babel without installing e.g. if you can't install node or npm on a machine.
# Beyond JSX - Psst: `babel` can compile to _any_ Virtual DOM library e.g. Yolk, Riot, ... - Use the `pragma` setting in `.babelrc`: ```js { "plugins": [["transform-react-jsx", { "pragma": "dom" }]] } ``` - Compiles to the desired library: ```bash # script.js: <Nav userid="claudiopro"/>; babel script.js # Outputs: dom(Nav, { userid: "claudiopro" }); ```
# Browserify - Compiles node modules to run in the browser - Aggregates `CommonJS` modules - Allows composible transforms, e.g. `brfs`, `amdify` - Generates source maps (with `-d` option) Note: Browserify is a clever hack by James Halliday "substack" to bundle node modules for use in the browser. It's based on a small overhead that is added to the modules and additional composible transforms, e.g. brfs for fs operations, and amdify for requirejs compatibility.
# Babelify - https://github.com/babel/babelify - Babel transform for Browserify - Requires plugins or presets Note: Babelify is a browserify transform that applies babel to the code before it's aggregated. Similarly to babel, it requires plugins or presets.
# Babelify: CLI - Pass `babelify` as value of the `-t` option - Accepts [`subarg`'s](https://github.com/substack/subarg) ```bash browserify app.js -o bundle.js \ -t [ babelify --presets [ es2015 react ] ] ```
# Babelify: Gulp ```js var gulp = require('gulp'), browserify = require('browserify'), babelify = require('babelify'), source = require('vinyl-source-stream'); gulp.task('build', function() { browserify('./app.js') .transform(babelify, {presets: ['es2015', 'react']}) .bundle() .pipe(source('main.js')) .pipe(gulp.dest('./dist')); }); ```
# Reactify - https://github.com/andreypopp/reactify - React transform for Browserify - Based on the deprecated `react-tools` Note: Before babelify, reactify was used in concert with browserify to compile JSX reusing the react-tools utilities. Now that babel is the main supported compiler for JSX this is probably going to be phased out.
# Reactify: CLI - Pass `reactify` as value of the `-t` option - Accepts [`subarg`'s](https://github.com/substack/subarg) ```bash browserify app.js -o bundle.js -t reactify ```
# Reactify: Gulp ```js var gulp = require('gulp'), browserify = require('browserify'), reactify = require('reactify'), source = require('vinyl-source-stream'); gulp.task('build', function() { browserify('./app.js') .transform(reactify) .bundle() .pipe(source('main.js')) .pipe(gulp.dest('./dist')); }); ```
# Webpack - Extensible module bundler - Works with AMD, CommonJS, ES6 modules, etc. - Bundles not just JavaScript, but also CSS, HTML templates, images, fonts, ... - Loaders trasform everything to JavaScript - Extensible via plugins - _Splits code in chunks loadable on demand_
# Webpack: CLI - Accepts several command line options ```bash # Install with npm: npm install -g webpack # Use the default webpack.config.js # if exists, and watches files: webpack app.js --watch # Uses a different config file: webpack app.js --config other.config.js ```
# Webpack: Config - Controls entry points, chunks, loaders, plugins, ... - Pure JS object, file must export it ```js module.exports = { entry: './app.js', output: { path: './dist', filename: '[id].bundle.js' }, module: { loaders: [ { test: /\.jsx?/, exclude: /node_modules/, loader: 'babel-loader' } ] } }; ``` Note: The config object is a pure JS object exported by the config.js. This is the file that controls how webpack processes your project. A project can have multiple config files.
# Webpack: Gulp The short way: ```js var gulp = require('gulp'), util = require('gulp-util'), webpack = require('webpack'), config = require('./webpack.config.js'); gulp.task('build', function(callback) { // run webpack webpack(config, function(err, stats) { if (err) throw new util.PluginError('build', err); util.log('build', stats.toString({ colors: true })); callback(); }); }); ```
# Webpack: Gulp The long way: ```js var gulp = require('gulp'), util = require('gulp-util'), webpack = require('webpack'), config = require('./webpack.config.js'); gulp.task('build', function(callback) { // returns a Compiler instance var compiler = webpack(config); compiler.run(function(err, stats) { callback(); }); // or compiler.watch({ // watch options }, function(err, stats) { callback(); }); }); ```
# Deprecated - JSXTransformer.js - Legacy script for in-browser transform, transforms and run scripts with type `text/jsx` - [`react-tools`](https://www.npmjs.com/package/react-tools) - A set of complementary tools to React, including the `jsx` transformer - [`jstransform`](https://github.com/facebook/jstransform) - A simple utility for pluggable JS syntax transforms using the Esprima parser
# Further reading - Babel blog - http://babeljs.io/blog/ - React blog - http://facebook.github.io/react/blog/
# Thank you! Claudio Procida [@claudiopro](https://github.com/claudiopro)