ttag-cli icon indicating copy to clipboard operation
ttag-cli copied to clipboard

Svelte preprocess

Open ljani opened this issue 2 years ago • 1 comments

This PR adds support for Svelte's preprocessing functionality, which is required to use ttag-cli with Svelte if the blocks are written in TypeScript.

The PR seems to be functional. However, ~I'm having some problems writing tests for this and~ I'd like to have some guidance on the following points:

  • I had to convert the TransformFn to async, because svelte.preprocess is async-only. I also changed eg. Babel calls to async. Is this desirable or should sync versions be preferred?
  • To load an ESM module in CJS, I need to use dynamic imports. However, because the current setup will transpile any import() calls to require() calls, I need to do some eval hackery to get around this. Is this acceptable or do you have any other suggestions? Should we try to sanitize the (external) input somehow? I don't think I'd like to reconfigure the whole pipeline in this PR. See also https://github.com/microsoft/TypeScript/issues/43329.
  • ~The test setup requires a svelte.config.js in the current working directory, or above it, and I'm not sure how to set it up and thus the test is currently failing (in addition to missing the snapshot). I can make this location configurable, but are there any preferences how should I pass the configuration variable?~ Running from eg. tests/fixtures/testSvelte seems to be okay, updated the PR.
  • ~I'd need to add yet another dependency svelte-preprocess to test preprocessing TypeScript.~ (This affects only devDependencies, so its not a problem, updated the PR.) I think dependencies are going to get out of hand at some point. Maybe vue-sfc-parser and svelte should be dynamically loaded, if available? Thus they could be moved from dependencies to devDependencies at least, if not removed from package.json.

Thanks for @MrOrz for initial work with https://github.com/ttag-org/ttag-cli/pull/94.

Feel free to finish this PR.

ljani avatar Dec 27 '22 13:12 ljani

If anyone needs it, here's a rudimentary Vite (or Rollup) plugin for .po files to be used with Svelte, based on ttag-po-loader:

import parser from "ttag-cli/dist/src/lib/parser";
import utils from "ttag-cli/dist/src/lib/utils";
import { createFilter } from "vite";

const filter = createFilter(/\.po$/);

export function poPlugin() {
    return {
        name: "po-plugin",
        transform(src, id) {
            if (filter(id)) {
                const poData = parser.parse(src);

                const messages = utils.iterateTranslations(poData.translations);
                const header = messages.next().value;
                delete header.comments;
                for (const msg of messages) {
                    delete msg.comments;
                }

                const value = JSON.stringify(poData)
                    .replace(/\u2028/g, "\\u2028")
                    .replace(/\u2029/g, "\\u2029");

                return {
                    code: `export default ${value};`,
                };
            }
        },
    };
}

I guess I could have used ttag-po-loader and just call it, but oh well.

ljani avatar Dec 29 '22 18:12 ljani