fex-team/fis3-hook-amd

fis3构建requirejs项目出现define的模块能被加载,但不执行回调的情况

Closed this issue · 11 comments

这种问题真不知道是报给FIS3的人还是requirejs的人,但考虑不使用fis3的情况下能正常使用,还是报到这里来吧,描述如下面代码

模块文件module/a.js

define(['jquery'], function($) { return {a: 0};});

构建后a.js的代码会变为

define('a', ['jquery'], function($) { return {a:0};});

假设我们正常通过路径去require这个模块,页面会多一段map代码配置path

require('/module/a', function(a){//do something}); 页面fis3生成的代码require.config({paths:{ "module/a": "/module/a" }});

但是如果像下面这样加载的话,即便a模块加载完成了,但模块的回调代码不执行,引用该模块的地方为undefined,因为这样页面不会生成map配置代码

var config = {url: '/module/a'};require([config.url], function(a){//err: a is undefined.});

相关信息,moduleName与args[0]不一致,这样不会执行里面的逻辑

requirejs源码completeLoad方法,else if (args[0] === moduleName) {
//Found matching define call for this script!
found = true;
}

fis 这边的问题,编译后的结果不符合预期,应该是这样

define('a', ['require', 'jquery'], function(require, $) { return {a:0};});

晚点修复哈

hi, 我刚试了下,产出并不是你说的那个样,升级 fis3-hook-amd 插件重试 ?

产出是define('a', ['jquery'], function($) { return {a:0};}); 我写错了,应该是没错的,但是我要说明的不是这个的问题,而是你在在require时用的不是字符串而是一个变量,define的模块加载进来的时候就不执行回调了,原因是moduleName 是'/module/a.js'与define的'a'不一样,这是我跟require源码发现的,如果我表述不是很明确并且你方便的话可以选择其他沟通方式

哦,正常来说, a 构建后,module ID 应该也是module/a, 不知道你那为何变成了 a 了,把你的项目放到一个仓库上,让我看看?

但是,fis 是分析不到变量中依赖的,只能用字面量。如:

require(['/components/msg/msg'], function(msg) {
  msg.sayHello();
});

嗯,我知道是这样,有没有可能通过让他们的名字匹配起来,解决这种问题呢?比如像js里使用__uri(path)那样,有这样一个函数__require(path),然后去生成map,并且把此处的path替换成map中的key,这样编译的话,就不会有那样的问题了。毕竟不支持动态配置path不利于我们写自己的组件,比如我写了一个组件,要传一个controllerUrl进去,本来只需要 controllerUrl: 'module/a.js'; 然后组件里面require([controllerUrl], function(a){});但按照这种情况,我只能传一个方法进去了controllerUrl: function(callback){require('module/a.js', function(a) {callback(a)}); 然后在组件里面写一个callback,再controllerUrl(callback); 这样破坏了原有的工程结构,是比较头疼的,不管怎样,非常感谢您的回答,也希望能有一种解决方案吧。

/**
 * Created by vengean on 15/11/2.
 * @require.async "../components/msg/msg.js"
 */
require([], function(){
    var config = {url: __moduleId('../components/msg/msg.js')};

    require([config.url], function(msg) {
        msg.sayHello();
    });
});

需要两步

  1. 标记依赖
  2. 通过 __moduleId(xxx) 获取模块 ID

这是原来就支持的吗?好像没在插件的文档里面看到过。感谢您的帮助

文档里面是还没有