【问题标题】:RequireJS paths configRequireJS 路径配置
【发布时间】:2013-05-25 09:26:13
【问题描述】:

我的 RequireJS 开发配置(在“index.html”文件中)是:

<script src="require-2.1.5.min.js"></script>
<script>
    require.config({
        baseUrl: 'js',
        paths: {
            angular: 'libraries/angular-1.1.5.min',
            jquery: 'libraries/jquery-2.0.0.min',
            underscore: 'libraries/underscore-1.4.4.min',
            ...
            zeroclipboard: 'plugins/zeroclipboard-1.0.7.min',
            tablesorter: 'plugins/jquery.tablesorter-2.9.1.min',
            ...
        },
        shim: {
            'angular': {
                exports: 'angular'
            },
            'underscore': {
                exports: '_'
            }
        },
        packages: [
            {
                name: 'index',
                location: 'app/index',
                main: 'main'
            }
        ]
    });

    require(['index']);
</script>

但在生产中,我只有 2 个用于库和插件的串联文件:

js/libraries.js // all jQuery, AngularJS, RequireJS, Underscore and other libraries concatenated
js/plugins.js // all plugins (already an AMD modules, no need for "shim" config) concatenated

那么,我现在如何编写我的配置“路径”?我没有任何 'libraries/angular-1.1.5.min.js' 和其他路径。

我的解决办法是这样写:

    paths: {
        angular: 'libraries',
        underscore: 'libraries'
    }

我将 AngularJS 和 Underscore 关联到 'libraries.js' 文件,一切正常。 (不需要 jQuery 和所有插件——它们已经是 AMD 模块了)。

但这是编写路径的正确方法吗?在我看来,我的解决方案有点肮脏,而不是最佳实践解决方案。

我的 r.js 构建过程:

({
baseUrl: 'scripts',
paths: {
    jquery: 'jquery-2.0.0.min',
    ...
    tablesorter: 'jquery.tablesorter-2.0.5.min',
    zeroclipboard: 'zeroclipboard-1.0.7.min'
},
name: 'foo/main',
exclude: [
    'angular',
    'jquery',
    ...
    'tablesorter',
    'zeroclipboard'
],
optimize: 'uglify',
out: 'production/js/foo.js'
})

UPD 1:

我想要什么:

www.mysite.com/about.html:

<script src="js/libraries.js"></script><-- jQuery (already AMD), AngularJS (not AMD), RequireJS, Underscore (not AMD) and other libraries already here, only 1 http request needed //-->
<script src="js/plugins.js"></script><-- all AMD //-->
<script>
    require.config({
        baseUrl: 'js',
        paths: {
            angular: WHAT I NEED TO WRITE HERE?,
            underscore: WHAT I NEED TO WRITE HERE?
        },
        shim: {
            'angular': {
                exports: 'angular'
            },
            'underscore': {
                exports: '_'
            }
        },
        packages: [
            {
                name: 'about',
                location: 'js',
                main: 'about'
            }
        ]
    });

    require(['about']); // will load "js/about.js"
</script>

UPD 2:

好的,“优先级”很清楚,所以,我不需要第一个和第二个«script»标签(但我需要将“Require.js”与“libraries.js”分开)- RequireJS 将加载他们自动。但是“libraries.js”文件中的非 AMD 库应该怎么做呢?

AngularJS 和 UnderscoreJS 是非 AMD 模块,这就是我必须使用“shim”的原因,对吧?但是要使“shim”工作,我还需要使用“paths”,所以“shim”可以定位已填充的模块,对吗?但我仍然只有 1 个文件——“libraries.js”,我无法在“path”选项中写入它……真的卡住了……

【问题讨论】:

  • 您不应该添加那些额外的脚本标签,require.js 可以并且应该为您加载这些标签。我在下面关于优先选项的回答是否不清楚?
  • 你的回答太好了,我刚刚在阅读你的更新之前做了更新:)

标签: javascript requirejs


【解决方案1】:

为了预加载公共库代码,您应该使用优先级配置选项。 你可以在你的foo/main.js 文件中放这样的东西

require.config({
    priority: ["libraries", "plugins"]
});

然后您的构建文件可能如下所示。 库和插件文件应该包含一个定义语句,定义所有被认为是通用的/下载一次的依赖项。

({
    baseUrl: 'scripts',
    paths: {
        jquery: 'jquery-2.0.0.min',
        ...
        tablesorter: 'jquery.tablesorter-2.0.5.min',
        zeroclipboard: 'zeroclipboard-1.0.7.min'
    },
    modules: [
        {
            name: 'foo/main'
            excludes: ...
        },
        {
            name: 'libraries'
        },
        {
            name: 'plugins'
        }
    ],
    optimize: 'uglify',
    out: 'production/js/foo.js'
})

【讨论】:

  • «想法是所有必需的引导代码都通过 1 个文件加载»。例如,我的网站上有 3 个页面:关于、投资组合、联系人。我用我的模块制作了 3 个不同的文件(许多“定义”模块连接到 1 个文件中):“about.js”、“portfolio.js”、“contacts.js”。第四个文件是“libraries+plugins.js”——因为我希望浏览器缓存这个文件并且不再下载它。我无法将“libraries+plugins.js”代码放入每个“about.js”、“portfolio.js”、“contacts.js”文件中。
  • 啊,是的,这很有意义。我认为您需要查看priority 配置选项以允许多层输出requirejs.org/docs/1.0/docs/faq-optimization.html#priority
  • @artuska 我已经编辑了我的问题,以便更好地反映 require js 中的优先级选项
【解决方案2】:

您应该为两种环境使用相同的配置。您拥有的这个配置应该在外部文件中。当您使用 r.j 对其进行优化时,所有模块都已在该单个文件中,因此 RequireJS 将只使用它们而无需加载。看来您需要调整构建过程。

查看我最近的blog post

【讨论】:

  • 添加了我的 r.js 构建脚本。即使在您的博文之后我也不明白,如何使我的配置在开发和生产中保持相同(在“index.html”文件中)。如您所见,我从最终构建中排除了一些文件,将它们放在单独的文件 (libraries.js) 中,以便浏览器缓存它并且不要为我网站上的其他页面再次下载它。 “libraries.js”包含 AMD 模块库(如 jQuery,它已经是其核心中的 AMD 模块)和非 AMD 库(如 AngularJS)。因此,“libraries.js”文件中没有 AngularJS 的“定义”。
  • 也许我应该手动将所有库都设为 AMD 模块?我的意思是,只需编辑 Angular.js 文件并将其代码包装在 "define('angular', [], function() {...})" 函数中?
  • 我想那些大模块从构建中排除是有道理的。您可能需要检查 github.com/tnajdek/angular-requirejs-seed 项目,其中 AngularJS 与 RequireJS 一起使用。
猜你喜欢
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多