Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebPack with React Uncaught Reference Error

I'm very loosely following the example here up until the point where it starts running the dev server.

I have a test React component (in scripts/test.jsx):

/** @jsx React.DOM */

var React = require('react');

var Test = React.createClass({
    render: function(){
        return <h1>HI!</h1>
    }
});

module.exports = Test;

I have a webpack.config where I'm using the jsx loader against the source directory (It's basically the same as the one in the example except I'm adding the library properties).

I run webpack and it generates the bundle file like I expect, however, when I try to use the component in an html file (after including the bundle.js script reference) I get the following in console: "Uncaught ReferenceError: Test is not defined".

The HTML contains the following:

<div id="hi">
</div>
<script type="text/jsx">
    /** @jsx React.DOM */
    React.renderComponent(
      <Test />,
      document.getElementById('hi')
    );
</script>

Am I doing something incorrect to use a component that is defined in CommonJS style against an html page that isn't technically using a module loader (I'm trying to treat this test as if it's someone who is trying to load the component without any type of structured module loader)?

The output of the webpack is available here

EDIT 2: The full example code is available as a github repo

like image 313
Ryan Lanciaux Avatar asked Aug 05 '14 05:08

Ryan Lanciaux


1 Answers

Yeah, you'd be better off following the example and requiring Test from a .jsx file rather than inlining it in the HTML.

Otherwise, Test needs to be exported as a global, so you'd need to follow similar conventions to the browserify --standalone flag, which looks to be something like this:

output: {
    library: "Test",
    libraryTarget: "umd"
}

http://webpack.github.io/docs/webpack-for-browserify-users.html#standalone

Edit: After looking at your GH repo, you have:

<script src="bundle.js" type="text/js"></script>

instead of

<script src="bundle.js" type="text/javascript"></script>

so it wasn't loading bundle at all. Further, you can't have 2 separate copies of react, the way you have it currently you're requiring React from within webpack, and then you're also loading it on the page. You should either export a function which takes the React object, or use the global to be able to use it outside of the bundle.

For example this would work:

/** @jsx React.DOM */
module.exports = function(React) {

var Test = React.createClass({
    render: function(){
        return <h1>HI!!</h1>
    }
});

return Test;
};

and then:

    /** @jsx React.DOM */
    React.renderComponent(
      Test(React)(),
      document.getElementById('hi')
    );

or this

/** @jsx React.DOM */
var Test = React.createClass({
    render: function(){
        return <h1>HI!!</h1>
    }
});

module.exports = Test;

and then:

    /** @jsx React.DOM */
    React.renderComponent(
      <Test />,
      document.getElementById('hi')
    );

Though I can't imagine most folks consuming a React package are going to be loading it with a script tag, and you generally don't want globals, so it's probably best to just use the CommonJS style require and let people figure out shimming or whatever.

like image 64
tgriesser Avatar answered Sep 24 '22 15:09

tgriesser