RequireJS不适用于具有CDN托管库(jQuery)的多页项目

时间:2013-08-09 21:31:42

标签: javascript requirejs bundling-and-minification

我在多页项目中使用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脚本以及各个页面脚本。

(注意:我基于this example

上的build.js文件的结构

已更新!

我已更新问题以包含empty:的正确语法(感谢Travis!),现在构建运行没有错误。但是,我的JS文件没有连接或uglified。 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
}

最终更新(Yaay!它正在运行)

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

1。请勿将definerequire个调用混合在一个文件中。

我有几个文件,我把它们混合在一起:

页/ start.js

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

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

并且修复是这样做的:

页/ start.js

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

应用/ start_helper.js

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

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

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

3。因为

什么样的清单只有2个要点?


非常好 - 现在它就像一个魅力:)

1 个答案:

答案 0 :(得分:7)

看起来requireJs认为您正在尝试为下划线提供路径回退,因为您将其路径值指定为数组。尝试将其作为字符串来代替。

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

另请注意,correct symbol for empty pathsempty:(带有':')而不是empty

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

<强>更新

在评论中跟进对话,这是我项目的更新版本:https://dl.dropboxusercontent.com/u/21823728/so_rjs.tar.gz

正如评论中所提到的,你的问题似乎是你define在同一个文件中你需要这些模块的模块,我认为这导致r.js相信这些模块没有主要的切入点。惯例是将模块定义与需要这些模块的文件分开。

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

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

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