简体   繁体   English

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

[英]RequireJS doesn't work on a multipage project with CDN hosted libraries (jQuery)

I'm using RequireJS on a multipage project, with a Javascript folder structure that looks kinda like this (how do you make those fancy dir trees again in Markdown?): 我在一个多页面项目中使用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

Anyway, common.js is my main script file that is where I set up the configuration parameters. 无论如何, common.js是我的主脚本文件,我在那里设置配置参数。 This is what that looks like: 这是看起来像:

common.js file 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'
        ]
    }
});

All the page calls work as expected (with the CDN location being loaded), but I can't get my head around the minification part. 所有页面调用都按预期工作(加载了CDN位置),但我无法理解缩小部分。 The r.js optimizer simply refuses to cooperate, throwing an Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore r.js优化器只是拒绝合作,抛出Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore even though Underscore doesn't have a CDN specified. Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore即使Underscore没有指定CDN也是如此。

build.js file 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
}

Please help me figure out how to build this project to create the common.js script along with the individual page scripts. 请帮我弄清楚如何构建这个项目来创建common.js脚本以及各个页面脚本。

(Note: I based the structure of my build.js file on this example (注意:我在此示例中基于build.js文件的结构

Updated! 更新!

I've updated the question to include the correct syntax for empty: (thanks Travis!), and now the build runs without error. 我已经更新了问题以包含正确的empty:语法empty:感谢Travis!),现在构建运行没有错误。 However, my JS files are not concatenated or uglified. 但是,我的JS文件没有连接或uglified。 The CSS files are, at the import points, so something's happening. CSS文件在导入点处,所以发生了一些事情。 Complete build.js file below (forgive me, but she's a tall one): 下面完成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
}

Final Update (Yaay! It's working) 最后更新(Yaay!它正在运行)

Thanks to Travis below, everything is working great! 感谢下面的特拉维斯,一切都很好! (the files are getting minified and concatenated). (文件正在缩小和连接)。 Since his solution is hosted on Dropbox, and could be lost in the future (who knows amirite?), I'll just sum up the fixes he made: 由于他的解决方案是在Dropbox上托管的,并且将来可能会丢失(谁知道amirite?),我只是总结他所做的修复:

1. Don't mix define and require calls in a single file. 1.不要在单个文件中混合definerequire调用。

I had a couple of files where I'd mixed them like so: 我有两个文件,我把它们混合起来:

page/start.js 页/ start.js

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

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

and the fix was to do this: 并修复是这样做的:

page/start.js 页/ start.js

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

app/start_helper.js 应用程序/ start_helper.js

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

2. It's "empty:" not "empty" 这是"empty:"不是"empty"

That's a tricky one, though the RequireJS docs mention them. 这是一个棘手的问题,尽管RequireJS文档提到了它们。

3. Because 因为

what kind of list has just 2 bullet points? 什么样的清单只有2个要点?


Awesomelicious - now it works like a charm :) 太棒了 - 现在它就像一个魅力:)

Looks like requireJs thinks that you're trying to provide a paths fallback for underscore, since you're specifying its path value as an array. 看起来requireJs认为您正在尝试为下划线提供路径回退,因为您将其路径值指定为数组。 Try just doing it as a string instead. 尝试将其作为字符串来代替。

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

Also note that the correct symbol for empty paths is empty: (with a ':') not empty . 另请注意, 空路径正确符号为空 empty:带有':')不为empty

Finally, as an unrelated side note you could always look at lodash which is IMHO a more customizable, cross-browser compliant, faster underscore replacement with an identical API and it's hosted on cdnjs and is AMD-compliant 最后,作为一个不相关的附注,您可以随时查看lodash ,这是恕我直言,更可定制,跨浏览器兼容,更快的下划线替换与相同的API,它托管在cdnjs,并符合AMD标准

UPDATE UPDATE

Following up on the conversation within the comments, here's my updated version of your project: https://dl.dropboxusercontent.com/u/21823728/so_rjs.tar.gz 跟进评论中的对话,这是我项目的更新版本: https//dl.dropboxusercontent.com/u/21823728/so_rjs.tar.gz

As mentioned in the comments, your problem seemed to be that you were define ing modules within the same file that you were requiring those modules in, and that I believe was causing r.js to believe that these modules had no main entry point. 正如评论中所提到的,您的问题似乎是您在同一个文件中define模块,而这些模块是您需要这些模块的,并且我认为这会导致r.js相信这些模块没有主要入口点。 The convention is to separate out module definitions from files that require those modules. 惯例是将模块定义与需要这些模块的文件分开。

Notice there's an app folder now under assets/js where each module that used to be define d within your page modules is now stored. 请注意,现在assets/js下面有一个app文件夹,其中现在存储了用于在页面模块中define d的每个模块。 Your page modules now require these modules in. When I re-ran r.js (using uglify2 as the optimizer) everything seemed to work as expected. 您的页面模块现在require这些模块。当我重新运行r.js (使用uglify2作为优化器)时,一切似乎都按预期工作。

Furthermore, I removed some redundancy from your build.js file (you only have to specify baseUrl in your mainConfigFile if that's the one you're using for your build configuration as well). 此外,我从build.js文件中删除了一些冗余(您只需在mainConfigFile中指定baseUrl,如果这也是您为构建配置使用的那个)。 Finally, you may want to look into using the shim config if you want to attach jQuery and Bootstrap globally to every page. 最后,如果要将jQuery和Bootstrap全局附加到每个页面,您可能需要考虑使用shim配置 Otherwise you should just explicitly list them as dependencies when you need them. 否则,您应该在需要时将它们明确地列为依赖项。

Finally as one last piece of advice you may want to look at cutting down on the number of require within each file. 最后,作为最后一条建议,您可能希望减少每个文件中的require数量。 For most of those pages you could wrap everything in one require call and then just separate out different logic into functions to save some space on the event queue and also some cycles of having to redundantly call the require function. 对于大多数这些页面,您可以将所有内容包装在一个需要调用中,然后将不同的逻辑分离到函数中以节省事件队列上的一些空间,以及一些必须冗余调用require函数的循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM