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

Astro integration #1640

Open
dimonnwc3 opened this issue May 6, 2023 · 9 comments
Open

Astro integration #1640

dimonnwc3 opened this issue May 6, 2023 · 9 comments

Comments

@dimonnwc3
Copy link

is it possible to use this amazing library with https://astro.build?

@timofei-iatsenko
Copy link
Collaborator

I don't have experience with astro. You could try and report it back to community 😃

@TheUltDev
Copy link

TheUltDev commented May 12, 2023

@dimonnwc3 Astro builds on top of Vite, you should be able to follow the same Vite integration process:

Just follow the Lingui Vite integration and the core/macro (and possibly react) libraries should work?

@dimonnwc3
Copy link
Author

dimonnwc3 commented May 13, 2023

@TheUltDev thanks for suggestion. I was able to install and setup lingui with vite, but macros are not getting extracted.
It seems that extractor expects js/jsx/ts/tsx files, but astro is using .astro extension. Which is a mix of a JS and JSX inside one file.

Running of astro itself, with a Trans macro inside, throws an error:

 error   Named export 'createMacro' not found. The requested module 'babel-plugin-macros' is a CommonJS module, which may not support all module.exports as named exports.
  CommonJS modules can always be imported via the default export, for example using:

  import pkg from 'babel-plugin-macros';
  const { createMacro } = pkg;

@timofei-iatsenko
Copy link
Collaborator

but astro is using .astro extension

You need to implement a custom extractor for such files. You can take vue-extractor as example https://github.com/lingui/js-lingui/blob/main/packages/extractor-vue/src/vue-extractor.ts

@ws-rush
Copy link

ws-rush commented Jun 15, 2023

I think astro a huge problem, astro support React, vue, solid, and another frameworks components, I think it is intersting to write one astro extractor if it is possible

@liolocs
Copy link

liolocs commented Apr 10, 2024

I wrote a custom extractor for astro, not sure if this will work for whoever tests this but maybe a good starting point:

//astro-extractor.ts
import { transform } from "@astrojs/compiler";
import { extractor as defaultExtractor } from "@lingui/cli/api";

export const astroExtractor = {
    match(filename: string) {
        return filename.endsWith(".astro");
    },
    async extract(
        filename: string,
        code: string,
        onMessageExtracted: any,
        ctx: any
    ) {
        // transform to plain JS + Sourcemaps
        const { code: transformedCode, map } = await transform(code, {
            filename,
            sourcemap: "both",
            internalURL: "astro/runtime/server/index.js",
        });
        // reuse extractor from cli
        return defaultExtractor.extract(
            filename + ".ts",
            transformedCode,
            onMessageExtracted,
            { map, ...ctx }
        );
    },
};
//lingui.config.ts
import type { LinguiConfig } from "@lingui/conf";
import { astroExtractor } from "./astro-extractor";

const config: LinguiConfig = {
    locales: ["en", "es", "fr"],
    catalogs: [
        {
            path: "./src/locales/{locale}/messages",
            include: ["src"],
        },
    ],
    format: "po",
    compileNamespace: "es",
    extractors: [astroExtractor],
};

export default config;

@voidpumpkin
Copy link

@liolocs Thx a lot for the starting point.

I got simple extraction working by replacing transform with convertToTSX:

//astro-extractor.ts
import { convertToTSX } from "@astrojs/compiler";
import { extractor as defaultExtractor } from "@lingui/cli/api";

export const astroExtractor = {
  match(filename: string) {
    return filename.endsWith(".astro");
  },
  async extract(
    filename: string,
    code: string,
    onMessageExtracted: any,
    ctx: any,
  ) {
    let { code: transformedCode, map } = await convertToTSX(code);

    return defaultExtractor.extract(
      filename + ".tsx",
      transformedCode,
      onMessageExtracted,
      { map, ...ctx },
    );
  },
};

I have not tested a lot though.

@andrii-bodnar
Copy link
Contributor

@liolocs @voidpumpkin Thanks for your interest and effort in making the custom extractor! 🚀

I think this should be a native feature of Lingui. Would you be interested in contributing a separate package similar to extractor-vue?

It would also be great to have a documentation tutorial and example project.

@smnbbrv
Copy link

smnbbrv commented Oct 7, 2024

The extractor itself is a very small issue. Astro is an ecosystem where one can use Astro itself (where the currently provided macros just do not work), React (which actually requires writing custom integration and injecting the babel plugin in) and any other framework of choice. Currently one can use lingui only with react components which is just not enough. Astro is there because more than 50% of the websites can be statically rendered as astro components and not having lingui there makes it problematic. I spent several hours finding a reliable solution for this but I failed.

If one wants to fully support Astro (at least a combination of Astro + React), the primary goal is to actually support Astro components.

To enable the whole Lingui ecosystem one needs

  • support for astro components
  • integration with support for react
  • reliable way to load translations in the runtime (because react will need them to hydrate)
  • extractor
  • linter

That's what would make it really lingui-way of doing things

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants