2.4.x如何弄全局类

但是该循环引用还是循环引用 循环引用是模块加载的问题
建议使用 import()动态导入 或者require() :sweat_smile:

马赛克有分享过一个动态模块的写法

我也学习模仿了

/**
 * 异步引用脚本方法
 * @deprecated 一般使用require()同步加载
 * @param importer import()
 * @returns 动态导入的模块
 */
function requireAsync<T extends Promise<any>>(importer: T): Awaited<T> {
    //获取动态导入的模块
    let modules: Awaited<T> = Object.create(null);
    importer.then(exports => modules = exports);
    //处理异步返回
    return new Proxy(modules, {
        get(target: Awaited<T>, module: string) {
            //获取模块
            if (modules[module]) return modules[module];
            //调用模块
            return new Proxy(modules, {
                get(target: Awaited<T>, property: string) {
                    if (modules[module]) return modules[module][property];
                    console.log(`${modules[module]}模块未完载, 调用${property}方法失败!`);
                    return null;
                },
            });
        },
    });
}

不过后来想了下 还不如补个require的全局声明直接用require的好

declare global {
    /**
     * 同步引用脚本方法
     * @param module 模块加载路径
     * @example require<typeof import('./Global')>('./Global').default;
     * @returns 返回同步加载的模块
     */
    function require<T = { default: any }>(module: string): T;
}

如果出现了循环引用的问题还是多琢磨琢磨怎么组织代码的问题 模块加载顺序就随它去吧 还是不care的好

我写上面的就是为了不在函数内使用import,每次都需要填写脚本路径,改的时候你会发现很麻烦,用我的方式你只需要写一行代码在脚本最上方导入就行了

对于楼主的问题,这个我之前研究过所有的方式,能推荐给你的就一种,不想要每次都导入那么就只能用d.ts文件,其他方式都有各自的缺点。

生成d.ts可以参考我的MKFramework,gitee或者github搜就行,最新的dev分支做了cc插件,分离了d.ts生成代码可以自行参考,mk框架之所以还要导入是因为d.ts需要import项目中的ts文件不能做成全局,否则我也全局了

是的…

我是这样用的,不知道有没有问题

// 命名空间声明,用于代码提示
declare global {
    namespace app {
        let data: GameData;
        let ctrl: GameCtrl;
    }
}

class Init {
    constructor() {
        // 命名空间实际定义
        window['app'] = window.app || {
            data: null,
            ctrl: null,
        };

        app.data = GameData.getInstance();
        app.ctrl = GameCtrl.getInstance();
    }
}
export default new Init();

// 调用
app.ctrl.getAllData();

可以参照一下我这个,把所有公用的函数打包成一个lib
然后做为全局调用。
https://forum.cocos.org/t/topic/132963

看了mk项目,然后找到了build_dts生成脚本遇到两个问题
1.npx api-extractor run --local --diagnostics这个命令执行失败
2.prettier.format执行失败
对于2提示了No parser and no file path given, couldn’t infer a parser,我单纯拿一个很简单的几行数据的json文件都会被提示失败
对于1提示找log文件看错误,打开文件发现有error could not determine executable to run的日志
查了下看是否目录不对,但是起输出当前目录和命令执行目录都已经在当前脚本执行的目录下,
然后检查mk工程里有一个api-extractor.json文件 我复制过去脚本执行目录下,然后改了下对应的路径
其中需要修改的地方大概浏览了下有以下几个
mainEntryPointFilePath
reportFolder
publicTrimmedFilePath
确认了一下相对路径没错(以当前脚本执行路径为目录做相对路径)
因此这两个问题的出现大概是能定位什么问题导致吗?

我通过typescript库用tsc生成各个文件.d.ts后 ,自己用fs库来把她们衔接成一个.d.ts ,然后放在项目根目录,类似creator.d.ts和cc.d.ts的文件 但是内部文件依然找不到 不知道哪里出了问题,我这个方案是不可行的吗

那是不是意味着每加一个新的文件或者已有的文件中添加类或者枚举、接口、结构体等等都需要再这个命名空间手动去写一个的意思?

1赞

你先要保证 api-extractor 和 prettier 对应的 npm 包已经安装,还有问题就直接命令行执行,会有错误打印

另外最好不要用 tsc 生成单 d.ts 文件,因为如果你的打包代码内引用了外部的脚本,会一起生成 d.ts,即使你添加了 exclude 路径也一样,这些坑我早就躺过了,api-extractor 就是打包单 d.ts 的,另外还有其他功能可以参考 api-extractor 官网

我看你build_dts脚本也用了tsc的命令 :sweat_smile:
具体是 npx -p typescript tsc
那个不就是为了把项目编译出d.ts,然后再通过npx api-extractor run --local --diagnostics
来获取里边的api吗 我是这么去理解的,不过我在用这个脚本思路去构建我的脚本时遇到几个问题
1.tsc这个命令并不能完全帮助我把项目的ts文件全部编译成.d.ts,里边会报出cc的引擎库找不到,可能就是像你说的那个第三方库依赖问题,最终结果就是那个带有cc引用的文件ts会编译不出.d.ts
2.就是api-extractor接口问题,大致就是找不到路径什么的,应该是跟api-extractor.json的配置不正确相关,但是我是看了mk的示例去把路径改成自己的
比如 “mainEntryPointFilePath”: “…/…/xx.d.ts”, 改成了相对路径 (.d.ts应该是基于问题1所生成好的合并文件吧)
3.prettier的格式化问题,主要就是使用prettier.format时报出,具体问题就是我之前描述的一样,我也尝试过用一个简单几行的json文件让它去执行也是失败 然后我主要怀疑.prettierrc.json的配置实现,也同样参考mk的,基本我都没改照搬到自己的目录下
综上所述我的排查方向主要在两个json文件当中 npm包肯定是装了的 环境变量也专门去设了 也是全局安装 目前还在纠结当中 :rofl:
最新进展:
之前一直尝试用creator.d.ts来试不成功,但是用自己的自定义类弄出来的.d.ts就可以,
估且认为问题2算是解决,但是问题1的问题让我无法生成合并为一个完整的.d.ts让我很困惑。
另外就是目前通过api-extractor打出来的的包跟tsc生成好像没什么区别
最新进展2:
目前问题1解决了,只需要在入口文件加上/// 就可以了
现在回到问题2中 这个npx api-extractor run --local --diagnostics 这个命令是只能编译一个.d.ts吗
意思是我需要先提前组装好零散的.d.ts文件合成一个最终的.d.ts再交给这个命令处理吧
我尝试了几个.d.ts文件通过这个命令出来的结果是两个文件几乎没有区别 只是最后多了个export { }
这让我很是费解

还不如直接去看麒麟子的tgx

目前已经完成整合项目中的ts文件,重新生成一个.d.ts,然后各个ts写逻辑也不需要再import
但是creator编辑器会报

  • load script [./assets/script/xxxxxx] failed : ReferenceError: xxxxx is not defined

我的意思是单d.ts文件,是所有的d.ts整合

和声明文件无关啊 这是模块加载顺序的问题

恕我直言,之前看过,感觉甚至没有论坛其他框架好

论坛里框架话题的热度一言难尽 :joy:

你可以暂时忽略第三个格式化问题,那是我为了生成的d.ts好查看加的逻辑

第二个问题是,api-extractor的作用和你想的差不多,就是将所有引用的d.ts整合为一个,tsc也可以但是有我上面说的问题,入口d.ts是需要引用其他d.ts,才能整合其他的d.ts文件,这个和模块结构有关,你可以查看MK的mk_export.ts文件,使用一样的导出方式就可以了

另外你可以直接去api-extractor的官网查看文档,比我说的详细

另外编辑器报错的原因是你没有在全局注册,例如self.mk = mk_export导出的内容,这就是在全局注册,你可以参考mk_init.ts

还有问题可以点我头像加群讨论

框架这东西最好自己弄一个 借鉴下别人写的好的地方就行

我目前已经成功输出.d.ts 放在跟creator.d.ts一个目录 但是编辑器会报出load xxx脚本 fail之类 而且很多
但是编辑器已经不会报错了 仿佛creator不认识这个.d.ts 这个是什么原因
而且还有很多挂脚本的预制体或者节点都会报某些脚本出问题 不知道是不是没有import后creator就不认识脚本了
你所说的全局注册是指定在入口import吗这个.d.ts还是怎么 我尝试过用///
也试过import这个生成后的dts文件名"xxx"
要么让我添加一个命名空间 但cocos不认
要么就是各个文件不能允许出现export 然后直接全局就能使用 但cocos同样不认