Table of Contents:
Pt I: A Comprehensive Guide to Building Apps with React.js.
Pt 1.5: Utilizing Webpack and Babel to build a React.js App
Pt III: Architecting React.js Apps with Flux.
Pt IV: Add Routing to your React App with React Router. (Coming Soon)
Pt V: Add Data Persistence to your React App with Firebase. (Coming Soon)
Pt VI:Combining React.js, Flux, React Router, Firebase, Gulp, and Browserify. (Coming
Soon)
This series never got finished, instead, I created some courses that are much better.
Since writing this post I (along with most of the community) have adopted Webpack over Gulp. This is still a great post and contains some great information, but I recommend reading THIS tutorial for actual implementation as this post is a little out of date.
In part 1 we talked about all things React.
At this point you should feel comfortable with the following parts of React -
JSX
Virtual DOM
React.createClass
render (method)
React.render
state
getInitialState
setState
props
propTypes
getDefaultProps
Component LifeCycle
componentDidMount
getDerivedStateFromProps
componentWillUnmount
Events
onClick
onSubmit
onChange
If you’re not comfortable with the above, go re-read part 1.
At this point you might have noticed that in order to actually build apps with React, you need a way to transform your JSX into JS and also a way to export/import components from other components (or you need to put some thought into how you load your script tags in your HTML). This tutorial is going to introduce Gulp as a way to transform JSX into JS (along with a few other handy transformations). It’s also going to cover using Browserify with React in order to be able to import/export components for the use in other components.
I realize that there are many other ways to do the JSX -> JS transformation and specifically a lot of people are using webpack for mostly all of this. Those other ways are great. I’ve found that for beginners though, Gulp and Browserify make a great pair which abstracts some low level complexities without abstracting everything. I hope to build a future tutorial which uses Webpack instead of Gulp/Browserify.
Let’s start with Gulp. If you’ve had experience with another build tool, such as Grunt or Broccoli, this will make a lot of sense. If you have no experience with build tools, this next section is more specifically for you.
Let’s talk about why we need a tool like Gulp. Think of all the cool tools developers have built on top of things like JavaScript and CSS. Let’s use SASS and Coffeescript as examples. One day this (or perhaps these) developers got together and they said something along the lines of “Hey, CSS is cool, but it has a lot of limitations. Let’s make a language that is a layer on top of CSS. What we can do is we can create a language that is more powerful than CSS and has a lot more features. Then all we have to do is figure out a way for our language to have some sort of process to it which allows developers using our language to convert it (or transpile it) to actual CSS so the browser can understand it.” — and that’s exactly what they did. Coffeescript is another example. That conversation probably went like this “Wow JavaScript is so ugly. There’s not even a class keyword. We should build a language that isn’t so ugly and then figure out how to transpile it to actual JavaScript because that’s all the browser can understand.” A conversation similar to this most likely occurred when the React team decided to go with this JSX idea. As long as there’s a way to convert the “transpiled language” to a real language the browser can understand, there’s no issue. One convenient use case for Gulp is that we can tell Gulp that whenever we change a certain file or whenever we do some certain event, to go ahead and take our Coffeescript, SASS, JSX (etc), and transpile it into actual JavaScript or CSS.
Though having Gulp transpile your code is great, if you were only doing that,
you probably don’t need the power of Gulp since there are more basic solutions.
However, we’re going to use Gulp for more than just transpiling our JSX into JS.
Let’s think of some more things we do as developers that could be automated with
a build tool process like Gulp. Perhaps the most obvious processes are the ones
we use right before pushing our code to production. We first minify our code
(shorten variable names, remove white space, etc) in order to minimize our file
size. Next thing we usually do is concatenate all of our JavaScript files into
one file so when the client makes a request to the server for our app, it can
grab that one concatenated JavaScript file without having to worry about making
a bunch of requests to grab all of the files. Next thing you would need to do is
head over to your HTML page and change out all your <script>
tags with just one,
which was the minified JavaScript file. There are a plethora of things you can
do with Gulp, we’ll stick with the most common ones for this post.
Now that you have a better idea of why build tools like Gulp are so handy, let’s jump into getting started with Gulp.
The first thing you need to do when starting out with Gulp is to use NPM to install Gulp globally. If you’re not familiar with NPM, download Node and then do some googling. Using NPM is outside of the scope of this tutorial but is fairly straight forward.
In your terminal run
npm install --global gulp
that will install gulp globally on your computer.
Now, go ahead and make a new project with a folder structure that looks like this (remember, passively reading this tutorial won’t get you very far).
gulpfile.js
src
index.html
js
App.js
Child.js
Parent.js
Head over to your index.html
page and add the following code.
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.min.js"></script>
<script src="src/Child.js"></script>
<script src="src/Parent.js"></script>
<script src="src/App.js"></script>
</body>
</html>
Notice it’s pretty bare right now. All we really have is a div with an id of app and we’re loading React from a CDN.
Head over to your* Child.js* file and add the following code.
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
One more boilerplate addition. Now head over to your Parent.js file and add the following code.
var Parent = React.createClass({
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
Now head over to your App.js
file and add the following code.
React.render(<Parent />, document.getElementById('app'));
Notice all we’re doing is creating two components, one child, one parent. The
parent component is rendered to #app (in App.js
), which then renders the
child component passing in “child” as a property on props.
Now comes the fun part. Let’s head over to our gulpfile.js
file and start
building out our build process. Here’s the functionality that we eventually want from our final gulp build process.
Development
Production
<script>
tags in our index.html page with one <script>
which references our new minified build.js fileWith these processes above we’ll make it very simple to prepare our code for production and also very simple to convert our JSX to JS during development.
The very first thing we need to do is set up our package.json file. For those
unfamiliar with what our package.json is for, it’s essentially just a collection
of the node packages that are required for our application. In your terminal,
head over to the root of this project then type npm init
and select from the
different options (you can just hit enter until it finishes). The options don’t
matter too much - you can change them later.
Once you’re finished with that you’ll have a bare package.json file. Now in your terminal run the following commands.
npm install --save-dev gulp;
npm install --save-dev gulp-concat;
npm install --save-dev gulp-uglify;
npm install --save-dev gulp-react;
npm install --save-dev gulp-html-replace;
If you’ve used npm before, this is pretty straight forward. If you haven’t, we
practically just did witchcraft. All we did was tell npm to go and download each
of those packages and save them into our node_modules
folder (which was
created for us) and add them to our package.json
file as a developer
dependency. Now if you check out the node_modules
folder, it should be full of
the packages above. What we can do now is in our gulpfile.js
file, we can use
require
to essentially import the code from each of the different packages
and save that functionality into a variable. Let’s do that right now.
In the top of your gulpfile.js
file, add the following code.
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var react = require('gulp-react');
var htmlreplace = require('gulp-html-replace');
Notice we’ve created a variable for each of the packages we downloaded earlier. Now, each of those variables is just whatever was being exported from each individual package.
Before we dive into building our different Gulp tasks, we first need to create a
paths object. This paths object is going to be filled with properties that
represent differents paths. Copy this code under your variable declarations in
our gulpfile.js
file.
var path = {
HTML: 'src/index.html',
ALL: ['src/js/*.js', 'src/js/**/*.js', 'src/index.html'],
JS: ['src/js/*.js', 'src/js/**/*.js'],
MINIFIED_OUT: 'build.min.js',
DEST_SRC: 'dist/src',
DEST_BUILD: 'dist/build',
DEST: 'dist'
};
Now that are paths are defined, let’s create our first gulp task.
Our first task is going to be called transform and it’s going to be what transforms our JSX into JS. The code for this task looks like this,
gulp.task('transform', function(){
gulp.src(path.JS)
.pipe(react())
.pipe(gulp.dest(path.DEST_SRC));
});
Perhaps the coolest thing about Gulp is its ability to pipe and chain function
invocations. What this means is that we’re able to take one file, transform it
and do something with it, then take that transformation and do something else
with it, then when we’re finished, tell it where to put the newly created file.
That’s exactly what we’re doing above. We create a gulp task called transform
and pass it a callback function. In our callback function we grab the path.JS
array. Gulp then gets each one of those files, transforms them using the react
method we initialized earlier then pipes that outcome to dist/src
. If you ran
this task, after you’d see that Gulp took all your JS files, converted your JSX
to JS, then outputted the results to a new src
folder in a new dist
folder -
all in a manner of milliseconds. Pretty rad.
Let’s create our next Gulp task. All this task is going to do is take our
index.html
file and copy it over to our dist
folder so our newly created JS
files from our transform Gulp task above can be referenced by our index.html
page.
gulp.task('copy', function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
We’re now going to create our last Gulp task for development. What we want to do
is create a task that will always be running so when we change either our
index.html
or any of the JS files, our two tasks from earlier will run and
update the code in the dist
folder.
gulp.task('watch', function(){
gulp.watch(path.ALL, ['transform', 'copy']);
});
What the task above is saying is watch all of our files, whenever any of them change, run the transform task and the copy task. Pretty straightforward.
Now all we want to do for our development tasks is set up a default task. This
default task will run whenever we type gulp
in our command line. Here’s the
code for that.
gulp.task('default', ['watch']);
When we type gulp
, Gulp will run the watch task, which we know watches our
files for changes and then runs the transform
and copy
tasks.
Those are all the tasks we’re going to create for developing. There are
obviously a plethora of other tasks you could create for dev, but those are what
we’ll stick with right now. At this point you should be able to run gulp
and
the JSX in your App.js
file will be converted to JS and the output will go to
dist/src
. Your index.html file should have also been copied over to your dist
folder. Open your index.html
page in the browser and you should see your
components being rendered.
Now what we want to do is create a few gulp tasks for production so whenever we
run gulp build
our code will prepare itself to get pushed to production.
The first task we’re going to build for production is called build
. This
task is going to grab all of our JS files, concatenate all of them together,
minify them, then output the result to our dist/build
folder. The code for
that looks like this.
gulp.task('build', function(){
gulp.src(path.JS)
.pipe(react())
.pipe(concat(path.MINIFIED_OUT))
.pipe(uglify(path.MINIFIED_OUT))
.pipe(gulp.dest(path.DEST_BUILD));
});
The only thing that might look a little strange is the path.OUT argument we’re
passing to concat and uglify. All this is doing is telling both of those
functions what the resulting file path should be, so in this case, when we use
gulp.dest it’s going to take the path.MINIFIED_OUT file (build.min.js) and
output it to path.DEST_BUILD (dist/build
).
Now you might notice this is cool, but at this point it’s a little annoying
because whenever we run gulp build
, we then need to go and change our HTML
to reference the new build.min.js file rather than src/App.js
and whatever
other script tags we’re referencing here. What if there were a way to, whenever
we ran our production gulp tasks, to replace all of our <script>
tags with just
our new <script src=”build/build.mins.js”>
script and then output that new
file to our dist folder? Well, there is. The way we’re going to do that is with
a gulp-html-replace
. First, we need to head over to our index.html in our
main src folder and make some additions. Go ahead and modify the original
child/parent/App.js scripts to be wrapped in comments like this.
<!-- build:js -->
<script src="src/Child.js"></script>
<script src="src/Parent.js"></script>
<script src="src/App.js"></script>
<!-- endbuild -->
What’s going to happen is we’re going to tell Gulp, “Hey Gulp, when I tell you
to, concat and minify all my JS files and output them to a new dist/build
folder. As you’re doing that go to my copied index.html
page in my dist
folder and replace the build:js
comment and whatever is inside of it with
this new script tag <script src="build/build.min.js"></script>
but don’t
change my original index.html
file in my normal src
folder because I still
want to develop with that.”
Let’s now build out our replaceHTML
task. The code should look like this
gulp.task('replaceHTML', function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
'js': 'build/' + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
Note that what we give htmlreplace is an object with a key that represents where
to replace and whose value is what to replace. That ‘js’ key in htmlreplace
coincides with build:js
in our index.html
page.
Very last step is now that both of our production tasks are ready, we need to create another task that wraps both of those tasks in one. We do that with the following code
gulp.task('production', ['replaceHTML', 'build']);
Now whenever we run gulp production
, Gulp will run our replaceHTML
and
build
tasks. Go ahead and give it a try and check that your
dist/index.html
and dist/build/build.min.js
files are correct.
For reference, here’s the full gulpfile.js
file.
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var react = require('gulp-react');
var htmlreplace = require('gulp-html-replace');
var path = {
HTML: 'src/index.html',
ALL: ['src/js/*.js', 'src/js/**/*.js', 'src/index.html'],
JS: ['src/js/*.js', 'src/js/**/*.js'],
MINIFIED_OUT: 'build.min.js',
DEST_SRC: 'dist/src',
DEST_BUILD: 'dist/build',
DEST: 'dist'
};
gulp.task('transform', function(){
gulp.src(path.JS)
.pipe(react())
.pipe(gulp.dest(path.DEST_SRC));
});
gulp.task('copy', function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
gulp.task('watch', function(){
gulp.watch(path.ALL, ['transform', 'copy']);
});
gulp.task('build', function(){
gulp.src(path.JS)
.pipe(react())
.pipe(concat(path.MINIFIED_OUT))
.pipe(uglify(path.MINIFIED_OUT))
.pipe(gulp.dest(path.DEST_BUILD));
});
gulp.task('replaceHTML', function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
'js': 'build/' + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
gulp.task('default', ['watch']);
gulp.task('production', ['replaceHTML', 'build']);
At this point we have a full working build process using just Gulp. As you might
have noticed, this method has some weaknesses. First, you have to be very
careful how you load your different components in your HTML. Notice that we’re
loading the Child.js file before the Parent.js file. This makes sense
because Parent.js is dependent upon Child.js. Also note how we’re loading
Parent.js before we load App.js
, again this is because Parent is required in
the App.js
file. It might seem pretty straight forward in this example but as
your app grows, it’s very tricky to keep track of these Parent/Child
relationships and not to mention both Child and Parent are now in the global
scope, which from CS 101 we know is not a good thing. Another weakness in this
method is that if you put a debugger in our JSX, by the time our browser loads
that debugger we’re no longer in JSX land but in JS land and we have no way of
telling which line the error is on in our original JSX code. This isn’t ideal.
Although we still will always have to debug our transpiled JSX version, it would
be neat if we were able to still get the line numbers of where the error was at
in our original JSX file. Good news is when we introduce Browserify into our
build process, it will take care of both of these weaknesses and more.
At a fundamental level, all Browserify allows you to do is require certain packages just like we did earlier with gulp, concat, uglify, etc. This has huge benefits for us because not only do we now have access to all of NPMs packages, but we’re now able to require only the packages (or React components) we need to for that specific file. This solves our problem of all of our components being on the global scope. Let’s take a quick look at exporting and requiring modules.
I remember when I first started leaning about Browserify every definition about it would be in terms of commonjs - which meant literally nothing to me because I knew nothing about commonjs. That is until I fell upon this article on Reddit. The author talks about how Commonjs, AMD, and ES6 Modules are all ways to “break a Javascript project up into multiple self-contained modules and managing the dependencies between them”. That makes sense. I can essentially create module that can be passed around and used in other parts of my application without having to pollute the global scope. The author continues, “CommonJS is the standard implemented by Node. A file can assign any value (including a function or object) to its module.exports property and any other file can use require(“filename”) to get a copy of that value. It works great in Node but isn’t usable in a web browser; because of a quirk of the way file loading in HTML and Javascript works fetching each of the files would cause the browser to hang until it was loaded. There are, however, some tools (browserify) that will let you write your browser code in CommonJS and automatically convert it to something web appropriate.” Then it clicked. All Browserify allows me to do is have the greatness of using require in Node, but on the browser. This is fantastic for React because as you’ve probably guessed by now, each React component we create can be its own module that we can then require in other components based off of need. Let’s take a look at some sample commonjs syntax.
We’re going to create three files (NOTE: This example (Add
, Multiply
, Math
)
is just for demonstrating how Commonjs works, it’s not part of the overall
tutorial). The first file will be called Add.js
and it will export an
object with an addition helper method on it. The second file will be called
Multiply.js
and it will export an object with a multiplication helper method
on it. The third will be called Math.js
where we require and then use our Add
and Multiply module.
var addObj = {
add: function(x,y){
return x + y;
}
};
module.exports = addObj;
var multiplyObj = {
multiply: function(x,y){
return x * y;
}
};
module.exports = multiplyObj;
var addObj = require(‘./Add’);
var multplyObj = require(‘./Multiply’);
addObj.add(3,4) // 7
multiplyObj.multiply(2,5) // 10
Just a few minor things to note about the code above. If you want a certain object or function to be available in a different file, you use module.exports to export your code.
If you want to require whatever was exported from a different file, you use require and whatever the name of that file was minus the extension.
Now that we have a solid understanding of how Browserify can make our React code
more modular, let’s view the bigger picture of what our build process will look
like when we incorporate browserify. We’re still going to have two main tasks,
watch
and build
. watch
for development and build
for production.
On the surface both of these tasks will look very similar to our tasks before we
added Browserify. Our watch
task is going to concat our JS files, transform
them from JSX to JS, and output the results into our dist
folder. build
will also transform our JSX to JS, concatenate, minify, then output the result
to out dist
folder. The process looks similar, but there are actually some
really cool features introduced by Browserify which we haven’t talked about.
We’ll get those more when we look at the code.
Let’s jump in.
Like before, we’re going to start out downloading all of the NPM packages we’ll need for our new gulpfile. However, before we jump into that let’s hurry and remove an NPM package we were using for the previous example that we won’t be using for this example. In your terminal run
npm uninstall gulp-concat;
This commands remove the Concat libraries from our package.json
and our
node_modules
folder.
Now let’s install the new NPM packages we will need. Run the following command in your terminal.
npm install --save-dev vinyl-source-stream;
npm install --save-dev browserify;
npm install --save-dev watchify;
npm install --save-dev reactify;
npm install --save-dev gulp-streamify;
We’ll get into what each of these packages do when we use them in our tasks.
Head over to your gulpfile.js
and go ahead and remove everything. It’s easier
to start new since we’re introducing a pretty big change with browserify. At the top of your gulpfile add the following code like we did before.
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var htmlreplace = require('gulp-html-replace');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify');
var streamify = require('gulp-streamify');
var path = {
HTML: 'src/index.html',
MINIFIED_OUT: 'build.min.js',
OUT: 'build.js',
DEST: 'dist',
DEST_BUILD: 'dist/build',
DEST_SRC: 'dist/src',
ENTRY_POINT: './src/js/App.js'
};
The first task we’re going to create is our copy task. This is exactly the same
as before. We’re taking our index.html page and copying it over to our dist
folder.
gulp.task('copy', function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
Our next task is going to be our main task for development. This one is pretty lengthy so I’ll post the code and we’ll walk through it.
gulp.task('watch', function() {
gulp.watch(path.HTML, ['copy']);
var watcher = watchify(browserify({
entries: [path.ENTRY_POINT],
transform: [reactify],
debug: true,
cache: {}, packageCache: {}, fullPaths: true
}));
return watcher.on('update', function () {
watcher.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC))
console.log('Updated');
})
.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC));
});
The very first thing we do is tell Gulp to watch our index.html
file for any
changes and if something does change, run the copy task.
The next thing we do is set up a watcher. Watchify works very closely with Browserify. A problem that was occurring with these Browserify/React build processes was that Browserify would take forever to transpile because it was going through every component every single time anything changed and would re-update the new bundled file. Watchify fixes this. Instead of going through every file, Watchify will cache your files and only update the ones that need to be updated. This makes builds take a LOT less time.
Notice we’re passing a browserify function invocation to our watchify function
invocation. Let’s now talk a bit about that browserify invocation. We’re passing
browserify an object that is going to essentially set up the configurations for
our browserify build. The first property on the object is entries
. Notice
entries is an array with the path of just our main component in it (app.js).
You might remember earlier we had a JS array (['src/js/*.js',
'src/js/**/*.js']
) which was every JS file we wanted to be transformed from JSX
to JS. Well one perk with browserify is that you just tell it the entry point or
the main component in your app and it will take care of all the child
components. Pretty slick. Next we have the transform
property. Browserify
works with more than just React. Here is where we tell Browserify how to
transform our code. In this case, we’re using reactify which will take care of
our JSX to JS transpiling. Next is debug
which is set to true. This tells
Browserify to use source maps. What source maps do is even though we’re
referencing the transpiled JSX in our index.html page, through source maps when
there is an error in our code, the error will point to the line number in our
JSX file rather than our transpiled JS file. This is super convenient for
debugging. That last line with cache: {}, packageCache: {}, fullPaths: true
is necessary, but we won’t go into it. The watchify website just states that
it’s needed in order to use watchify.
The next thing we’re going to do is set up our watcher to watch for updates in
our parent component or in any of its children components. We tell our watcher
to watch for updates then we pass it a callback function to invoke whenever
there is an update. The code in the callback should look fairly familiar.
watcher.bundle
concatenates all of our different components into one file
and does some browserify magic to make the module.exports/requires work. Then
the rest is just piping the result to our dist/src
folder. The last thing in
our watch task is that we’re continuing to bundle and pipe after we set up the
on update callback. The reason for this is so that when we first call gulp
watch
our code will bundle and pipe itself to the dist folder even before a
change is made. Then any changes made to our JS files after that will just
overwrite the initial bundled code.
The last thing for our development tasks is to set the default gulp task to run
the watch task so we can now just run gulp
and our watch task will kick off.
gulp.task('default', ['watch']);
Just like before we started using Browserify, I like to keep my Development and
Production tasks separate. Like before, create a gulp task called build
.
This task is going to be very similar to our watch
task except this one is
only going to bundle and pipe our code without actually watching it for updates.
It’s also going to minify the final code then output it to dist/build
rather
than dist/src
.
gulp.task('build', function(){
browserify({
entries: [path.ENTRY_POINT],
transform: [reactify]
})
.bundle()
.pipe(source(path.MINIFIED_OUT))
.pipe(streamify(uglify(path.MINIFIED_OUT)))
.pipe(gulp.dest(path.DEST_BUILD));
});
Like I mentioned, this is mostly the same. We got rid of source mapping and our watchify stuff and added minification, but that’s it.
Also exactly like before we used Browserify, we want to be able to modify our
index.html page when it’s ready for production and switch out our regular
scripts with the minified versions. We’ll use the same replaceHTML
task that
we used before to do this.
gulp.task('replaceHTML', function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
'js': 'build/' + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
and to wrap both of our production tasks into one gulp process,
gulp.task('production', ['replaceHTML', 'build']);
and that’s it! Here’s what the full gulpfile.js
should look like
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var htmlreplace = require('gulp-html-replace');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify');
var streamify = require('gulp-streamify');
var path = {
HTML: 'src/index.html',
MINIFIED_OUT: 'build.min.js',
OUT: 'build.js',
DEST: 'dist',
DEST_BUILD: 'dist/build',
DEST_SRC: 'dist/src',
ENTRY_POINT: './src/js/App.js'
};
gulp.task('copy', function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
gulp.task('watch', function() {
gulp.watch(path.HTML, ['copy']);
var watcher = watchify(browserify({
entries: [path.ENTRY_POINT],
transform: [reactify],
debug: true,
cache: {}, packageCache: {}, fullPaths: true
}));
return watcher.on('update', function () {
watcher.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC))
console.log('Updated');
})
.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC));
});
gulp.task('build', function(){
browserify({
entries: [path.ENTRY_POINT],
transform: [reactify],
})
.bundle()
.pipe(source(path.MINIFIED_OUT))
.pipe(streamify(uglify(path.MINIFIED_OUT)))
.pipe(gulp.dest(path.DEST_BUILD));
});
gulp.task('replaceHTML', function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
'js': 'build/' + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
gulp.task('production', ['replaceHTML', 'build']);
gulp.task('default', ['watch']);
You now have a very nice build process that has some very nice features. To recap, those features include
I hope this tutorial was useful for you. At this point you should be fairly comfortable with React and its different pieces. You should also have an idea of how to setup a build process using Gulp and Browserify to compliment your React development. Up next, Flux and how to better architect your React.js applications.
Hear me out - most JavaScript newsletters suck. That's why we made Bytes.
The goal was to create a JavaScript newsletter that was both insightful and entertaining. Over 80,000 subscribers later and well, reviews don't lie
I pinky promise you'll love it, but here's a recent issue so you can decide for yourself.
Delivered to over 80,000 developers every Monday