2.4.x如何弄全局类

在A.ts文件和B.ts文件各自不需要import 随意用互相的类和函数 有办法吗,项目大了就一堆import,有时候换个文件位置全部要变引用 头都大

命名空间了解一下 :clap:

注册到globalThis ,自己在.d.ts里面声明一下

我觉得妥,我TGX 也打算这样弄!

class App {
    get xxx() {
        return xxxx
    }       
}
declare global {
    var $app: App
    interface global {
        $app: App
    }
}
window.$app = new App()

这样就能跨了,一个$app就够了,别太多
然后在你的启动scene上方,import “./App” 就可以了
减少到处import,然后修改漏掉的风险

【包教包会】CocosCreator怎么用namespace实现类似于cc的全局变量

1赞

我看过这个帖子,但是并不是我想要的,我之前在家公司就是完全毫无感知在某个文件夹里写好了某个xxx.ts,然后在别人的ts里边就能够直接知道我写的ts的所有类和函数,自己在写自己的ts时没有意识要export或者要import什么,也忘了看他们是怎么实现的,现在回想起来感觉好神奇

然后就是这个帖子的demo 我下载后发现依然提示我要import
image

能详细描述一下吗,就是这个App里边的get XXX 是各个模块功能的类?

你没仔细看帖子
把Demo里的“gi.d.ts”复制到项目根目录就好了,也就是assets这个文件夹的同级目录
你可以百度下.d.ts,你说的那个也是通过这个来实现的

//HelloWorld.ts
export namespace xx {
    export let say: string = 'hello';
}
declare global {
    let xx: typeof import('./HelloWorld').xx;
}
window['xx'] = require('./HelloWorld')['xx'];
//anyScript.ts
class App {
    say: string = 'hello';
}
declare global {
    interface Window {
        app: App;
    }
    let app: App;
}
window.app = new App();
//anyScript.ts
namespace App {
    export const say: string = 'hello';
}
globalThis['App'] = App;
//anyScript.ts
class App {
    static say: string = 'hello';
}
globalThis['App'] = App;

想要实现'全局调用’只要把一个namespace或class或变量进行'全局'声明然后挂载到'全局'上

:joy:当初我也是摸索好久:joy:

但是该循环引用还是循环引用 循环引用是模块加载的问题
建议使用 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 官网