xiCO2k / laravel-vue-i18n

Allows to connect your `Laravel` Framework translation files with `Vue`.
MIT License
598 stars 49 forks source link

TypeError: langs[(("../../lang/" + (intermediate value)) + ".json")] is not a function #55

Closed EdgedSheet closed 2 years ago

EdgedSheet commented 2 years ago

Hi,

I've tried installing this package and followed the documentation for Vite, but I'm getting the following error in the console.

Uncaught (in promise) TypeError: langs[(("../../lang/" + (intermediate value)) + ".json")] is not a function

I am getting this on a fresh installation of Laravel Jetstream and the installation of this package

laravel new example --jet 
npm i laravel-vue-i18n

vite.config.js

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";
import i18n from "laravel-vue-i18n/vite";

export default defineConfig({
    plugins: [
        laravel({
            input: "resources/js/app.js",
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        i18n(),
    ],
});

app.json

import "./bootstrap";
import "../css/app.css";

import { createApp, h } from "vue";
import { createInertiaApp } from "@inertiajs/inertia-vue3";
import { InertiaProgress } from "@inertiajs/progress";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m";
import { i18nVue } from "laravel-vue-i18n";

const appName =
    window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) =>
        resolvePageComponent(
            `./Pages/${name}.vue`,
            import.meta.glob("./Pages/**/*.vue")
        ),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(i18nVue, {
                resolve: async (lang) => {
                    const langs = import.meta.glob("../../lang/*.json");
                    return await langs[`../../lang/${lang}.json`]();
                },
            })
            .use(plugin)
            .use(ZiggyVue, Ziggy)
            .mount(el);
    },
});

InertiaProgress.init({ color: "#4B5563" });

Am I stupid and am I forgetting something or is something not working properly ?

xiCO2k commented 2 years ago

Hey @EdgedSheet just created this repo with a vite example, I basically followed all your steps and everything works, check here: https://github.com/xiCO2k/laravel-vue-i18n-vite-app

EdgedSheet commented 2 years ago

Hey @EdgedSheet just created this repo with a vite example, I basically followed all your steps and everything works, check here: https://github.com/xiCO2k/laravel-vue-i18n-vite-app

Exact clone of that repo still gives me it.

Capture

xiCO2k commented 2 years ago

When running vite or vite build?

EdgedSheet commented 2 years ago

When running vite or vite build?

Both

xiCO2k commented 2 years ago

Just tried again and no issue at all, can you check what node version are you running?

EdgedSheet commented 2 years ago

Node version: 18.7.0

I just found why it's throwing that error.

This package is generating language files with the php_ prefix. So on dev you have php_en.json and on build you'll have php_en.4f0daea0.js for example.

However the lang parameter in de resolve seems to return both en and php_en. So it's looking for both the files php_en.json and en.json during the import of which one will be undefined. So it can't call the function.

Seems like a simple fix is using a check to see if it contains 'php_'.

E.g:

.use(i18nVue, {
    resolve: async (lang) => {
        const langs = import.meta.glob("../../lang/*.json");
        if (lang.includes("php_")) {
            return await langs[`../../lang/${lang}.json`]();
        }
    },
})

Not sure why it does that for me.

vildanbina commented 2 years ago

+1

xiCO2k commented 2 years ago

Hey @vildanbina I could not find a way to replicate this one, but will leave this open.

If you can provide any info, that would be awesome.

Thanks

vildanbina commented 2 years ago

I resolved that issue when I used Server Side Rendering. It didn't work in other ways.

So, to help others:

In my app.js file I have:

app.use(i18nVue, {
    lang: 'en',
    resolve: lang => {
        const langs = import.meta.globEager('../../lang/*.json');
        return langs[`../../lang/${lang}.json`].default;
    },
});

While in my vite.config.js I have:

export default defineConfig({
    plugins: [
        // ...
        i18n(),
    ],
});

In this way works fine.

EdgedSheet commented 2 years ago

I resolved that issue when I used Server Side Rendering. It didn't work in other ways.

So, to help others:

In my app.js file I have:

app.use(i18nVue, {
    lang: 'en',
    resolve: lang => {
        const langs = import.meta.globEager('../../lang/*.json');
        return langs[`../../lang/${lang}.json`].default;
    },
});

While in my vite.config.js I have:

export default defineConfig({
    plugins: [
        // ...
        i18n(),
    ],
});

In this way works fine.

I don’t use this package anymore for my current project as I have dynamic blog items in my database with languages and I’m pretty sure this doesn’t support retrieving those.

But I tested this for another project where I’m using it, and it does seem to fix it.

xiCO2k commented 2 years ago

Thanks guys!

squid-ui commented 1 year ago
if (lang.includes("php_")) {

It worked for me!