lingui / js-lingui

🌍 📖 A readable, automated, and optimized (3 kb) internationalization for JavaScript
https://lingui.dev
MIT License
4.31k stars 368 forks source link

Astro integration #1640

Open dimonnwc3 opened 1 year ago

dimonnwc3 commented 1 year ago

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

thekip commented 1 year ago

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

TheUltDev commented 1 year ago

@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 commented 1 year ago

@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;
thekip commented 1 year ago

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 commented 1 year ago

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 commented 2 months ago

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;