0

I'm using django-pipeline along with browserify based on the documentation here -

http://gregblogs.com/how-django-reactjs-and-browserify/

I have it working perfectly fine when loading NPM/Bower packages like so -

'build_js': {
    'source_filenames': (
        'js/bower_components/jquery/dist/jquery.js',
        'bootstrap/js/bootstrap.js',
        'js/bower_components/react/react-with-addons.js',
        'js/bower_components/react/react-dom.js',
        'datatables/js/jquery.dataTables.js',
        'datatables/js/dataTables.bootstrap.js',
        'js/node_modules/marked/marked.min.js',
        'js/node_modules/react-router/umd/ReactRouter.js',
        'js/child.js',
        'js/parent.js',
        'js/build.browserify.js',
    ),
    'output_filename': 'js/build_js.js',

The problem is I'm trying to reference the child.js and parent.js within the build.browserify.js

This is the contents of the 3 files -

child.js

var Child = React.createClass({
  render: function(){
    return (
      <div>
        and this is the <b>{this.props.name}</b>.
      </div>
    )
  }
});

parent.js

var Parent = React.createClass({
  render: function(){
    return (
      <div>
        <div> This is the parent. </div>
        <Child name="child"/>
      </div>
    )
  }
});

build.browserify.js

ReactDOM.render(
  <Parent />,
  document.getElementById('content')
);

I actually get 3 errors in my browser -

The following happens on my child.js and parent.js files both on line 4 -

Uncaught SyntaxError: Unexpected token <

And then I get this on my build.browserify.browserified.js at line 3

Uncaught ReferenceError: Parent is not defined

This is the contents of that file -

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
ReactDOM.render(
  React.createElement(Parent, null),
  document.getElementById('content')
);

},{}]},{},[1]);

edit -

If I put all code in a single build.browserify.js file like this it works -

var Child = React.createClass({
  render: function(){
    return (
      <div>
        and this is the <b>{this.props.name}</b>.
      </div>
    )
  }
});

var Parent = React.createClass({
  render: function(){
    return (
      <div>
        <div> This is the parent. </div>
        <Child name="child"/>
      </div>
    )
  }
});

ReactDOM.render(
    <Parent />, 
    document.getElementById('app')
);
whoisearth
  • 4,080
  • 13
  • 62
  • 130
  • 2
    Are you sure that you're transforming the JSX properly? `Uncaught SyntaxError: Unexpected token <` usually indicates that's the problem – taylorc93 Dec 22 '15 at 18:45
  • If I put all the code in a single file it works fine. updating to show that. – whoisearth Dec 22 '15 at 18:47
  • 1
    Are you also `require`ing all the dependencies in each file? ie, in parent.js: `require('/path/to/child');` – taylorc93 Dec 22 '15 at 19:21
  • Tried that, specifically `var Parent = require('parent');` on a few variations of `Parent`, `parent`, `parent.js`, `./parent` etc. the files are all in the same location. In any case I get the following error - Error: Cannot find module 'Parent' from '/var/www/app/static/js' which is where the module is in a file called `parent.js` – whoisearth Dec 22 '15 at 19:29
  • Did you export the Parent component using `module.exports`? – taylorc93 Dec 22 '15 at 19:30
  • you've lost me on that as I'm new to javascript. However, I did finally get a new message by doing `var Parent = require('./parent.js');` which I thought I had done before. It is finding it now which I can see in my `build.browserify.browserified.js` file however now I get new errors like `Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).` because it doesn't like that there isn't a prop on the `` – whoisearth Dec 22 '15 at 19:39

1 Answers1

2

@taylorc93 is on the right track with this, but you're missing an additional step.

In addition to having to do require('./parent') in any file where you want to include the parent module, you also need to actually export the content of the parent.js file. So, parent.js should look like:

child.js

var React = require('react');

modules.export = React.createClass({
  displayName: 'Child', // Always setting React component's displayName  will make your error messages easier to understand
  render: function(){
    return (
      <div>
        and this is the <b>{this.props.name}</b>.
      </div>
    )
  }
});

parent.js

var React = require('react');
var Child = require('./child');

modules.export = React.createClass({
  displayName: 'Parent', // Always setting React component's displayName  will make your error messages easier to understand
  render: function(){
    return (
      <div>
        <div> This is the parent. </div>
        <Child name="child"/>
      </div>
    )
  }
});

build.browserify.js

var ReactDOM = require('react-dom');
var Parent = require('./parent');

ReactDOM.render(
    <Parent />, 
    document.getElementById('app')
);

Also, while not required, it's good practice to give Component files uppercase names, just like you would class files in Java. Most apps will also name the root file as app.js or main.js or something like that, rather than build.browserify.js which is a bit vague since technically the file has nothing to do with building or with Browserify.

Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128
  • This is loading the files but it's complaining about the props being null which it doesn't do if I contain everything in one file. Also, I don't need to call var React or var ReactDOM because it's being handled by django-pipeline/browserify. This is the error I get with having the parent/child added - `ReactDOM.render( React.createElement(Parent, null), document.getElementById('content') );` think it requires a new question though? – whoisearth Dec 22 '15 at 19:56
  • `Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).` – whoisearth Dec 22 '15 at 19:57
  • I'm sorry, I'm not familiar with `django-pipeline/browserify`. The [docs](https://facebook.github.io/react/docs/glossary.html) should answer the question about that warning. Basically, just do `React.createElement(Parent)`. Only add the `null` in if you also include the third parameter as stated in the docs. – Matthew Herbst Dec 22 '15 at 20:19
  • For dealing with the props error, it's good practice do add the `propTypes` field to your components. That way if they aren't coming through properly React will give you fairly nice error messages explaining why. – Matthew Herbst Dec 22 '15 at 20:20