Cocos Creator v2.4.5-rc.1 测试帖

下周就能发布啦~



自定义脚本无法绑定

目前引擎提供的第三方库还没有适配 M1 上的 iOS 模拟器, 后续会支持.

刚升级2.4.4之后,微信小游戏遇到一个字体消失的bug,操作就是反复切后台后,系统字体消失了。

官方升级文档明明说是修复了这个bug的,但是测试之后,还是有问题。

手机型号:华为mate10
复现概率: 不高

补上字体labe的设置,刚让测试复现了一下,复现概率挺高的,比2.4.2高很多

image

按这个回复修改后,也没有效果

需要自己修改onHide和onShow,优化代码有更新,测试有效会在下个版本更新,这是微信这边给开发者的优化建议。

远程加载一个404的链接 为什么返回加载成功


版本 2.4.5rc2
提个bug,编辑器的cjs/loader.js 去识别和加载esm模块。。。

这个npm包是同时支持commonjs和esm规范的。按道理来说这个不应该去加载esm规范的
2.4.4正常

复现方式:新建空项目,npm install @ailhc/egf-core

估计是升级最新的electron导致的?或者是合并了3.0的代码?

2021-03-30T15:03:49.175Z - failed: load script [@ailhc/egf-core] failed : Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/mac/Documents/CocosSpace/test245/node_modules/@ailhc/egf-core/dist/es/lib/index.mjs
at Module.load (internal/modules/cjs/loader.js:990:11)
at Module._load (internal/modules/cjs/loader.js:885:14)
at Function.f._load (electron/js2c/asar_bundle.js:5:12734)
at Module.require [as __require] (internal/modules/cjs/loader.js:1032:19)
at Module.i.require (/Applications/CocosCreator/Creator/2.4.5-rc.2/CocosCreator.app/Contents/Resources/app.asar/editor-framework/lib/share/require.js:1:630)
at b (/Applications/CocosCreator/Creator/2.4.5-rc.2/CocosCreator.app/Contents/Resources/app.asar/editor-framework/lib/share/require.js:1:2179)
at Object.require (/Applications/CocosCreator/Creator/2.4.5-rc.2/CocosCreator.app/Contents/Resources/app.asar/editor/page/project-scripts.ccc:1:534)
at /Users/mac/Documents/CocosSpace/test245/temp/quick-scripts/dst/assets/AppMain.js:7:35
at __define (/Users/mac/Documents/CocosSpace/test245/temp/quick-scripts/dst/assets/AppMain.js:44:18)
at /Users/mac/Documents/CocosSpace/test245/temp/quick-scripts/dst/assets/AppMain.js:75:25

@EndEvil

模块解析去applyExports ,读取package.json,解析路径

function applyExports(basePath, expansion) {
  const mappingKey = `.${expansion}`;
//先去解析package.json的exports字段,刚好那个npm包就有exports字段指向index.mjs
  let pkgExports = readPackageExports(basePath);
  if (pkgExports === undefined || pkgExports === null)
    return false;

  if (isConditionalDotExportSugar(pkgExports, basePath))
    pkgExports = { '.': pkgExports };

  if (typeof pkgExports === 'object') {
    if (ObjectPrototypeHasOwnProperty(pkgExports, mappingKey)) {
      const mapping = pkgExports[mappingKey];
                 //就去解析脚本路径,并返回出去,index.mjs
      return resolveExportsTarget(pathToFileURL(basePath + '/'), mapping, '',
                                  mappingKey);
    }

    let dirMatch = '';
    for (const candidateKey of ObjectKeys(pkgExports)) {
      if (candidateKey[candidateKey.length - 1] !== '/') continue;
      if (candidateKey.length > dirMatch.length &&
          StringPrototypeStartsWith(mappingKey, candidateKey)) {
        dirMatch = candidateKey;
      }
    }

    if (dirMatch !== '') {
      const mapping = pkgExports[dirMatch];
      const subpath = StringPrototypeSlice(mappingKey, dirMatch.length);

      const resolved = resolveExportsTarget(pathToFileURL(basePath + '/'),
                                            mapping, subpath, mappingKey);
      // Extension searching for folder exports only
      const rc = stat(resolved);
      if (rc === 0) return resolved;
      if (!(RegExpPrototypeTest(trailingSlashRegex, resolved))) {
        const exts = ObjectKeys(Module._extensions);
        const filename = tryExtensions(resolved, exts, false);
        if (filename) return filename;
      }
      if (rc === 1) {
        const exts = ObjectKeys(Module._extensions);
//这里才去读package.json的main字段。。。
        const filename = tryPackage(resolved, exts, false,
                                    basePath + expansion);
        if (filename) return filename;
      }
      // Undefined means not found
      return;
    }
  }

  throw new ERR_PACKAGE_PATH_NOT_EXPORTED(basePath, mappingKey);
}

