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

时间:2016-04-08 23:52:03

标签: javascript reactjs browserify react-jsx bundling-and-minification

最近我一直在玩react.js,我喜欢我可以开发工作UI组件的速度。我现在已经创建了很多组件,我想在不同的.jsx文件中分发一些组件。

我读过的每件事都说我每次搬到制作时都应该使用像browserify或webpacker这样的捆绑器。但是我反对这个想法。我喜欢在javascript中开发的部分原因是因为它是一种脚本语言而且没有编译器可以随意使用。如果我想搞乱构建链等,我可能只是在c中进行开发工作。

我主要制作工程工具。这涉及制作工具,然后让其他工程师和操作员使用。我可能不会在一两年后再看一个工具。我希望当我确实需要再次查看它或者跟在我后面的人需要查看它时,他们可以直接进入源代码并开始进行更改。我不想记得我的构建环境是如何在2016年建立的。

对于我的特定应用程序,我也不关心加载速度或客户端资源。没有人在手机上使用我的工具,很少重新加载工具。

所以,除非你能说服我确实想要捆绑,否则将单个页面web应用程序与react.js组件分成多个.jsx文件放在一起的最简洁方法是什么?

更新/改进的问题/部分答案:

我从Quick Start without NPM的示例开始。这是我想要实现的一个简单示例:

的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;

事实证明,我第一次错过的是所有重要的window.Hello1 = Hello1; 。此行将函数公开给全局范围,否则应用程序将给出错误:Uncaught ReferenceError: Hello1 is not defined,因为默认情况下,babel会将每个文件加载到自己的范围内。

我还有一些未解决的问题。现在,由于这里收到的一些有用的澄清,我知道如何正确地问他们。 首先,是否有一个重量较轻且不会改变变量范围的jsx转码器?

其次,在我的例子中,babel-core / browser.js使用ajax加载.jsx文件,然后对其进行转换。但是,这意味着当在本地文件上运行时,CORS脚本将失败,除非我使用--allow-files-access-from-files标志启动chrome。对此有优雅的解决方法吗?

最后,当我尝试使用像这样的新版本的bable-core:“https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js”时,它将无法运行。相反,我得到一个错误:browser.js:19824 Uncaught TypeError: Cannot read property 'keys' of undefined。为什么呢?

3 个答案:

答案 0 :(得分:4)

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

经常涉及的其他工具是转换器,这些工具可以将代码转换为其他内容(如babel)。如果您使用普通的旧JavaScript,则不需要它们,如果您使用新的ES6语法,则需要它们在旧的javascript中翻译您的代码并在每个浏览器中运行它。

说没有这些工具是必需的。 the React tutorial直接在页面中包含文件,它可以在没有任何其他工具的情况下工作,它不是很高效,但它可以在没有其他工具的情况下工作。

答案 1 :(得分:3)

我发现这是使用jsx最简单的方法,没有任何构建步骤:

var table = $('#datatable').DataTable({
    ajax: {
        url: 'ajax_path',
        type: 'POST',
    },
    paging: false, searching: false, dom: 'rt',
    order: [],
    columnDefs: [
        { targets: [0], type: 'natural', },
        { targets: [3], className: 'select-checkbox dt-center', orderable: false, width: '70px', },
    ],
    select: {
        style: 'os',
        selector: 'td.select-checkbox:not(.not-selectable):last-child',
    },
    buttons: [],

    initComplete: function(settings, json) {
        // Select checkbox behaviors...
        var checkbox_colIdx = 3
        var identifiers_colIdx = 0;
        var table = $('#datatable').DataTable();

        var unselectables_IDs = ['1', '2', '4']; // to be replace by your json response i.e. json['unselectables_IDs']
        var row_IDs = table.column(identifiers_colIdx).data();

        $(row_IDs).each(function(index, value) {
            var row_ID = value.replace(/\D/g,'');

            if ($.inArray(row_ID, unselectables_IDs) !== -1) {
                $(table.row(index).node()).addClass('not-selectable');
                $(table.row(index).node()).children('td.select-checkbox').removeClass('select-checkbox');
            }
        });

        // Deselect unselectable rows (that can still be selected by using the shift key)...
        table.on('select', function(e, dt, type, indexes) {
            if (type === 'row') {
                var rows = table.rows(indexes).nodes();

                $.each($(rows), function() {
                    if ($(this).hasClass('not-selectable')) table.row($(this)).deselect();
                })
            }
        });
    },
});

并在App.jsx中:

<!DOCTYPE html>
<html>
<head>
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.14.0/babel.min.js"></script>
    <script type="text/babel" data-presets="es2017, stage-3" data-plugins="syntax-async-functions,transform-class-properties"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="App.jsx"></script>
<script type="text/babel" >
    ReactDOM.render(<App/>, document.getElementById('app'));
</script>
</body>
</html>

答案 2 :(得分:0)

我想为了避免使用这些工具,您只需要在HTML文档的结束正文标记之前包含您的页面中的反应和反应,以及所有文件。我相信React网站上的教程使用了这种方法,并避免使用任何工具。