有没有可能阻止 requireJS 自动添加 .js 文件扩展名?

55
我正在使用requireJS来加载脚本。它在文档中有如下详细说明
引用: 模块名称所使用的路径不应包含.js扩展名,因为路径映射可能是针对一个目录。
在我的应用程序中,我将所有脚本文件映射到一个配置路径中,因为它们在运行时是动态生成的(我的脚本最初是像order.js这样的东西,但变成像order.min.b25a571965d02d9c54871b7636ca1c5e.js这样的东西(这是文件内容的哈希值,用于缓存清除)。
在某些情况下,require会在这些路径的末尾添加第二个.js扩展名。虽然我在服务器端生成了动态路径,然后填充了配置路径,但我还必须编写一些额外的Javascript代码来从有问题的文件中删除.js扩展名。
阅读requireJS文档,我真的不明白为什么您会希望将路径映射用于目录。这是否意味着可以以一次调用的方式加载整个目录中的文件?我不明白。

有人知道是否可以强制要求停止在文件路径中添加 .js,这样我就不必绕过它了吗?

谢谢。

更新:根据要求添加了一些代码示例。

这是我的 HTML 文件内部(这是一个 Scala 项目,因此我们无法直接将这些变量写入 .js 文件):

foo.js.modules = {
    order               : '@Static("javascripts/order.min.js")',
    reqwest             : 'http://5.foo.appspot.com/js/libs/reqwest',
    bean                : 'http://4.foo.appspot.com/js/libs/bean.min',
    detect              : 'order!http://4.foo.appspot.com/js/detect/detect.js',
    images              : 'order!http://4.foo.appspot.com/js/detect/images.js',
    basicTemplate       : '@Static("javascripts/libs/basicTemplate.min.js")',
    trailExpander       : '@Static("javascripts/libs/trailExpander.min.js")',
    fetchDiscussion     : '@Static("javascripts/libs/fetchDiscussion.min.js")'
    mostPopular         : '@Static("javascripts/libs/mostPopular.min.js")'
};

然后在我的main.js内部:

requirejs.config({
    paths: foo.js.modules
});

require([foo.js.modules.detect, foo.js.modules.images, "bean"], 
    function(detect, images, bean) {
        // do stuff
});

在上面的例子中,我必须使用字符串"bean"(它指的是require路径),而不是我的直接对象(像其他人使用的foo.js.modules.bar),否则我会得到额外的.js附加。希望这样讲清楚了。

你能否提供一个require函数调用的例子? 你是否在使用require.config()?你的设置是什么? - shovemedia
谢谢 - 我已经在上面添加了一些代码。只是使用 require.config() 将路径推入 require 中。 - Matt Andrews
变量bean不会解析为任何内容(不带引号)。您必须使用完整的foo.js.modules.bean引用。个人而言,我使用带引号的形式,所以我不确定否则会发生什么。 - shovemedia
不确定我是否理解 - 除了在回调参数中,我正在使用带引号的内容,但我不希望它在那里成为字符串。当我使用foo.js.modules.bean时,它会添加额外的'.js'扩展名。 - Matt Andrews
我现在明白了。这可能被认为是一个 bug,但是我总是从 requirejs.config -> paths 中的所有条目中省略 ".js"。如果你这样做,你应该能够使用 foo.js.modules.ID 引用或字符串 "ID",但是根据模块本身的导出方式,你可能会遇到问题。例如,我无法使用引用方法导入 jQuery,因为 jQuery 将自己导出为 id "jquery",但 requirejs 不知道将其与我在路径下的 "js/lib/jquery-1.7.1" 条目匹配起来。 - shovemedia
注意,我其他模块的工作方式与以下示例相同,并且可以很好地导出: define([],function(){ var Bob = function(){} return Bob }) - shovemedia
3个回答

117
如果您不想添加对noext的依赖,也可以只将虚拟查询字符串附加到路径末尾,以防止追加.js扩展名,例如:
require.config({
    paths: {
        'signalr-hubs': '/signalr/hubs?noext'
    }
});

这是noext插件的作用。


1
在我看来,这是更好的解决方案,你不需要再添加另一个库到负载中。只需在配置中增加六个额外字符即可。 - Quango
同意 - 这个简单多了。这也恰好是我正在寻找的确切示例(SignalR)。谢谢! - Jim Liddell
有人知道为什么我们不能在配置中添加选项吗? - Maxim
1
@BobStein-VisiBone 不行。它的工作原理是 ?noext 变成 ?noext.js,但仍然充当虚拟查询字符串。 - Jonathan Sudiaman
1
即使只在结尾加上 ? 而不是 ?noext,它也能正常工作。 - Asuka165
显示剩余2条评论

14

这是requirejs的noext插件

不需要添加".js"扩展名即可加载脚本,非常实用于动态脚本...

文档

请查看examples文件夹。所有你可能需要的信息都在注释或示例代码本身中。

基本用法

将插件放置在baseUrl文件夹内(通常与main.js文件位于同一文件夹)或创建一个别名指向插件位置:

require.config({
    paths : {
        //create alias to plugins (not needed if plugins are on the baseUrl)
        async: 'lib/require/async',
        font: 'lib/require/font',
        goog: 'lib/require/goog',
        image: 'lib/require/image',
        json: 'lib/require/json',
        noext: 'lib/require/noext',
        mdown: 'lib/require/mdown',
        propertyParser : 'lib/require/propertyParser',
        markdownConverter : 'lib/Markdown.Converter'
    }
});

//use plugins as if they were at baseUrl
define([
        'image!awsum.jpg',
        'json!data/foo.json',
        'noext!js/bar.php',
        'mdown!data/lorem_ipsum.md',
        'async!http://maps.google.com/maps/api/js?sensor=false',
        'goog!visualization,1,packages:[corechart,geochart]',
        'goog!search,1',
        'font!google,families:[Tangerine,Cantarell]'
    ], function(awsum, foo, bar, loremIpsum){
        //all dependencies are loaded (including gmaps and other google apis)
    }
);

0

我正在使用node.js的requirejs服务器端。但是noext插件对我不起作用。我怀疑这是因为它试图向url添加?noext,而我们在服务器端有文件名而不是url。

我需要将我的文件命名为.njs或.model以将它们与静态.js文件分开。希望作者更新requirejs,不要强制用户遵循自动.js文件扩展约定。

同时,这里有一个快速修补程序来禁用此行为。

要应用此修补程序(针对node_modules/requirejs/bin/r.js版本2.1.15):

  1. 保存到名为disableAutoExt.diff的文件中,然后打开终端
  2. cd path/to/node_modules/
  3. patch -p1 < path/to/disableAutoExt.diff
  4. 将disableAutoExt: true添加到您的requirejs.config中:requirejs.config({disableAutoExt: true,});

现在,我们可以执行require(["test/index.njs", ...] ...并继续工作。

将此修补程序保存在disableAutoExt.diff中:

--- mod/node_modules/requirejs/bin/r.js 2014-09-07 20:54:07.000000000 -0400
+++ node_modules/requirejs/bin/r.js 2014-12-11 09:33:21.000000000 -0500
@@ -1884,6 +1884,10 @@
         //Delegates to req.load. Broken out as a separate function to
         //allow overriding in the optimizer.
         load: function (id, url) {
+            if (config.disableAutoExt && url.match(/\..*\.js$/)) {
+                url = url.replace(/\.js$/, '');
+            }
+
             req.load(context, id, url);
         },

该补丁只是在 node_modules/requirejs/bin/r.js 的第1887行左右添加了以下内容:
if (config.disableAutoExt && url.match(/\..*\.js$/)) {
    url = url.replace(/\.js$/, '');
}

更新:通过将URL更改深入代码来改进补丁,因此在对模块调用undef后不再导致挂起。需要undef是因为:

在使用node.js进行开发时禁用模块缓存,请将以下内容添加到您的主应用程序文件中:

requirejs.onResourceLoad = function(context, map)
{
    requirejs.undef(map.name);
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接