需要与RequireJS进行反应

时间:2015-07-27 02:48:07

标签: requirejs reactjs

我正在使用node,react和requirejs,(并从Typescript生成符合AMD标准的JS,但我不认为这与手头的问题有关)。我只是想在我的应用程序中要求React:

// config.js
require.config({
    baseUrl: '../scripts/lib/node_modules',
    paths: {
        lib: '..',
        react: 'react/lib', 
        app: '../../app',
        jquery: 'jquery/dist/jquery',
        scripts: '../..',
    },
});
require(['react/React'], function (react) {

});

然后我将使用RequireJS的data-main api加载此配置,导航到此页面:

<!DOCTYPE html>
<html>
    <head>
        <title>My Updated Test Project</title>
        <script data-main="../scripts/config.js" src="../scripts/lib/node_modules/requirejs/require.js"></script>
    </head>
    <body>
        <h1>My Test Project</h1>
    </body>
</html>

RequireJS在尝试加载React时抱怨:

Error: Module name "EventPluginUtils" has not been loaded yet for context: _. Use require([])

在React.js中,几乎第一行是“裸露需求”

var EventPluginUtils = require("./EventPluginUtils");

如果我阅读RequireJS有关此错误消息的信息,则表示修复是停止使用裸需求。

  

当有require('name')调用时,会发生这种情况,但尚未加载'name'模块。   如果错误消息包括Use require([]),那么它应该是一个顶级的require调用(不是在define()调用中的require调用)应该使用async的回调版本来加载代码

但我不认为改变使用AMD需要的反应来源是React的作者所想到的。还有其他选择吗?我是否需要列出React.js require作为垫片的每个模块?这让我觉得很多前期和维护工作。我错过了一些关于RequireJS的基本信息吗? (我是这个模块的新手。)

编辑:

React打包为CommonJS模块,因此看起来像RequireJS 应该能够加载它:http://requirejs.org/docs/api.html#packages

但是简单地添加包含React的package.json文件的文件夹的位置似乎并没有让我在那里。它试图加载来自baseUrl的反应,好像它没有意识到有为该模块id配置的包。

2 个答案:

答案 0 :(得分:3)

这个问题获得了很多观点,并且我在此期间使用React的方式得到了显着改善,因此我将提供当前的设置。

如果你想使用RequireJS中的React,那很简单。不需要打包,自定义构建步骤或源修改。 NPM React模块附带一个脚本,其中包含UMD format中定义的所有React,它与两者 AMD和CommonJS兼容。 node_modules/react/dist/react.js。 (或者选择另一种风味,例如node_modules/react/dist/react.min.js)。大多数NPM模块附带distbuild文件夹,其中包含您可以使用的单个文件。这是我问过的原始问题的正确答案。

然而,尽管组合RequireJS和React非常容易,但如果你使用NPM来管理你的前端JS依赖关系,经过大量的工作和反思,我相信使用打包器几乎所有网站都是更好的选择。将依赖项打包到少量文件中会更容易,通常性能更高(在生产中),因此您不必为应用程序要使用的每个源文件执行HTTP请求。作为一个非常好的附带好处,您可以使用易于理解的CommonJS语言编写导入语句(请参阅上面的链接),而不是AMD规范。 CommonJS更易于读写,每个文件的顶部都需要更少的样板。

通过解决延迟加载问题,AMD可以提高性能 - 您不必立即请求,解析,编译和执行所有网站代码。相反,当用户导航到需要它们的页面时,会下载并解析新脚本。从理论上讲,这可以让您更快地初始页面加载,这是一个非常重要的指标。然而,实际上,有两个原因导致这种情况无法阻止。首先,每个HTTP请求都会引入开销和延迟,与大量小的HTTP请求相比,拥有一些大的HTTP请求会更好。即使您的网站足够大,以至于您确实希望将代码分解为多个脚本文件,您仍然不希望源中的每个代码文件都有一个脚本文件。相反,您希望将代码打包到几个包中,并且两个打包实用程序都有一些复杂的选项可以将代码分解为打包。其次,实际上,每个页面都需要大量的代码,因为它的框架代码。在您的网站变得非常非常大之前,您在AMD系统中要避免的页面特定代码量相对较小。是的,我知道,RequireJS has a way组合文件以提高性能。但你必须选择加入,而不是选择加入。

我可以看到包装有两个缺点。一个是构建时间更长,因为打包代码必须递归遍历整个代码库并解析每个require语句的代码,构建依赖关系图,然后它必须写出所有文件一包Webpack有多种选项可以改善开发过程中的构建时间(所谓的&#34;增量构建&#34;)。

包装的第二个问题有点棘手。浏览器中的源代码将是一个大型打包文件。

通过仔细配置,可以解决构建时间和大型调试包。对于打包时间问题,您至少需要保留较大的供应商依赖关系。这不仅可以改善构建时间和可读性,而且还可以改善缓存,因为浏览器的缓存模型是基于文件的,将低波动率和高波动率代码分离到单独的文件中是很好的。在Webpack中,您可以通过在Webpack配置中将它们声明为外部来保留供应商库,或者您可以使用导致类似内容的DLL plugin,但将各个供应商库打包到一个供应商包中。 / p>

Browserify vs webpack?我已经广泛使用了这一点,我推荐webpack。我发现它更容易配置(这可能是因为文档更适合我的需求)并且它具有我想要的所有功能,还有一些用于未来的功能,例如常见的块提取。

最后,如果你正在使用打字稿,你需要告诉它要发出什么样的模块:CommonJS,AMD或其他。您可以通过设置tsconfig.json.compilerOptions.module来执行此操作。有效值包括&#34; amd&#34;,&#34; commonjs&#34;,&#34; umd&#34;以及其他一些值。使用webpack时,您希望发出&#34; commonjs&#34;。 (但是,webpack可以为您编译typescript脚本,因此您可能希望集成该步骤。)

请注意RequireJS,browserify和webpack之间的争论。就目前而言,所有三个都可以配置为几乎所有用例产生基本相同的输出。我不认为它总是这样,但现在就是这样。区分它们的唯一方法是沿着非功能性维度,例如性能,采用和易用性。对我来说,webpack是最容易设置的,这是决定性的优势。我没有打扰性能测试。

答案 1 :(得分:-1)

尝试使用Browserify(npm install browserify)而不是requirejs.I遇到了这个确切的问题,但由于某种原因,requirejs无法正常工作。

如果你对它有所了解,可以在这里看一下关于Browserify的快速视频。它帮助了我,我希望它对你也有帮助:http://youtube.com/watch?v=78_iyqT-qT8