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

Vue-i18n-loader does not work #58

Closed
adetbekov opened this issue Mar 28, 2018 · 21 comments
Closed

Vue-i18n-loader does not work #58

adetbekov opened this issue Mar 28, 2018 · 21 comments

Comments

@adetbekov
Copy link

adetbekov commented Mar 28, 2018

There is the problem in the main loader. In the documentation of vue-i18n, translations could be defined in the Single page component() by the following configs in the rule's module:

module: {
   rules: [
   {
     test: /\.vue$/,
     loader: 'vue-loader',
     options: {
       loaders: {
         i18n: '@kazupon/vue-i18n-loader'
       }
     }
   },
   // ...
 ]
}

The problem is that we don't use 'vue-loader', we use 'eslint-loader' instead in nuxt project. And adding loaders into the config changes nothing. I tried to define new 'push()' with 'vue-loader', but after that, other loaders works incorrectly. Or maybe Vue-i18n-loader is not adaptive for the SSR, so maybe we need nuxt-i18n-loader. And is there a place to be?

@ghost ghost closed this as completed Mar 28, 2018
@ghost ghost added the cmty:question label Mar 28, 2018
@benoitemile
Copy link

Hi, there was a huge revamp in vue-loader by Evan, here's what I've done to make it work :
in vue sfc :

<i18n lang="i18n>
{ awesome stuff }
</i18n>
config.module.rules.push({
  test: /\.i18n$/,
  loader:  `@kazupon/vue-i18n-loader?${JSON.stringify(
    { includePaths: [path.resolve(__dirname), 'node_modules'] }
  )}`,
});

@adetbekov
Copy link
Author

@benoitemile That is not working for me 😔

config.module.rules.push({
  enforce: "pre",
  test: /\.i18n$/,
  loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
    includePaths: [require("path").resolve(__dirname), "node_modules"]
  })}`
})
<i18n lang="i18n">
{
  "en": {
    "hello": "hello world!"
  },
  "ru": {
    "hello": "Привет мир!"
	},
	"kz": {
    "hello": "Sälem älem!"
  }
}
</i18n>

@benoitemile
Copy link

Can you please make sure that you're running vueLoader 15 https://github.com/vuejs/vue-loader/tree/next please ?

@adetbekov
Copy link
Author

@benoitemile Sorry, vue-loader@next crushes styles(I use sass-loader), so I just installed simple vue-lodaer. Nothing changed.

"dependencies": {
    "@nuxtjs/axios": "^5.1.1",
    "cookieparser": "^0.1.0",
    "element-ui": "^2.3.2",
    "js-cookie": "^2.2.0",
    "nuxt": "^1.4.0",
    "nuxt-i18n": "^2.9.1",
    "vue-loader": "^14.2.2"
  },
  "devDependencies": {
    "@kazupon/vue-i18n-loader": "^0.3.0",
    "autoprefixer": "^8.2.0",
    "babel-eslint": "^8.2.2",
    "eslint": "^4.19.1",
    "eslint-config-prettier": "^2.9.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-prettier": "^2.6.0",
    "eslint-plugin-vue": "^4.4.0",
    "jade": "^1.11.0",
    "jade-loader": "^0.8.0",
    "node-sass": "^4.8.3",
    "nuxt-sass-resources-loader": "^1.2.0",
    "postcss": "^6.0.21",
    "postcss-hexrgba": "^1.0.0",
    "postcss-nested": "^3.0.0",
    "postcss-responsive-type": "^1.0.0",
    "prettier": "^1.11.1",
    "sass-loader": "^6.0.7",
    "sass-resources-loader": "^1.3.3",
    "style-loader": "^0.20.3"
  }

@benoitemile
Copy link

benoitemile commented Apr 1, 2018

hi @adetbekov , here's my package.json atm

"dependencies": {
    "@kazupon/vue-i18n-loader": "^0.3.0",
    "@nuxtjs/axios": "^5.0.0",
    "@nuxtjs/component-cache": "^1.1.1",
    "@nuxtjs/dotenv": "^1.1.0",
    "@nuxtjs/localforage": "^1.0.2",
    "@nuxtjs/proxy": "^1.1.4",
    "@nuxtjs/pwa": "^2.0.5",
    "@nuxtjs/sentry": "^1.0.1",
    "@nuxtjs/toast": "^3.0.0",
    "axios": "^0.18.0",
    "babel-polyfill": "^6.26.0",
    "bootstrap": "^4.0.0",
    "bootstrap-vue": "^2.0.0-rc.2",
    "file-loader": "^1.1.11",
    "fontfaceobserver": "^2.0.13",
    "full-icu": "^1.2.1",
    "intl": "^1.2.5",
    "lazysizes": "^4.0.1",
    "newrelic": "^3.1.0",
    "node-sass": "^4.8.3",
    "nuxt-custom-headers": "^2.0.0",
    "nuxt-edge": "^2.0.0",
    "nuxt-sass-resources-loader": "nuxt-community/nuxt-sass-resources-loader#feat/v2",
    "object-hash": "^1.2.0",
    "sass-loader": "^6.0.7",
    "sass-resources-loader": "^1.3.3",
    "smoothscroll-polyfill": "^0.4.3",
    "svg-sprite-loader": "^3.7.1",
    "url-loader": "^1.0.1",
    "vue-i18n": "^7.6.0",
    "vue-i18n-extensions": "^0.1.0",
    "vue-loader": "^15.0.0-beta.7",
    "vue-slider-component": "^2.5.8",
    "vue-styleguidist": "^1.4.9",
    "webpack-gcs-plugin": "^0.1.1"
  },
  "devDependencies": {
    "babel-eslint": "^8.2.1",
    "babel-jest": "^22.1.0",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "browser-env": "^3.2.4",
    "eslint": "^4.18.2",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-config-prettier": "^2.6.0",
    "eslint-config-standard": "^11.0.0-beta.0",
    "eslint-loader": "^2.0.0",
    "eslint-plugin-html": "^4.0.2",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-json": "^1.2.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-node": "^6.0.1",
    "eslint-plugin-prettier": "^2.5.0",
    "eslint-plugin-promise": "^3.5.0",
    "eslint-plugin-react": "^7.6.0",
    "eslint-plugin-standard": "^3.0.1",
    "eslint-plugin-vue": "^4.2.2",
    "jest": "^22.1.4",
    "jest-junit": "^3.4.1",
    "jest-serializer-vue": "^1.0.0",
    "postcss-html": "^0.15.0",
    "stylelint": "^9.1.2",
    "stylelint-config-recommended-scss": "^3.0.0",
    "stylelint-config-standard": "^18.2.0",
    "stylelint-order": "^0.8.0",
    "stylelint-scss": "^2.2.0",
    "vue-jest": "^2.1.1",
    "vue-test-utils": "^1.0.0-beta.11"
  }

here's a part of my nuxt.config.js

build: {
    extend(config, ctx) {
      config.module.rules.push({
        test: /\.i18n$/,
        loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
          includePaths: [path.resolve(__dirname), 'node_modules']
        })}`
      });
    }
},
plugins: [
    '~/plugins/vue-i18n.js'
],
render: {
    bundleRenderer: {
      directives: {
        t: i18nExtensions.directive
      }
    },
}

here's my vue-i18n.js

import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

export default ({ app, store }) => {
  const currentApp = app;
  currentApp.i18n = new VueI18n({
    locale: store.state.i18n.currentLocale.language,
    fallbackLocale: 'fr',
  });
};

here's a i18n part of a component :

