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

部署到heroku时出现错误,请大神指点 #15819

Open
1 task done
zhuoyue2022 opened this issue Jun 4, 2024 · 4 comments
Open
1 task done

部署到heroku时出现错误,请大神指点 #15819

zhuoyue2022 opened this issue Jun 4, 2024 · 4 comments
Labels
RSS bug Something isn't working

Comments

@zhuoyue2022
Copy link

路由地址

NOROUTE

完整路由地址

NOROUTE

相关文档

heroku.com

预期是什么?

请问错误在哪儿,谢谢

实际发生了什么?

部署不成功

部署

RSSHub 演示 (https://rsshub.app)

部署相关信息

No response

额外信息

-----> Building on the Heroku-22 stack
-----> Determining which buildpack to use for this app
-----> Node.js app detected
       
-----> Creating runtime environment
       
       NPM_CONFIG_LOGLEVEL=error
       NODE_VERBOSE=false
       NODE_ENV=production
       NODE_MODULES_CACHE=true
       
-----> Installing binaries
       engines.node (package.json):   22.x
       engines.npm (package.json):    unspecified (use default)
       engines.pnpm (package.json):   unspecified (use default)
       packageManager (package.json): [email protected]
       
       Resolving node version 22.x...
       Downloading and installing node 22.2.0...
       Using default npm version: 10.7.0
       Installing [email protected] via corepack 0.28.1
       Using pnpm 9.1.4
       
-----> Installing dependencies
       Running 'pnpm install' with pnpm-lock.yaml
       Packages are hard linked from the content-addressable store to the virtual store.
         Content-addressable store is at: /tmp/pnpmcache.60ALe/v3
         Virtual store is at:             node_modules/.pnpm
       .../[email protected]/node_modules/core-js postinstall$ node -e "try{require('./postinstall')}catch(e){}"
       .../[email protected]/node_modules/esbuild postinstall$ node install.js
       .../node_modules/utf-8-validate install$ node-gyp-build
       .../node_modules/bufferutil install$ node-gyp-build
       .../node_modules/msw postinstall$ node -e "try{require('./config/scripts/postinstall')}catch(e){}"
       .../[email protected]/node_modules/core-js postinstall: Done
       .../node_modules/msw postinstall: Done
       .../node_modules/puppeteer postinstall$ node install.mjs
       .../[email protected]/node_modules/esbuild postinstall: Done
       .../node_modules/bufferutil install: Done
       .../node_modules/utf-8-validate install: Done
       .../[email protected]/node_modules/es5-ext postinstall$  node -e "try{require('./_postinstall')}catch(e){}" || exit 0
       .../[email protected]/node_modules/es5-ext postinstall: Done
       .../node_modules/puppeteer postinstall: Done
       
       dependencies:
       + @hono/node-server 1.11.2
       + @hono/swagger-ui 0.2.2
       + @hono/zod-openapi 0.14.1
       + @notionhq/client 2.2.15
       + @postlight/parser 2.2.3
       + @sentry/node 8.7.0
       + @tonyrl/rand-user-agent 2.0.66
       + aes-js 3.1.2
       + art-template 4.13.2
       + bbcodejs 0.0.4
       + cheerio 1.0.0-rc.12
       + chrono-node 2.7.6
       + city-timezones 1.2.1
       + cross-env 7.0.3
       + crypto-js 4.2.0
       + currency-symbol-map 5.1.0
       + dayjs 1.11.8
       + destr 2.0.3
       + directory-import 3.3.1
       + dotenv 16.4.5
       + entities 4.5.0
       + etag 1.8.1
       + fanfou-sdk 5.0.0
       + form-data 4.0.0
       + googleapis 137.1.0
       + hono 4.4.3
       + html-to-text 9.0.5
       + https-proxy-agent 7.0.4
       + iconv-lite 0.6.3
       + imapflow 1.0.162
       + instagram-private-api 1.46.1
       + ioredis 5.4.1
       + ip-regex 5.0.0
       + jsdom 24.1.0
       + json-bigint 1.0.0
       + jsrsasign 10.9.0
       + lru-cache 10.2.2
       + lz-string 1.5.0
       + mailparser 3.7.1
       + markdown-it 14.1.0
       + module-alias 2.2.3
       + notion-to-md 3.1.1
       + oauth-1.0a 2.2.6
       + ofetch 1.3.4
       + otplib 12.0.1
       + pac-proxy-agent 7.0.1
       + proxy-chain 2.4.0
       + puppeteer 22.6.2
       + puppeteer-extra 3.3.6
       + puppeteer-extra-plugin-stealth 2.11.2
       + puppeteer-extra-plugin-user-data-dir 2.4.1
       + puppeteer-extra-plugin-user-preferences 2.4.1
       + query-string 9.0.0
       + rate-limiter-flexible 5.0.3
       + re2js 0.4.1
       + rfc4648 1.5.3
       + rss-parser 3.13.0
       + sanitize-html 2.13.0
       + simplecc-wasm 0.1.5
       + socks-proxy-agent 8.0.3
       + source-map 0.7.4
       + telegram 2.21.2
       + tiny-async-pool 2.1.0
       + title 3.5.3
       + tldts 6.1.24
       + tosource 2.0.0-alpha.3
       + tough-cookie 4.1.4
       + tsx 4.11.2
       + twitter-api-v2 1.17.1
       + undici 6.18.2
       + uuid 9.0.1
       + winston 3.13.0
       + xxhash-wasm 1.0.2
       + zod 3.23.8
       
       devDependencies:
       + @babel/preset-env 7.24.6
       + @babel/preset-typescript 7.24.6
       + @microsoft/eslint-formatter-sarif 3.1.0
       + @stylistic/eslint-plugin 2.1.0
       + @types/aes-js 3.1.4
       + @types/babel__preset-env 7.9.6
       + @types/crypto-js 4.2.2
       + @types/eslint 8.56.10
       + @types/eslint-config-prettier 6.11.3
       + @types/etag 1.8.3
       + @types/fs-extra 11.0.4
       + @types/html-to-text 9.0.4
       + @types/imapflow 1.0.18
       + @types/js-beautify 1.14.3
       + @types/jsdom 21.1.7
       + @types/json-bigint 1.0.4
       + @types/jsrsasign 10.5.13
       + @types/lint-staged 13.3.0
       + @types/mailparser 3.4.4
       + @types/markdown-it 14.1.1
       + @types/module-alias 2.0.4
       + @types/node 20.14.0
       + @types/sanitize-html 2.11.0
       + @types/supertest 6.0.2
       + @types/tiny-async-pool 2.0.3
       + @types/title 3.4.3
       + @types/tough-cookie 4.0.5
       + @types/uuid 9.0.8
       + @typescript-eslint/eslint-plugin 7.11.0
       + @typescript-eslint/parser 7.11.0
       + @vercel/nft 0.27.1
       + @vitest/coverage-v8 1.6.0
       + eslint 8.57.0
       + eslint-config-prettier 9.1.0
       + eslint-nibble 8.1.0
       + eslint-plugin-n 17.7.0
       + eslint-plugin-prettier 5.1.3
       + eslint-plugin-unicorn 53.0.0
       + eslint-plugin-yml 1.14.0
       + fs-extra 11.2.0
       + got 14.3.0
       + husky 9.0.11
       + js-beautify 1.15.1
       + lint-staged 15.2.5
       + mockdate 3.0.5
       + msw 2.3.1
       + prettier 3.3.0
       + remark-parse 11.0.0
       + supertest 7.0.0
       + typescript 5.4.5
       + unified 11.0.4
       + vite-tsconfig-paths 4.3.2
       + vitest 1.6.0
       
       
       > [email protected] prepare /tmp/build_fe102604
       > husky || true
       
       .git can't be foundDone in 18.4s
       
-----> Build
       Running build
       
       > [email protected] build /tmp/build_fe102604
       > tsx scripts/workflow/build-routes.ts
       
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
node:internal/modules/run_main:115
    triggerUncaughtException(
    ^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/tmp/build_fe102604/assets/build/routes.json' imported from /tmp/build_fe102604/lib/registry.ts
    at finalizeResolution (node:internal/modules/esm/resolve:260:11)
    at moduleResolve (node:internal/modules/esm/resolve:920:10)
    at defaultResolve (node:internal/modules/esm/resolve:1119:11)
    at nextResolve (node:internal/modules/esm/hooks:791:28)
    at F (file:///tmp/build_fe102604/node_modules/.pnpm/[email protected]/node_modules/tsx/dist/esm/index.mjs?1717508465425:2:3184)
    at nextResolve (node:internal/modules/esm/hooks:791:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:238:30)
    at handleMessage (node:internal/modules/esm/worker:255:24)
    at Immediate.checkForMessages (node:internal/modules/esm/worker:157:28)
    at process.processImmediate (node:internal/timers:478:21) {
  code: 'ERR_MODULE_NOT_FOUND',
  url: 'file:///tmp/build_fe102604/assets/build/routes.json'
}
Node.js v22.2.0
        ELIFECYCLE  Command failed with exit code 1.
-----> Build failed
       
       We're sorry this build is failing! You can troubleshoot common issues here:
       https://devcenter.heroku.com/articles/troubleshooting-node-deploys
       
       If you're stuck, please submit a ticket so we can help:
       https://help.heroku.com/
       
       Love,
       Heroku
       
 !     Push rejected, failed to compile Node.js app.
 !     Push failed

这不是重复的 issue

  • 我已经搜索了 现有 issue,以确保该错误尚未被报告。
@zhuoyue2022 zhuoyue2022 added the RSS bug Something isn't working label Jun 4, 2024
@redstarence

This comment was marked as duplicate.

@Means88
Copy link
Contributor

Means88 commented Sep 20, 2024

可以在部署的时候初始化一下 git 仓库

package.json

-    "prepare": "husky || true",
+    "prepare": "git init && git config user.email <youremail> && git config user.name <yourname> && git add -A && git commit -m \"initial commit\" && husky || true",

@YicunWendyWu
Copy link

可以在部署的时候初始化一下 git 仓库

package.json

-    "prepare": "husky || true",
+    "prepare": "git init && git config user.email <youremail> && git config user.name <yourname> && git add -A && git commit -m \"initial commit\" && husky || true",

初始化git仓库之后,没有了git错误的部分,但还是会有ERR_MODULE_NOT_FOUND的部分

@YicunWendyWu
Copy link

用Claude生成的diff, 现在可以heroku部署了,供参考

diff --git a/lib/registry.ts b/lib/registry.ts
index 0ac903323..753c99044 100644
--- a/lib/registry.ts
+++ b/lib/registry.ts
@@ -3,9 +3,9 @@ import { directoryImport } from 'directory-import';
 import { Hono, type Handler } from 'hono';
 import path from 'node:path';
 import { fileURLToPath } from 'node:url';
+import fs from 'node:fs';
 import { serveStatic } from '@hono/node-server/serve-static';
 import { config } from '@/config';
-
 import index from '@/routes/index';
 import healthz from '@/routes/healthz';
 import robotstxt from '@/routes/robots.txt';
@@ -26,20 +26,35 @@ let namespaces: Record<
     }
 > = {};
 
-switch (process.env.NODE_ENV) {
-    case 'test':
-    case 'production':
-        // @ts-expect-error
-        namespaces = await import('../assets/build/routes.json');
-        break;
-    default:
-        modules = directoryImport({
-            targetDirectoryPath: path.join(__dirname, './routes'),
-            importPattern: /\.ts$/,
-        }) as typeof modules;
+async function loadNamespaces() {
+    switch (process.env.NODE_ENV) {
+        case 'test':
+        case 'production':
+            try {
+                const routesPath = path.join(process.cwd(), 'assets', 'build', 'routes.json');
+                if (fs.existsSync(routesPath)) {
+                    const routesContent = await fs.promises.readFile(routesPath, 'utf-8');
+                    namespaces = JSON.parse(routesContent);
+                } else {
+                    console.warn('routes.json not found. Falling back to directory import.');
+                    await loadModules();
+                }
+            } catch (error) {
+                console.error('Error loading routes.json:', error);
+                await loadModules();
+            }
+            break;
+        default:
+            await loadModules();
+    }
 }
 
-if (Object.keys(modules).length) {
+async function loadModules() {
+    modules = directoryImport({
+        targetDirectoryPath: path.join(__dirname, './routes'),
+        importPattern: /\.ts$/,
+    }) as typeof modules;
+
     for (const module in modules) {
         const content = modules[module] as
             | {
@@ -81,9 +96,12 @@ if (Object.keys(modules).length) {
     }
 }
 
+await loadNamespaces();
+
 export { namespaces };
 
 const app = new Hono();
+
 for (const namespace in namespaces) {
     const subApp = app.basePath(`/${namespace}`);
     for (const path in namespaces[namespace].routes) {
@@ -103,10 +121,12 @@ for (const namespace in namespaces) {
 app.get('/', index);
 app.get('/healthz', healthz);
 app.get('/robots.txt', robotstxt);
+
 if (config.debugInfo) {
     // Only enable tracing in debug mode
     app.get('/metrics', metrics);
 }
+
 app.use(
     '/*',
     serveStatic({
@@ -115,4 +135,4 @@ app.use(
     })
 );
 
-export default app;
+export default app;
\ No newline at end of file
diff --git a/scripts/workflow/build-routes.ts b/scripts/workflow/build-routes.ts
index 9003f73e4..6209c60aa 100644
--- a/scripts/workflow/build-routes.ts
+++ b/scripts/workflow/build-routes.ts
@@ -1,73 +1,105 @@
 import { namespaces } from '../../lib/registry';
 import { RadarItem } from '../../lib/types';
 import { parse } from 'tldts';
-import fs from 'node:fs';
-import path from 'node:path';
+import fs from 'fs/promises';
+import path from 'path';
 import toSource from 'tosource';
-
 import { getCurrentPath } from '../../lib/utils/helpers';
+
 const __dirname = getCurrentPath(import.meta.url);
 
-const maintainers: Record<string, string[]> = {};
-const radar: {
-    [domain: string]: {
-        _name: string;
-        [subdomain: string]: RadarItem[] | string;
-    };
-} = {};
+async function ensureDirectoryExists(dirPath: string) {
+    try {
+        await fs.mkdir(dirPath, { recursive: true });
+    } catch (error) {
+        console.error(`Error creating directory ${dirPath}:`, error);
+    }
+}
 
-for (const namespace in namespaces) {
-    let defaultCategory = namespaces[namespace].categories?.[0];
-    if (!defaultCategory) {
-        for (const path in namespaces[namespace].routes) {
-            if (namespaces[namespace].routes[path].categories) {
-                defaultCategory = namespaces[namespace].routes[path].categories[0];
-                break;
+async function writeJsonFile(filePath: string, data: any) {
+    try {
+        await fs.writeFile(filePath, JSON.stringify(data, null, 2));
+        console.log(`Successfully wrote ${filePath}`);
+    } catch (error) {
+        console.error(`Error writing ${filePath}:`, error);
+    }
+}
+
+async function main() {
+    const maintainers: Record<string, string[]> = {};
+    const radar: {
+        [domain: string]: {
+            _name: string;
+            [subdomain: string]: RadarItem[] | string;
+        };
+    } = {};
+
+    for (const namespace in namespaces) {
+        let defaultCategory = namespaces[namespace].categories?.[0];
+        if (!defaultCategory) {
+            for (const path in namespaces[namespace].routes) {
+                if (namespaces[namespace].routes[path].categories) {
+                    defaultCategory = namespaces[namespace].routes[path].categories[0];
+                    break;
+                }
             }
         }
-    }
-    if (!defaultCategory) {
-        defaultCategory = 'other';
-    }
-    for (const path in namespaces[namespace].routes) {
-        const realPath = `/${namespace}${path}`;
-        const data = namespaces[namespace].routes[path];
-        const categories = data.categories || namespaces[namespace].categories || [defaultCategory];
-        // maintainers
-        if (data.maintainers) {
-            maintainers[realPath] = data.maintainers;
+        if (!defaultCategory) {
+            defaultCategory = 'other';
         }
-        // radar
-        if (data.radar?.length) {
-            for (const radarItem of data.radar) {
-                const parsedDomain = parse(new URL('https://' + radarItem.source[0]).hostname);
-                const subdomain = parsedDomain.subdomain || '.';
-                const domain = parsedDomain.domain;
-                if (domain) {
-                    if (!radar[domain]) {
-                        radar[domain] = {
-                            _name: namespaces[namespace].name,
-                        };
-                    }
-                    if (!radar[domain][subdomain]) {
-                        radar[domain][subdomain] = [];
+        for (const path in namespaces[namespace].routes) {
+            const realPath = `/${namespace}${path}`;
+            const data = namespaces[namespace].routes[path];
+            const categories = data.categories || namespaces[namespace].categories || [defaultCategory];
+            // maintainers
+            if (data.maintainers) {
+                maintainers[realPath] = data.maintainers;
+            }
+            // radar
+            if (data.radar?.length) {
+                for (const radarItem of data.radar) {
+                    const parsedDomain = parse(new URL('https://' + radarItem.source[0]).hostname);
+                    const subdomain = parsedDomain.subdomain || '.';
+                    const domain = parsedDomain.domain;
+                    if (domain) {
+                        if (!radar[domain]) {
+                            radar[domain] = {
+                                _name: namespaces[namespace].name,
+                            };
+                        }
+                        if (!radar[domain][subdomain]) {
+                            radar[domain][subdomain] = [];
+                        }
+                        radar[domain][subdomain].push({
+                            title: radarItem.title || data.name,
+                            docs: `https://docs.rsshub.app/routes/${categories[0]}`,
+                            source: radarItem.source.map((source) => {
+                                const sourceURL = new URL('https://' + source);
+                                return sourceURL.pathname + sourceURL.search + sourceURL.hash;
+                            }),
+                            target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath,
+                        });
                     }
-                    radar[domain][subdomain].push({
-                        title: radarItem.title || data.name,
-                        docs: `https://docs.rsshub.app/routes/${categories[0]}`,
-                        source: radarItem.source.map((source) => {
-                            const sourceURL = new URL('https://' + source);
-                            return sourceURL.pathname + sourceURL.search + sourceURL.hash;
-                        }),
-                        target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath,
-                    });
                 }
             }
         }
     }
+
+    // Use process.cwd() to get the absolute path to the project root
+    const projectRoot = process.cwd();
+    const buildDir = path.join(projectRoot, 'assets', 'build');
+
+    // Ensure the build directory exists
+    await ensureDirectoryExists(buildDir);
+
+    // Write files using absolute paths
+    await writeJsonFile(path.join(buildDir, 'radar-rules.json'), radar);
+    await fs.writeFile(path.join(buildDir, 'radar-rules.js'), `(${toSource(radar)})`);
+    await writeJsonFile(path.join(buildDir, 'maintainers.json'), maintainers);
+    await writeJsonFile(path.join(buildDir, 'routes.json'), namespaces);
 }
 
-fs.writeFileSync(path.join(__dirname, '../../assets/build/radar-rules.json'), JSON.stringify(radar, null, 2));
-fs.writeFileSync(path.join(__dirname, '../../assets/build/radar-rules.js'), `(${toSource(radar)})`);
-fs.writeFileSync(path.join(__dirname, '../../assets/build/maintainers.json'), JSON.stringify(maintainers, null, 2));
-fs.writeFileSync(path.join(__dirname, '../../assets/build/routes.json'), JSON.stringify(namespaces, null, 2));
+main().catch(error => {
+    console.error('An error occurred during the build process:', error);
+    process.exit(1);
+});
\ No newline at end of file

WindowsXp-Beta added a commit to WindowsXp-Beta/RSSHub that referenced this issue Oct 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RSS bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants