javascriptdjangoreactjsbrowserifydjango-pipeline

Uncaught ReferenceError: Parent is not defined


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')
);

Solution

  • @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.