Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于将 egg 项目 node_modules 上传层部署问题 #11

Closed
yugasun opened this issue May 14, 2020 · 6 comments
Closed

关于将 egg 项目 node_modules 上传层部署问题 #11

yugasun opened this issue May 14, 2020 · 6 comments
Labels

Comments

@yugasun
Copy link
Contributor

yugasun commented May 14, 2020

由于 egg 框架在加载插件时,查询路径是固定的三个路径:

  • {APP_PATH}/node_modules
  • {EGG_PATH}/node_modules
  • $CWD/node_modules

官方代码:

getPluginPath(plugin) {
    if (plugin.path) {
      return plugin.path;
    }

    const name = plugin.package || plugin.name;
    const lookupDirs = [];

    // 尝试在以下目录找到匹配的插件
    //  -> {APP_PATH}/node_modules
    //    -> {EGG_PATH}/node_modules
    //      -> $CWD/node_modules
    lookupDirs.push(path.join(this.options.baseDir, 'node_modules'));

    // 到 egg 中查找,优先从外往里查找
    for (let i = this.eggPaths.length - 1; i >= 0; i--) {
      const eggPath = this.eggPaths[i];
      lookupDirs.push(path.join(eggPath, 'node_modules'));
    }

    // should find the $cwd/node_modules when test the plugins under npm3
    lookupDirs.push(path.join(process.cwd(), 'node_modules'));

    for (let dir of lookupDirs) {
      dir = path.join(dir, name);
      if (fs.existsSync(dir)) {
        return fs.realpathSync(dir);
      }
    }

    throw new Error(`Can not find plugin ${name} in "${lookupDirs.join(', ')}"`);
},

参考:https://github.com/eggjs/egg-core/blob/ca04a457c8cc7a1c1cc77a4e62a6cfde29a5ef19/lib/loader/mixin/plugin.js#L328-L359

导致如果将 node_modules 部署到层后,egg 的云函数会报插件找不到问题,主要是 EGG_PATH 路径在层加载的目录下面,此路径会变成 /opt/egg,进而导致查询 egg 插件模块路径变成 /opt/egg/node_modules,而此时所有 npm 依赖模块路径是 /opt/node_modules,为此我们需要改写 EGG_PATH,代码如下:

Object.defineProperty(Application.prototype, Symbol.for('egg#eggPath'), {
  value: '/opt'
})

最终解决方案,在项目目录新增 sls.js 入口文件:

const { Application } = require('egg')

Object.defineProperty(Application.prototype, Symbol.for('egg#eggPath'), {
  value: '/opt'
})

const app = new Application({
  env: 'prod',
})

// 指定 binary types 类型
app.binaryTypes = ['*/*']

module.exports = app

然后重新部署即可。

注意:确保上传的 layer 是包含 node_modules 文件夹

@yugasun yugasun pinned this issue May 14, 2020
@yugasun yugasun added the FAQ label May 14, 2020
@iqingting
Copy link

该方法我这里测试不行,报这个错误,将 node_modules 上传后没问题

{
"errorCode": -1,
"errorMessage": "user code exception caught",
"stackTrace": "Error: Can not find plugin egg-onerror in \"/var/user/node_modules, /opt/node_modules, /opt/egg/node_modules, /var/user/node_modules\"\n    at AppWorkerLoader.getPluginPath (/opt/egg-core/lib/loader/mixin/plugin.js:358:11)\n    at AppWorkerLoader.loadPlugin (/opt/egg-core/lib/loader/mixin/plugin.js:108:26)\n    at AppWorkerLoader.loadConfig (/opt/egg/lib/loader/app_worker_loader.js:16:10)\n    at new EggApplication (/opt/egg/lib/egg.js:54:17)\n    at new Application (/opt/egg/lib/application.js:60:5)\n    at Object.<anonymous> (/var/user/sls.js:7:13)\n    at Module._compile (internal/modules/cjs/loader.js:701:30)\n    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)\n    at Module.load (internal/modules/cjs/loader.js:600:32)\n    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)"
}

@yugasun
Copy link
Contributor Author

yugasun commented May 15, 2020

@iqingting 如果使用的是 v1 版本,可以尝试清理本地缓存 rm -rf ~/.serverless,然后新增 sls.js 文件,重新部署。如果使用 v2 版本,新增 sls.js 文件后,直接重新部署即可。

@iqingting
Copy link

v2 版本,重新部署还是这个问题。是不是因为 tencent-egg 这个 component 没更新

@yugasun
Copy link
Contributor Author

yugasun commented May 15, 2020

同时确保上传的 layer 是包含 node_modules 文件夹。验证方式,下载该层代码,解压后是有 node_modules 文件夹。

@iqingting
Copy link

搞定了。之前是直接上传的文件夹,所以有问题。自己压缩上传 zip 包就可以了

@yugasun
Copy link
Contributor Author

yugasun commented Nov 23, 2020

已支持基于层部署自动注入配置变更:#20
因此用户无需再自己创建上述 sls.js 文件。

@yugasun yugasun closed this as completed Nov 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants