V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
sydneyzh
V2EX  ›  JavaScript

使用 requireJS 在同一个文件里定义多个模块的方法?

  •  
  •   sydneyzh · 2015-06-01 04:16:38 +08:00 · 5362 次点击
    这是一个创建于 3467 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近扒网站 - palleton,
    一个单页app,
    主模块(requirejs的data-main指向的文件)app.compiled.js里面,
    出现了这样的结构:

    开头
    http://i.imgur.com/cIEcXdz.png

    结尾
    http://i.imgur.com/8yUYHjo.png

    定义了多个相互依赖的模块。
    想问下这样的结构是什么原理?
    (requirejs文档没有讲这种结构。
    搜了下网上也只是说一个文件写一个模块,再用Optimizer来弄)

    9 条回复    2015-06-02 15:57:21 +08:00
    Septembers
        1
    Septembers  
       2015-06-01 04:46:01 +08:00
    https://gist.github.com/anonymous/34687d96207d838f1d79

    BTW: 代码片段请发Gist,发图片阅读很麻烦
    Septembers
        2
    Septembers  
       2015-06-01 04:47:05 +08:00
    sydneyzh
        3
    sydneyzh  
    OP
       2015-06-01 07:20:28 +08:00
    @Septembers gist被墙了。没开代理连这页的回复框都刷不出来。我还以为贴被封了。谢谢但回答没有帮助。
    sydneyzh
        4
    sydneyzh  
    OP
       2015-06-01 07:27:20 +08:00 via Android
    这个文件貌似还就是optimization tool生成的
    eeeeeeve
        5
    eeeeeeve  
       2015-06-01 10:43:12 +08:00
    @sydneyzh 这种结构真难读懂啊
    iwege
        6
    iwege  
       2015-06-01 14:09:19 +08:00   ❤️ 1
    感觉应该是r.js 合并生成的。这一般是发布的时候build tools 来生成的代码。
    jsq2627
        7
    jsq2627  
       2015-06-01 16:19:19 +08:00   ❤️ 1
    要在同一个文件声明多个模块,就像 2L 说的一样,显式在 define 第一个参数指定模块名。文档里说是不推荐这么做的,而是统一约定一个文件一个模块,用文件名表示模块名。

    楼主贴的这段代码是 Optimizer 生成的。它把每个文件的代码嵌入到了一个自调用里:
    (function () {
    // my-module-foo.js
    }).call(this),
    (function () {
    // my-module-bar.js
    }).call(this);

    因为这时所有模块合并到了一个文件,没法用文件名做模块名了。所以 Optimizer 把原来的文件名加到了 define 第一个参数。
    (function () {
    // my-module-foo.js
    define("my-module-foo", [], function { /* ... */ });
    }).call(this),
    (function () {
    // my-module-bar.js
    define("my-module-bar", [], function { /* ... */ });
    }).call(this);

    所以就有了这样的结构。
    latelx
        8
    latelx  
       2015-06-02 11:34:47 +08:00   ❤️ 1
    有时候一个模块里定义多个模块的需要还是有的,比如模板,一起作为一个目录给别人用总觉得怪怪的,这时候就有合并的需求。
    我把主模块定义为匿名模块,模板定义为一个命名模块(有命名空间),然后匿名模块将模块依赖就可以了,requirejs会自动将匿名模块作为加载合并文件时的模块定义。

    [https://gist.github.com/846f1245c2ea69e2f5d6](https://gist.github.com/846f1245c2ea69e2f5d6)
    leonlu
        9
    leonlu  
       2015-06-02 15:57:21 +08:00   ❤️ 1
    amd推荐的开发模式是一个文件只写一个模块,同时推荐只定义匿名的模块。也就是这样:

    比如, app/index.js里边的代码应该是

    // 这里定义一个匿名模块
    define(function (require) {

    // 这里明确写出所有的依赖
    var common = require('../common/index');

    // 这里是模块输出
    return {};

    });

    那么在使用r.js或者其他构建工具的时候,通过语法分析找到相关的数据(主要是路径和依赖),会编译成一个具名且明确依赖的模块,并且将依赖放到前边,比如app/index.js会被编译成这样:

    define('common/index', [], function (require) { /*.. */})

    define('app/index', ['../common/index'], function (require) { /* .. */ });

    合并的原因是,不合并的amd脚本根本没办法用。一个页面上异步加载好几十个脚本,然后才算启动成功,太low了,根本不能用到生产环境上。。。

    当然还有其他方面的考虑,请参考amd的规范。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1070 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 22:29 · PVG 06:29 · LAX 14:29 · JFK 17:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.