解析完路径,创建module对象,去加载

//尝试加载native 模块,没有
const mod = loadNativeModule(filename, request);
  if (mod && mod.canBeRequiredByUsers) return mod.exports;

  // Don't call updateChildren(), Module constructor already does.
//新建一个模块
  const module = new Module(filename, parent);

  if (isMain) {
    process.mainModule = module;
    module.id = '.';
  }

  Module._cache[filename] = module;
  if (parent !== undefined) {
    relativeResolveCache[relResolveCacheIdentifier] = filename;
  }

  let threw = true;
  try {
    // Intercept exceptions that occur during the first tick and rekey them
    // on error instance rather than module instance (which will immediately be
    // garbage collected).
    if (enableSourceMaps) {
      try {
//加载模块
        module.load(filename);
      } catch (err) {
        rekeySourceMap(Module._cache[filename], err);
        throw err; /* node-do-not-add-exception-line */
      }
    } else {
//我调试走了这里进去加载模块
      module.load(filename);
    }
    threw = false;
  } finally {
    if (threw) {
      delete Module._cache[filename];
      if (parent !== undefined) {
        delete relativeResolveCache[relResolveCacheIdentifier];
        const children = parent && parent.children;
        if (ArrayIsArray(children)) {
          const index = children.indexOf(module);
          if (index !== -1) {
            children.splice(index, 1);
          }
        }
      }
    }
  }

加载模块逻辑

Module.prototype.load = function(filename) {
  debug('load %j for module %j', filename, this.id);

  assert(!this.loaded);
  this.filename = filename;
  this.paths = Module._nodeModulePaths(path.dirname(filename));

  const extension = findLongestRegisteredExtension(filename);
  // allow .mjs to be overridden
//**阿这。。。mjs结尾的就不加载了?那为什么拿exports呢?**
  if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) {
//直接抛异常了
    throw new ERR_REQUIRE_ESM(filename);
  }
  Module._extensions[extension](this, filename);
  this.loaded = true;

  const ESMLoader = asyncESM.ESMLoader;
  const url = `${pathToFileURL(filename)}`;
  const module = ESMLoader.moduleMap.get(url);
  // Create module entry at load time to snapshot exports correctly
  const exports = this.exports;
  // Called from cjs translator
  if (module !== undefined && module.module !== undefined) {
    if (module.module.getStatus() >= kInstantiated)
      module.module.setExport('default', exports);
  } else {
    // Preemptively cache
    // We use a function to defer promise creation for async hooks.
    ESMLoader.moduleMap.set(
      url,
      // Module job creation will start promises.
      // We make it a function to lazily trigger those promises
      // for async hooks compatibility.
      () => new ModuleJob(ESMLoader, url, () =>
        new ModuleWrap(url, undefined, ['default'], function() {
          this.setExport('default', exports);
        })
      , false /* isMain */, false /* inspectBrk */)
    );
  }
};

但是拿到了exports又没法解析。。。

为什么3.0不会有问题呢?
解决方法:
Node.js 如何处理 ES6 模块

@EndEvil 大神,请教一个问题,
从2.2.2版本升上来遇到
我有个脚本是
用在onLoad的时候尝试对齐组件与canvas及parent节点的

onLoad()
{
    let root = this
    //这边使用了scheduleOnce来做为延时
    this.scheduleOnce( () =>
    {
        root.tryUpdateLayoutByRules()
    })
}

在2.2.2的时候是正常的
但是到了2.4.5就失败了,看起来是没有执行

现在在编辑器中 ,component的scheduleOnce是不会执行的吗?

這個的意思是,因為 v3 有實作,由於 v2 的code差異太大,目前暫時不考慮實作…對嗎?

我们确认下

谢谢,该问题已经修复

2.4.4 cc.tween()没有这三个方法吧:

2.4.5有吗


2.4.4有阿


我怎么没有啊,而且我硬填上去回报错啊
image

我错了,是大写然后这样用的啊,懂了。多谢!
image

不过我有个疑问,他tag是这样用的吗 怎么效果很奇怪

我懂了,不同节点里面tag是共用的

stopAllByTarget 用这个也行