bundle-tools icon indicating copy to clipboard operation
bundle-tools copied to clipboard

Support multiple src

Open fredarchimed opened this issue 6 years ago • 11 comments

Hello,

To localize the application, I need to send the JSON files to a translator. I can't send whole components with template, css and script. The tag works perfectly but I'd like to have multiple sources. I have a 'common.json' with the standard strings and 'myComponent.json' for the specific ones. I tried to add 2 tags i18n unfortunately.

Is there a way to import multiple json files for 1 component? Thanks.

fredarchimed avatar Sep 05 '17 11:09 fredarchimed

I would also be interested if there was a way to achieve this?

arjanski avatar Oct 11 '17 09:10 arjanski

In order to support this function, I need to check the custom-blocks specification of vue-loader.

kazupon avatar Nov 02 '17 00:11 kazupon

I am also interested by this feature. It could also be very flexible to support multiple language files for one component. eg. <i18n src="json!yaml!./[componentName].lang.[locale].yaml"/>

FranckFreiburger avatar Dec 06 '17 08:12 FranckFreiburger

Any idea on when this feature might be implemented, or alternatively what workarounds exist? I have a component that needs to dynamically load the language file based on the currently set lang. Thanks!

ssuess avatar Sep 06 '19 10:09 ssuess

Is there no way to work around this limitation at all? I need to be able to dynamically change the value of src depending on my query vars. Any advice greatly appreciated, thanks!

ssuess avatar Sep 12 '19 09:09 ssuess

@kazupon I guess I will try to implement this myself and submit a pull request, but before I do can you point me to where in the code you think this should be handled or any other advice? Thanks

ssuess avatar Nov 05 '19 12:11 ssuess

@ssuess @fredarchimed Hi Guys, I am starting my first vue project. It is a port of a fair sized Knockout.js project so I know that there are about 2500 strings in the UI and I don't want to load all 2500 strings when the initial page loads. I want to do what both of you seem to want to do as well: when I load an area of my SPA, I want to demand load the strings for that area of the SPA as well.

Did either of you come up with a solution that you might be willing to share? I have been researching for the past couple of days and cant believe that there seem to be no packages / tutorials on how to do this. I would have thought that every reasonable sized SPA would have this as a basic requirement of i18n.

Anyway, any pointers, suggestions or explanations of how you guys solved it would be great.

gregveres avatar Jan 27 '20 00:01 gregveres

@gregveres my current plan (not yet implemented) is to add a plugin to webpack that will let me merge my various files into a single one that I will import using the current process. Not my preferred solution but the least complicated for me at the moment in the absence of changes to this component.

ssuess avatar Jan 27 '20 11:01 ssuess

@ssuess Ok. Not ideal, but I get it given the state of i18n it seems. If I figure out anything else, I will come back and share it.

gregveres avatar Jan 27 '20 13:01 gregveres

Here is something that is working for my use case. I desire a folder structure as follows: --components ----HelloWorldComponent ------HelloWorldComponent.vue ------Locales --------en.json, fr.json, de.json, etc.

i.e. Each component has a subfolder that keeps a collection of language files. The hope was to be able to just drop new language files into the locales folder of each relevant component and have things just work. My HelloWorldComponent.vue file looks like this:

<template src='./HelloWorld.html' />
<script src='./HelloWorld.js' />
<style scoped lang='scss' src='./HelloWorld.scss' />
<i18n folder="./Locales" />

The intention was to create a custom webpack loader that combines all files in the folder specified in the i18n tag and passing that to the vue-i18n-loader. The following is the i18nFolderLoader custom loader code that I've come up with

module.exports = function (source) {
    const loaderUtils = require('loader-utils')
    const params = loaderUtils.parseQuery(this.resourceQuery)

    const folder = getFolderParam(params);
    if (folder) {
        source = combineAllFiles(this.context, folder, source)
    }

    return source || {}
}

function getFolderParam(params) {
    for (var p in params) {
        if (params.hasOwnProperty(p) && p.toLowerCase() === 'folder') {
            return params[p]
        }
    }

    return null
}

function combineAllFiles(context, folder, source) {
    const fs = require('fs')
    const path = require('path')

    var jsonSource = JSON.parse(source || '{}');
    var fullFolder = path.resolve(context, folder)

    fs.readdirSync(fullFolder).forEach(file => {
        var srcFile = path.resolve(fullFolder, file)
        var srcContents = fs.readFileSync(srcFile).toString()
        jsonSource = Object.assign(jsonSource, JSON.parse(srcContents))
    });

    return JSON.stringify(jsonSource)
}

And the vue.config.js file now looks like this:

 module.exports = {
    pluginOptions: {
        i18n: {
            locale: 'en',
            fallbackLocale: 'en',
            localeDir: 'GlobalLocales',
            enableInSFC: true
        }
    },
    chainWebpack: config => {
        config.module
            .rule("i18n")
            .resourceQuery(/blockType=i18n/)
            .type('javascript/auto')
            .use("i18n")
                .loader("@kazupon/vue-i18n-loader")
                .end()
            .use('i18nFolderLoader')
                .loader('./src/loaders/i18nFolderLoader')
                .end()
    }
}

This hasn't been tested extensively. I am new to Vue and Webpack, so it is very probable that I am doing things in nonstandard or possibly dangerous ways. I am all ears if anyone has suggestions on making this solution more robust or safer.

cnickc avatar Feb 12 '20 18:02 cnickc

@cnickc did you finally test your code?

PabloRN avatar Apr 07 '20 08:04 PabloRN

vue-i18n-loader will be deprecated near the future We can use unplugin-vue-i18n Thanks

kazupon avatar Nov 16 '22 01:11 kazupon