CocosCreator2.4.2/2.4.3无法编译引用了项目文件夹外部的npm模块

  • Creator 版本:2.4.3

  • 目标平台:

  • 重现方式:

  • 首个报错:
    load script [@ailhc/egf-core] failed : Error: Cannot find module ‘@ailhc/egf-core’
    Require stack:

  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\project-scripts.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\scene-utils\lib\sandbox.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\scene-utils\edit-mode\index.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\scene-utils\index.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor-framework\lib\renderer\editor.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor-framework\lib\renderer\index.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor-framework\renderer.js
  • D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\index.html
    at Module._resolveFilename (internal/modules/cjs/loader.js:683:15)
    at Function.Module._resolveFilename [as _resolveFilenameVendor] (D:\programs\cocos-creator-editor\Creator\2.4.3\resources\electron.asar\common\reset-search-paths.js:43:12)
    at Function.c._resolveFilename (D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\project-scripts.js:1:1272)
    at Function.Module._load (internal/modules/cjs/loader.js:601:27)
    at Module.require (internal/modules/cjs/loader.js:739:19)
    at require (internal/modules/cjs/helpers.js:14:16)
    at Object.cc.require (D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\project-scripts.js:1:689)
    at __require (E:\framework_space\EasyGameFrameworkOpen\examples\egf-ccc-full\temp\quick-scripts\dst\assets\src\AppMainComp.js:7:35)
    at __define (E:\framework_space\EasyGameFrameworkOpen\examples\egf-ccc-full\temp\quick-scripts\dst\assets\src\AppMainComp.js:38:18)
    at E:\framework_space\EasyGameFrameworkOpen\examples\egf-ccc-full\temp\quick-scripts\dst\assets\src\AppMainComp.js:66:25
  • 之前哪个版本是正常的:
  • 手机型号:
  • 手机浏览器:
  • 编辑器操作系统:win10
  • 重现概率:100%

ccc-project-updir-node_modules-test.zip (883.7 KB)

影响运行和构建

temp里是编译成功的

建议emgine层看这块代码查找原因

1赞

谢谢,我破案了,可能是引擎编辑器逻辑问题,到时贴上我的破案记录

@jare 不好意思,打扰您了,我更新了demo项目

  • 注册时就走的不同路子

  • 然后逻辑走到了internal/modules/cjs/loader.js中,发现

  • 这个loader.js在load project_scripts.js时,是根据这个文件所在的位置来生成node_module paths
    D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\project-scripts.js

    • 所以paths里没有包含真实项目的所有node_modules路径
      0: “D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\page\node_modules”
      1: “D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\editor\node_modules”
      2: “D:\programs\cocos-creator-editor\Creator\2.4.3\resources\app.asar\node_modules”
      3: “D:\programs\cocos-creator-editor\Creator\2.4.3\resources\node_modules”
    • 然后具体A脚本在require某个模块的时候,使用的parent不是A脚本,而是project-scripts.js
    • 所以就会出问题,导致编辑器内对引用npm模块报错

通过调试发现,编辑器加载脚本时,require逻辑里,resolveFileName接口接收的参数的parent都是project-scripts.js
这个module,所以处理node_modules路径时,都是按照这个module的paths来处理,但这个module的paths只包含项目内的node_modules 以及编辑器的node_modules

希望官方能够解决:@jare
经过调试发现,编辑器编译脚本,走的模块引用路径是
cc.require,逻辑在在internal/modules/cjs/loader.js中,
每个模块去require脚本时 走这个,

Module._load = function(request, parent, isMain)

传的parent不是那个模块(比如,A模块引用 @ailhc/egf-cli 那么,parent应该是A)
但是
parent都是一个app.asar\editor\\page\project-scripts.js 这样一个脚本。
所以,这个
parent的paths里没有项目外的node_modules文件夹路径
结果就是
编辑器编译脚本有问题,构建时编译脚本有问题,因为他们走的都是cc.require 。

预览的编译很正常,走的是__quick_compile_project__.require

这是预览编译和编辑器编译,构建编译的不一致。最好能够一致,不然这种问题有点恶心

临时解决方案(第二版:解决构建问题):
增加一个editor_require_fix.js,并设置为插件,只勾选web和编辑器加载就行

//主要是解决在monorepo环境下使用npm包,以及多项目共用npm包时,编辑器编译报错,构建编译报错的问题
//原因是编辑器环境编译和构建编译走cc.require,都会经过app.asar\\editor\\\page\\project-scripts.js来进行引用
//而这个app.asar\\editor\\\page\\project-scripts.js模块的node_modules路径只包含项目内的,以及编辑器内的,不包括项目外的node_modules
//放入assets目录中,设置为插件就可以了
if (CC_EDITOR) {
    const projectScriptsModule = process.mainModule.constructor._cache[process.resourcesPath + "\\app.asar\\editor\\\page\\project-scripts.js"];
    // cc.log(projectScriptsModule.id);
    // cc.log(projectScriptsModule.paths);
    if (!projectScriptsModule.isAddCustomPaths) {
        const projectPath = Editor.remote.AssetDB.assetdb.cwd;//项目路径
        // let pathStrs = projectPath.split("\\");
        // const upDirName = pathStrs[pathStrs.length - 1];
        // const up_Dir_node_modules_path = projectPath.replace(upDirName, "node_modules");
        // const up_upDirName = pathStrs[pathStrs.length - 2];
        // const up_up_Dir_node_modules_path = projectPath.replace(up_upDirName + "\\" + upDirName, "node_modules");
        const path = process.mainModule.require("path");
        //添加node_modules路径,按需增加
        const up_Dir_node_modules_path = path.resolve(projectPath, "..\\node_modules");
        const up_up_Dir_node_modules_path = path.resolve(projectPath, "..\\..\\node_modules");
        projectScriptsModule.paths.push(up_Dir_node_modules_path);
        projectScriptsModule.paths.push(up_up_Dir_node_modules_path);
        projectScriptsModule.isAddCustomPaths = true;
        // cc.warn("路径")
        // cc.warn(projectScriptsModule.paths);
    }



}
2赞

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。