且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在没有捆绑器的情况下使用react.js?

更新时间:2022-10-19 13:16:53

你必须要区分我认为,有一件事是捆绑(webpack或browserify),需要的工具组成项目的许多文件,并将它们捆绑在一个或多个文件中。这些工具不是必需的,但是如果你有一个更大的项目则非常有用。



经常涉及的其他工具是转换器,带有你的代码的工具和将它们转化为其他东西(如巴贝尔)。如果您使用普通的旧JavaScript,则不需要它们,如果您使用新的ES6语法,则需要它们在旧的javascript中翻译您的代码并在每个浏览器中运行它。



说没有这些工具是必需的。 React教程直接在页面中包含文件,无需任何其他工具即可运行,它不是很高效,但它没有其他工具。


Recently I have been playing around with react.js and I like the speed that I can develop working UI components. I have now created quite a few components and I would like to distribute some of them among different .jsx files.

Every thing I've read says that I should be using a bundler like browserify or webpacker whenever moving to production. However I am against this idea. Part of the reason I like developing in javascript is because its a scripted language and there is no compiler to muck around with. If I wanted to mess around with build chains and the like I would probably just do my development work in c.

I primarily make engineering tools. This involves making a tool and then giving it other engineers and operators to use. I probably won't look at a tool again for a year or two. I expect that when I do need to look at it again or someone following after me needs to look at it that they can jump right into the source code and start making changes. I don't want to have to remember how my build environment was set up back in 2016.

For my particular application, I also don't care about load speed or client resources. No one is using my tools from a phone and the tools will rarely be reloaded.

So, unless you can convince me that I really do want to bundle, what is the cleanest way to put together single page web application(s) with react.js components split among multiple .jsx files?


UPDATE / REFINED QUESTION / PARTIAL ANSWER:

I started with the example from Quick Start without NPM. Here is a simple example of what I was trying to achieve:

index.html:

<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello React!</title>
        <script src="../build/react.js"></script>
        <script src="../build/react-dom.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    </head>
    <body>
        <div id="example"></div>
        <script type="text/babel" src="hello1.jsx"></script>
        <script type="text/babel" src="hello2.jsx"></script>
        <script type="text/babel">
            ReactDOM.render(
                <div>
                    <Hello name='Bruce'/>
                    <Hello2 name='Bruce'/>
                </div>,
                document.getElementById('example')
            );
        </script>
    </body>
</html>

hello1.jsx:

var Hello1 = React.createClass({
    render: function() {
        var name = this.props.name;
        var message = 'Hello ' + name;
        return <h1>{message}</h1>;
    }
});

window.Hello1 = Hello1;

hello2.jsx:

var Hello2 = React.createClass({
    render: function() {
        var name = this.props.name;
        var message = 'Hello ' + name;
        return <p>{message}</p>;
    }
});

window.Hello2 = Hello2;

It turns out that what I was missing the first time was the all important window.Hello1 = Hello1;. This line exposes the function to the global scope otherwise the application will give the error: Uncaught ReferenceError: Hello1 is not defined because by default babel loads each file into its own scope.

I still have some unresolved questions. Now, thanks to some of the helpful clarification received here, I know how to properly ask them. First, is there a jsx transcoder that is lighter weight that doesn't change variable scoping?

Secondly, in my example, babel-core/browser.js makes use of ajax to load the .jsx file and then transform it. However this means it will fail does to CORS scripting when run on a local file unless I start chrome with the --allow-files-access-from-files flag. Is there an elegant work around for this?

Finally, when I try to use a newer version of bable-core like this one: "https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js", it will not run. Instead I get an error: browser.js:19824 Uncaught TypeError: Cannot read property 'keys' of undefined. Why?

you have to make a distinction I think, one thing is the bundler (webpack or browserify), tools that takes the many files that compose your project and bundle them together in one or more files. These tools are not required but the are extremely useful if you have a larger project.

The other kind of tools that are often involved are transpiler, tools that takes your code and transform them in something else (like babel). If you are using plain old javascript they are not required, if you are using the new ES6 syntax you need them to translate your code in the old javascript and run it in every browser.

That said non of theese tools are required. the React tutorial includes the files directly in the page and it works without any other tools, it's not very performant but it works without other tools.