yassinedoghri / astro-i18next

An astro integration of i18next + some utility components to help you translate your astro websites!
https://astro-i18next.yassinedoghri.com
MIT License
498 stars 36 forks source link

Add support for Vercel Edge functions #85

Open beeb opened 1 year ago

beeb commented 1 year ago

Note: I know there is an issue specifically for Netlify Edge workers but I get a different error with Vercel, see below.

I'm trying to deploy a simple test project to Vercel using Edge functions and the official Astro adapter.

// astro.config.mjs
import { defineConfig } from 'astro/config'

import astroI18next from 'astro-i18next'
import vercel from '@astrojs/vercel/edge'

export default defineConfig({
    integrations: [astroI18next()],
    output: 'server',
    adapter: vercel()
})

package.json

{
    "dependencies": {
        "@astrojs/vercel": "^2.3.5",
        "astro": "^1.6.13",
        "astro-i18next": "1.0.0-beta.14",
        "i18next": "^22.0.8",
        "i18next-fs-backend": "^2.0.1"
    }
}

When deploying (or building locally), I get the following error:

05:34:45 PM [build] Building server entrypoints...
18:34:46.364 | [commonjs--resolver] Cannot bundle Node.js built-in "module" imported from "node_modules/.pnpm/astro-i18next@1.0.0-beta.14_astro@1.6.13/node_modules/astro-i18next/dist/index.js". Consider disabling ssr.noExternal or remove the built-in dependency.
18:34:46.791 | error   Cannot bundle Node.js built-in "module" imported from "node_modules/.pnpm/astro-i18next@1.0.0-beta.14_astro@1.6.13/node_modules/astro-i18next/dist/index.js". Consider disabling ssr.noExternal or remove the built-in dependency.
18:34:46.792 | Error: Cannot bundle Node.js built-in "module" imported from "node_modules/.pnpm/astro-i18next@1.0.0-beta.14_astro@1.6.13/node_modules/astro-i18next/dist/index.js". Consider disabling ssr.noExternal or remove the built-in dependency.
18:34:46.792 | at error (file:///vercel/path0/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/es/shared/rollup.js:1858:30)
18:34:46.792 | at throwPluginError (file:///vercel/path0/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/es/shared/rollup.js:21587:12)
18:34:46.792 | at Object.error (file:///vercel/path0/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/es/shared/rollup.js:22541:20)
18:34:46.792 | at Object.resolveId (file:///vercel/path0/node_modules/.pnpm/vite@3.2.5/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:33615:34)
18:34:46.793 | at Object.handler (file:///vercel/path0/node_modules/.pnpm/vite@3.2.5/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:45912:19)
18:34:46.793 | at file:///vercel/path0/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/es/shared/rollup.js:22748:40

It would be great to be able to do SSR with Vercel! Thanks for this project

fprl commented 1 year ago

Hi @beeb,

This is because edge functions don't have access to any node APIs, this is the same for Vercel Edge, Deno and Cloudflare workers (they are adding support for some packages here).

I was going to ask @yassinedoghri what does he think about creating a PR to handle this. I have been testing a solution, and I think a good way of handling this would be to re-introduce the resources option in configs. If this is set, then the i18next-fs-backend package — which is the one importing and using all the node APIs — won't be imported.

The only thing is that you would need to manually import all the translation files (if you are using namespaces). Is there any workaround for this last thing? Maybe a pre-build script that builds the resources object from all the translations files on the locales directory.

I think if this is solved, it can solve all the current issues with different environments (vercel edge, netlify edge, Deno and cloudflare workers).

PS: I recommend you to downgrade to 1.0.0-beta.12 and import everything you want in resources without using i18next-fs-backend.

beeb commented 1 year ago

Hey @francoromanol thanks for the reply.

I reverted to beta.12 and converted all my files to the older format, and the dev mode works. But when building, I still get the error:

[commonjs--resolver] Cannot bundle Node.js built-in "module" imported from "node_modules/.pnpm/astro-i18next@1.0.0-beta.12_astro@1.6.14/node_modules/astro-i18next/dist/index.js". Consider disabling ssr.noExternal or remove the built-in dependency.

I also get an error in dev mode when using HeadHrefLangs but that is maybe unrelated.

yassinedoghri commented 1 year ago

Hey @francoromanol, first off, a huge thank you for the time you spent investigating this!

Sorry for taking some time to respond, a bit swamped with work lately.

I was going to ask @yassinedoghri what does he think about creating a PR to handle this. I have been testing a solution, and I think a good way of handling this would be to re-introduce the resources option in configs.

The resources option is still present in beta.14, it's an option from the i18next config that you can override using the i18nextServer key:

/** @type {import('astro-i18next').AstroI18nextConfig} */
export default {
  defaultLocale: "en",
  locales: ["en", "fr"],
  i18nextServer: {
    resources: {...}
  }
};

That being said, the i18next-fs-backend plugin is kind of backed in with astro-i18next and I realize it shouldn't as you mentioned it is basically the issue here. Still though, instead of going back to beta.12 (and as another workaround), you can remove it from the installed plugins using the i18nextServerPlugins key:

/** @type {import('astro-i18next').AstroI18nextConfig} */
export default {
  defaultLocale: "en",
  locales: ["en", "fr"],
  i18nextServer: {
    resources: {...}
  }
  i18nextServerPlugins: {
    fsBackend: null
  }
};

The only thing is that you would need to manually import all the translation files (if you are using namespaces). Is there any workaround for this last thing? Maybe a pre-build script that builds the resources object from all the translations files on the locales directory.

Good idea, though maybe there is another way of loading the translation files, say through http just like for client side translations. Using the i18next-http-backend plugin for example.

Ideally, Vercel, Netlify and Cloudflare users should be able to set the same default config and have everything work magically just as SSG.

fprl commented 1 year ago

Hi @yassinedoghri,

Thanks to you for this package and no problem at all!

I tried this solution, and while building the Astro app with Vercel I see two issues:

with vercel/serverless:

as node is possible to use here, we only get the build error mentioned in https://github.com/yassinedoghri/astro-i18next/issues/71#issuecomment-1332170721.

As also mentioned in https://github.com/yassinedoghri/astro-i18next/issues/71#issuecomment-1336499036, if astro-i18next is not initialized at runtime, the build command works.

with vercel/edge:

if I applied the solution you mention:

i18nextServerPlugins: {
    fsBackend: null,
  },

I'm still getting the Cannot bundle Node.js built-in "module" ... error.

I commented this line of the package, build it again, and the Astro build command works:

// src/index.ts
100        // initializing runtime astro-i18next config
101          serverImports += `import {initAstroI18next} from "astro-i18next";`;

So right now neither serverless nor edge is working, I just tried changing the package locally.

eschbach-dd commented 1 year ago

Is there any update?