【问题标题】:RequireJS doesn't work on a multipage project with CDN hosted libraries (jQuery)RequireJS 不适用于具有 CDN 托管库 (jQuery) 的多页项目
【发布时间】:2013-08-09 21:31:41
【问题描述】:

我在一个多页项目中使用 RequireJS,其 Javascript 文件夹结构看起来有点像这样(你如何在 Markdown 中再次制作那些花哨的目录树?):

common.js
lib/
-- jquery-1.9.1.min.js
-- modernizr-2.6.2.min.js
-- underscore-amd.min.js
page/
-- index.js
-- start.js
-- checkout.js

无论如何,common.js 是我设置配置参数的主要脚本文件。看起来是这样的:

common.js 文件

// Configure RequireJS
requirejs.config({
    baseUrl: "assets/js/lib",
    paths: {
        page: '../page',
        jquery: [
            '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min',
            //If the CDN location fails, load from this location
            'jquery-1.9.1.min'
        ],
        modernizr: [
            '//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min',
            //If the CDN location fails, load from this location
            'modernizr-2.6.2.min'
        ],
        underscore: [
            'underscore-amd.min'
        ]
    }
});

所有页面调用都按预期工作(加载了 CDN 位置),但我无法理解缩小部分。 r.js 优化器只是拒绝合作,即使 Underscore 没有指定 CDN,也会抛出 Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore

build.js 文件

{
    appDir: '../www',
    baseUrl: 'js/lib',
    dir: '../www-built',
    mainConfigFile: '../www/assets/js/common.js',
    modules: [
        //First set up the common build layer.
        {
            //module names are relative to baseUrl
            name: '../common',
            include: ['jquery',
                      'modernizr',
                      'underscore'
            ]
        },
        // Now the page scripts
        {
            //module names are relative to baseUrl/paths config
            name: '../page-index',
            include: ['page/index'],
            exclude: ['../common']
        },
    ],
    paths: {
        jquery: "empty",
        modernizr: "empty"
    },
    optimize: "uglify2",
    removeCombined: true
}

请帮助我弄清楚如何构建此项目以创建 common.js 脚本以及各个页面脚本。

(注意:我的build.js 文件的结构基于this example

更新!

我已更新问题以包含 empty: 的正确语法(感谢 Travis!),现在构建运行没有错误。但是,我的 JS 文件没有连接或丑化。 CSS 文件在导入点,所以发生了一些事情。完成下面的build.js 文件(请原谅我,但她个子很高):

{
    appDir: '../www',
    baseUrl: 'assets/js', // relative to appDir
    dir: '../www-built',
    mainConfigFile: '../www/assets/js/common.js',
    modules: [
        //First set up the common build layer.
        {
            //module names are relative to baseUrl
            name: 'common',
            //List common dependencies here. Only need to list
            //top level dependencies, "include" will find
            //nested dependencies.
            include: ['jquery',
                      'modernizr',
                      'underscore',
                      'bootstrap'
            ]
        },

        //Now set up a build layer for each page, but exclude
        //the common one. "exclude" will exclude nested
        //the nested, built dependencies from "common". Any
        //"exclude" that includes built modules should be
        //listed before the build layer that wants to exclude it.
        //"include" the appropriate "app/main*" module since by default
        //it will not get added to the build since it is loaded by a nested
        //require in the page*.js files.
        {
            //module names are relative to baseUrl/paths config
            name: 'pages/home',
            include: ['pages/home'],
            exclude: ['common']
        },
        {
            //module names are relative to baseUrl/paths config
            name: 'pages/start',
            include: ['pages/start'],
            exclude: ['common']
        },
        {
            //module names are relative to baseUrl/paths config
            name: 'pages/checkout',
            include: ['pages/checkout'],
            exclude: ['common']
        },
    ],
    paths: {
        jquery: "empty:",
        modernizr: "empty:"
//        underscore: "empty:"
    },
    optimize: "uglify2",
    optimizeCss: "standard",
    removeCombined: true,
    preserveLicenseComments: false
}

最终更新(耶!它正在工作)

感谢下面的 Travis,一切运行良好! (文件被缩小和连接)。由于他的解决方案托管在 Dropbox 上,并且将来可能会丢失(谁知道 amirite?),我将总结一下他所做的修复:

1。不要在一个文件中混用 definerequire 调用。

我有几个文件,我像这样混合它们:

page/start.js

 define(['jquery','underscore'],function($,_) {
      ...
 });

 require(['jquery','page/start'], function($, Y) { // BAD!
      ...
 });

解决方法是这样做:

page/start.js

 require(['jquery','app/start_helper'], function($, Y) {
      ...
 });

app/start_helper.js

 define(['jquery','underscore'],function($,_) {
      ...
 });

2。这是"empty:" 不是"empty"

这是一个棘手的问题,尽管 RequireJS 文档提到了它们。

3。因为

什么样的列表只有两个要点?


真棒 - 现在它就像一个魅力:)

【问题讨论】:

  • 有人吗?这里很安静:(
  • 您是否尝试过为下划线添加 CDN?这里有一个://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js
  • @skishore 的问题是它没有被包装(你不能像在 RequireJS 中那样使用像 Underscore 这样的非 AMD 模块而不将其包装在 define 调用中)
  • 您能否添加“不要将definerequire 调用混合在一个文件中。” 作为单独的答案并选择它作为解决方案?跨度>
  • @kaiser 我的代码有几个问题,其中之一是definerequire 调用的混合。我已经编辑了 Travis 的答案以强调这一点。

标签: javascript requirejs bundling-and-minification


【解决方案1】:

看起来 requireJs 认为您正在尝试为下划线提供路径后备,因为您将其路径值指定为数组。试着把它作为一个字符串来代替。

paths: {
    underscore: 'underscore-amd.min'
}

还要注意correct symbol for empty pathsempty:(带有':')而不是empty

最后,作为不相关的附注,您可以随时查看 lodash,恕我直言,这是一个更可定制、跨浏览器兼容、更快的下划线替换,具有相同的 API,它托管在 cdnjs 上并且符合 AMD 标准

更新

跟进 cmets 内的对话,这是我对您项目的更新版本:https://dl.dropboxusercontent.com/u/21823728/so_rjs.tar.gz

正如 cmets 中所述,您的问题似乎是您在需要这些模块的同一文件中 defineing 模块,并且我认为这导致 r.js 认为这些模块没有主要入口点。惯例是将模块定义与需要这些模块的文件分开。

请注意,assets/js 下现在有一个 app 文件夹,其中存储了页面模块中以前为 defined 的每个模块。您的页面模块现在require 这些模块在。当我重新运行r.js(使用uglify2 作为优化器)时,一切似乎都按预期工作。

此外,我从您的 build.js 文件中删除了一些冗余(您只需在您的 mainConfigFile 中指定 baseUrl,如果这也是您用于构建配置的那个)。最后,如果您想将 jQuery 和 Bootstrap 全局附加到每个页面,您可能需要考虑使用 shim config。否则,您应该在需要时将它们明确列为依赖项。

最后,作为最后一条建议,您可能希望减少每个文件中 require 的数量。对于大多数这些页面,您可以将所有内容包装在一个 require 调用中,然后将不同的逻辑分离到函数中,以节省事件队列上的一些空间,以及一些必须冗余调用 require 函数的循环。

【讨论】:

  • 很高兴能帮上忙!重新 javascript 没有被连接优化:你使用的是什么版本的 requireJs? “uglify2”仅在 2.1.2 之后可用。另外,如果您让我知道您的版本,那么我可以尝试复制您的问题。另外,您使用removeCombined 是否有原因?根据example build script,如果将其设置为 true,则“任何组合到构建包中的文件都将从输出文件夹中删除”,我认为这听起来不像您正在寻找的行为。跨度>
  • (接上一条评论)尝试将optimize 的值更改为“uglify”而不是“uglify2”并去掉removeCombined 行,看看是否有帮助!否则,让我知道您使用的是什么版本的 requirejs,我会尝试复制问题。
  • 您的问题是您在顶级页面模块中使用defineing 模块,即混合使用requiredefine 调用。 r.js 似乎期望在您的顶级页面模块中您只使用 require 调用,并且任何 defined 模块都应该放在单独的文件中(每个文件一个)。
  • 查看我的更新答案,了解似乎对我有用的解决方案。
  • 没问题!很高兴我能帮忙:D
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 2015-04-06
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
相关资源
最近更新 更多