<i18n lang="i18n">
{
  "fr": {
    "in_stock": "En stock"
  },
  "en": {
    "in_stock": "In stock"
  },
  "es": {
    "in_stock": "some traduction"
  },
  "de": {
    "in_stock": "Auf Lager"
  },
  "it": {
    "in_stock": "Disponibile"
  },
  "nl": {
    "in_stock": "Op voorraad"
  },
  "pt": {
    "in_stock": "In stock"
  }
}
</i18n>

and finally the results :
https://i.imgur.com/F066MWU.png
https://i.imgur.com/BYArnvq.png

In the nuxtServerInit, we have some logical to handle marketLanguage from the http request.

Let me know if you're still having issues

@moifort
Copy link

moifort commented Apr 3, 2018

Hello everybody, I have an alternative solution, if you are interested.

Explanation

The problem by adding the webpack configuration like below, is that you overwrite all of vue-loader rules set by Nuxt.

// nuxt.config.js
...
build: {
    extend(config, ctx) {
      config.module.rules.push({
        test: /\.i18n$/,
        loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
          includePaths: [path.resolve(__dirname), 'node_modules']
        })}`
      });
    }
},
...

A simple console.log() on the webpack configuration:

// Find the rules
console.log( config.module.rules.find( el => el.loader === 'vue-loader' ).options.loaders)
// Output
{ 
js: 
   { loader: 'babel-loader',
     options: { babelrc: false, cacheDirectory: true, presets: [Array] } },
  css: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] } ],
  less: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] },
     { options: [Object], loader: 'less-loader' } ],
  scss: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] },
     { options: [Object], loader: 'sass-loader' } ],
  sass: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] },
     { options: [Object], loader: 'sass-loader' } ],
  stylus: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] },
     { options: [Object], loader: 'stylus-loader' } ],
  styl: 
   [ { loader: 'vue-style-loader', options: [Object] },
     { loader: 'css-loader', options: [Object] },
     { options: [Object], loader: 'stylus-loader' } ]
}

Solution

The simplest way it's to add the configuration like below

// nuxt.config.js
...
build: {
    extend(config, ctx) {
      config.module.rules.find( el => el.loader === 'vue-loader' ).options.loaders.i18n = '@kazupon/vue-i18n-loader'
    }
},
...

Full Setup

Install vue-i18n and @kazupon/vue-i18n-loader (in dev).

package.json

"dependencies": {
    "@firebase/app": "^0.1.10",
    "@firebase/database": "^0.2.1",
    "@nuxtjs/axios": "^5.0.0",
    "nuxt": "^1.0.0",
    "vue-i18n": "^7.6.0",
    "vue-moment": "^3.2.0",
    "vuetify": "^0.17.3"
  },
  "devDependencies": {
    "@kazupon/vue-i18n-loader": "^0.3.0",
    "yaml-loader": "^0.4.0",
    "@std/esm": "^0.26.0",
    "cross-env": "^5.0.1",
    "esm": "^3.0.14",
    "firebase-tools": "^3.17.4",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.1"
  }

Create i18n.js plugin.

plugins/i18n.js

import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

export default ({app, store}) => {
    app.i18n = new VueI18n({
        locale: 'ja',
        fallbackLocale: 'ja',
    });
};

Add plugin to Nuxt
nuxt.config.js

   /*
    ** Plugins to load before mounting the App
    */
    plugins: [
        '@/plugins/i18n.js',
    ],

Add <i18n> in component/page/layout template
components/MyComponent

<template>
    <div>{{ $t('hello') }}<div/>
</template>
<i18n>
{
  "en": {
    "hello": "hello world!"
  },
  "ja": {
    "hello": "こんにちは、世界!"
  }
}
</i18n>

You can see a sample on my repository: https://github.com/moifort/play-with-nuxt

ctmxo3hwf0

@adetbekov
Copy link
Author

adetbekov commented Apr 12, 2018

@moifort @benoitemile Sooorry, but it doesn't work for me at all!
Error:
Cannot read property 'indexOf' of undefined

extend(config, { isDev, isClient, isServer }) {
  if (isDev && isClient) {
    config.module.rules.push({
      enforce: "pre",
      test: /\.(js|vue)$/,
      loader: "eslint-loader",
      exclude: /(node_modules)/
    })
  }

  config.module.rules.find(
    el => el.loader === "vue-loader"
  ).options.loaders.i18n =
    "@kazupon/vue-i18n-loader"

  if (isServer) {
    config.externals = [
      nodeExternals({
        whitelist: [
          /es6-promise|\.(?!(?:js|json)$).{1,5}$/i,
          /^vue-awesome/
        ]
      })
    ]
  }
}

image
I tried to include this trick inside (isDev && isClient) condition, but nothing changed. And I need SSR I18N.
Thanks!
Here is my config https://github.com/adetbekov/acs-front/blob/master/nuxt.config.js

@adetbekov
Copy link
Author

@moifort OMG! OMG! It works after updating some npm packages. THANKS!😭

@moifort
Copy link

moifort commented May 13, 2018

👍

@karellm
Copy link

karellm commented Aug 4, 2018

When I add the vue-i18n-loader via the extend() method in the config, the language switcher breaks. Do any one of you manage to get nuxt-i18n to work properly with vue-i18n-loader?

@ghost
Copy link

ghost commented Aug 11, 2018

This question has been resolved by @moifort, see answer.

@chanlito
Copy link

I'm using nuxt-edge after upgrading to 5.1 I'm getting the following error:

TypeError: Cannot set property 'i18n' of undefined at Builder.extendBuild.config (/Users/chanlito/Codes/experimental/x-app/node_modules/nuxt-i18n/src/module.js:105:31)

@paulgv
Copy link
Collaborator

paulgv commented Aug 18, 2018

Hi @chanlito
I won't be able to fix this until next week, in the meantime, I'd recommend you disable vueI18nLoader option in your config.

@karellm
Copy link

karellm commented Aug 18, 2018

@paulgv I don't think this issue is fixed. I followed all the steps and the language switcher breaks as soon as I add the extend() hook. Have you successfully tested this? If so can you please provide your config? Thanks!

@karellm
Copy link

karellm commented Aug 27, 2018

@paulgv can you confirm that the language switcher still works for you with vueI18nLoader: true ?

@paulgv
Copy link
Collaborator

paulgv commented Aug 27, 2018

@karellm I haven't used vue-i18n-loader recently and don't think I've ever tried with a lang switcher actually, the few times I used it was to make some quick prototyping before moving all translations to another file. But there are some issues with this option for sure, I still need to investigate but am lacking time lately...

@tillkruss
Copy link

I'm seeing the same error:

TypeError: Cannot set property 'i18n' of undefined
config.module.rules.find(
    el => el.loader === 'vue-loader'
).options.loaders.i18n = '@kazupon/vue-i18n-loader'

The output of vue-loader is:

{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        transformAssetUrls: {
            video: 'src', source: 'src', object: 'src', embed: 'src'
        },
        productionMode: false
    }
}

@manniL
Copy link
Contributor

manniL commented Sep 23, 2018

Solution for nuxt 2:

config.module.rules.push({
                resourceQuery: /blockType=i18n/,
                loader: '@kazupon/vue-i18n-loader'
            })

@blooddrunk
Copy link

vueI18nLoader: true option doesn't work for me with [email protected] if the i18n tag specifies src json files.
Renaming '*.json' files to any arbitrary extension('*.lang' for example) solves this.

@blooddrunk
Copy link

Set vueI18nLoader to false and explicitly apply loader config suggested by intlify/vue-i18n-loader#16 (comment) works.

@parreirat
Copy link

parreirat commented Dec 11, 2019

@moifort

Thank you so much - struggled with the single file component i18n for couple hours and your rule find + change worked perfectly! <3

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

No branches or pull requests

10 participants