Vue 3 + vue-i18n-next: what am I doing wrong? - javascript

I've started a Vue 3 project (currently not much more than a boilerplate with TypeScript) and tried to add i18n to it.
As far as I've got, vue-i18n does not work properly with Vue 3; but vue-i18n-next should.
here is my main.ts
import { createApp } from "vue";
import "./registerServiceWorker";
import router from "./router";
import store from "./store";
import { createI18n } from 'vue-i18n'
import App from "./App.vue";
//import en from "./locale/en.json"
//import ru from "./locale/ru.json"
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ru: {
message: {
hello: 'Таки здравствуйте'
}
}
}
const i18n = createI18n({
locale: 'ru',
/* messages: {
en,
ru
},*/
messages,
fallbackLocale: 'en'
})
const app = createApp(App)
.use(store)
.use(router)
.use(i18n);
.mount("#app");
here is my App.vue
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<div>{{ $t("message.hello") }}</div>
<router-view />
</template>
However, I get a warning
[intlify] The message format compilation is not supported in this build. Because message compiler isn't included. You need to pre-compilation all message format. So translate function return 'message.hello'.
Indeed I've found and installed #intlify/message-compiler - but don't have any idea on using it.
my webpack.config.js is taken from examples
const path = require("path");
module.exports = {
rules: [
{
test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
type: "javascript/auto",
loader: "#intlify/vue-i18n-loader",
include: [
// Use `Rule.include` to specify the files of locale messages to be pre-compiled
path.resolve(__dirname, "./src/locale"),
],
},
],
};
my vue.config.js seems to be pretty simple
module.exports = {
chainWebpack: (config) => {
config.plugin("html").tap((args) => {
args[0].template = "./resources/index.html";
return args;
});
},
configureWebpack: {
devServer: {
watchOptions: {
ignored: ["/node_modules/", "/public/", "**/.#*"],
},
},
},
parallel: true,
devServer: {
disableHostCheck: true,
public: process.env.DEV_PUBLIC ?? "mlb.ru",
port: process.env.DEV_PORT ?? 8080,
},
};
and I've even found that my messages has been compiled into bundle.
Maybe anyone has any success with vue-18n-next or maybe some other i18n solution for Vue 3?

The repo & docs have moved:
https://github.com/intlify/vue-i18n-next
I have tried a very similar code and import { createI18n } from 'vue-i18n' should work for you as long as you are in vue-i18n#9.0.0-beta.16
... [code]
import { createI18n } from 'vue-i18n'
const messages = {
es: {
message: {
value: 'Hola Español.',
},
},
en: {
message: {
value: 'Hello English.',
},
},
}
const i18n = createI18n({
locale: 'es',
messages,
})
app
.use(i18n)
.mount('#app')
[code] ...

Like Vue itself, the i18n package comes with various versions. Like Vue, they have a version with and without a runtime compiler. From the docs:
vue-i18n.esm-bundler.js: includes the runtime compiler. Use this if you are using a bundler but still want locale messages compilation (e.g. templates via inline JavaScript strings)
The warning you received is apparently telling you that you need this compiler version. The docs are slightly less clear about this but you need to point the import to the runtime compiler version of the package, like this:
import { createI18n } from "vue-i18n/dist/vue-i18n.esm-bundler.js";

I use i18n in external file (i18n.js) I hope it helps you.
i18n.js
import { createI18n } from 'vue-i18n'
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ru: {
message: {
hello: 'Таки здравствуйте'
}
}
}
const i18n = createI18n({
locale: 'en',
messages
})
export default i18n
main.js
import { createApp } from 'vue'
import App from './App.vue'
import i18n from "#/i18n"
const app = createApp(App)
app.use(i18n)
app.mount('#app')
App.vue
<template>
<span><div>{{ $t("message.hello") }}</div></span>
</template>

Related

Problems with Amplify and Vite

I am getting errors while setting up Amplify Authentication with React and Vite.
This is what I have tried already.
Packages used:
"#aws-amplify/ui-react": 4.2.0
"aws-amplify": 5.0.5
Main.jsx
import Amplify from "aws-amplify"
import awsExports from "./aws-exports"
Amplify.configure(awsExports)
vite.config.js
import { defineConfig } from 'vite'
import postcss from './postcss.config.js'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
define: {
'process.env': process.env,
'global': {}
},
css: {
postcss,
},
plugins: [react()],
resolve: {
alias: [
{
find: /^~.+/,
replacement: (val) => {
return val.replace(/^~/, "");
},
},
{
find: './runtimeConfig', replacement: './runtimeConfig.browser',
}
],
},
build: {
commonjsOptions: {
transformMixedEsModules: true,
}
}
})
Running, npm run dev, app crashes and console has this error:
'Uncaught SyntaxError: The requested module '/node_modules/.vite/aws-amplify.js?v=d4f24853' does not provide an export named 'default' (at main.jsx:5:1)'

How do you get Amplify Authenticator, Vue2 and Vite to work together?

Started a vue2 project from scratch, which is using Vite. I would like to force the user to log in to Cognito via Amplify.
When I run npm run dev I receive the following error:
VITE v3.1.3 ready in 405 ms
➜ Local: http://127.0.0.1:5173/
➜ Network: use --host to expose
✘ [ERROR] Could not read from file: /Users/thename/dev/mwt-notification-backend/example-vue/vue/dist/vue.runtime.esm.js
node_modules/#aws-amplify/ui-vue/dist/index.js:1:496:
1 │ ...ss, createTextVNode, Fragment, renderList, onBeforeMount, useAttrs, withModifiers, h as h$2, onUnmounted } from "vue";
╵ ~~~~~
/Users/reikschatz/dev/mwt-notification-backend/example-vue/node_modules/esbuild/lib/main.js:1566
let error = new Error(`${text}${summary}`);
Not sure why this happens but here are my files:
package.json
"dependencies": {
"#aws-amplify/core": "^4.7.5",
"#aws-amplify/ui-vue": "^2.4.22",
"aws-amplify": "^4.3.36",
"buefy": "^0.9.22",
"vue": "^2.7.10"
},
main.js
import Vue from 'vue';
import Buefy from 'buefy';
import 'buefy/dist/buefy.css';
import App from './App.vue';
import Amplify from '#aws-amplify/core';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
Vue.use(Buefy);
new Vue({
render: (h) => h(App),
}).$mount('#app');
App.vue
<script>
import { Authenticator } from '#aws-amplify/ui-vue';
import '#aws-amplify/ui-vue/styles.css';
export default {
components: { Authenticator },
};
</script>
<template>
<authenticator> ... </authenticator>
</template>
vite.config.js
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import legacy from '#vitejs/plugin-legacy';
import vue2 from '#vitejs/plugin-vue2';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue2(),
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
}),
],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
});
The version of #aws-amplify/ui-vue you're using in your project requires Vue v3 and does not support your version of Vue. To use Vue v2, you'll need to work with the legacy #aws-amplify/ui-components package: https://github.com/aws-amplify/amplify-ui/tree/legacy/legacy/amplify-ui-vue

How to configure Relay.JS in Vite?

I'm trying to migrate my React project from CRA to Vite, this is my vite.config.js:
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
import envCompatible from 'vite-plugin-env-compatible'
import relay from "vite-plugin-relay"
import macrosPlugin from "vite-plugin-babel-macros"
import path from 'path';
import fs from 'fs/promises';
export default defineConfig({
resolve: {
alias: {
'~': path.resolve(__dirname, 'src'),
'#material-ui/core': path.resolve(__dirname, 'node_modules/#material-ui/core')
}
},
esbuild: {
loader: "tsx",
include: /src\/.*\.[tj]sx?$/,
exclude: [],
},
optimizeDeps: {
esbuildOptions: {
plugins: [
{
name: "load-js-files-as-jsx",
setup(build) {
build.onLoad({ filter: /src\/.*\.js$/ }, async (args) => ({
loader: "tsx",
contents: await fs.readFile(args.path, "utf8"),
}));
},
},
],
},
},
define: {
global: {},
},
plugins: [
envCompatible(),
react(),
relay,
//macrosPlugin(),
],
})
My GraphQL query files are like this:
import graphql from 'babel-plugin-relay/macro'
const getQuery = () => graphql`
query UserQuery($id: ID!) {
user(id: $id) {
id
fullName
}
}
`
export default getQuery
When I tried to run the project in dev mode (command $ vite), I got this error:
So I did some search and replaced vite-plugin-relay to vite-plugin-babel-macros like this:
// others import
import relay from "vite-plugin-relay"
import macrosPlugin from "vite-plugin-babel-macros"
export default defineConfig({
// configs like bellow
plugins: [
envCompatible(),
react(),
//relay,
macrosPlugin(),
],
})
So I started to get a new error:
How can I configure Relay to work on Vite.JS?
Might be a bit late, but the issue has been fixed in Relay#13 and you can find some workarounds in this thread for older versions of Relay :
https://github.com/facebook/relay/issues/3354
You can also try adding the option eagerEsModules: true to your relay babel plugin configuration.
Unless you have some specific usecase that requires the use of babel-plugin-relay, your issue should be resolved if you change your imports from
import graphql from 'babel-plugin-relay/macro'
to
import { graphql } from "react-relay";
You should only need the relay vite plugin at that point, and can remove vite-plugin-babel-macros
There's a few things wrong with your setup.
1. Don't use vite-plugin-babel-macros:
Use #vitejs/plugin-react instead.
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
import relay from "vite-plugin-relay";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [relay, react({
babel: {
plugins: ['babel-plugin-macros']
},
})],
});
You can probably get it to work with vite-plugin-babel-macros, but the later is an official plugin.
2. Don't use 'babel-plugin-relay/macro':
Use the following instead:
import { graphql } from "react-relay";
It's unclear to me why the official docs suggest using babel-plugin-relay/macro, but that just doesn't work.
3. Configure relay.config.js correctly:
{
"src": "./src",
"language": "typescript",
// Change this to the location of your graphql schema
"schema": "./src/graphql/schema.graphql",
"exclude": [
"**/node_modules/**",
"**/__mocks__/**",
"**/__generated__/**"
],
"eagerEsModules": true
}
In particular, make sure you use language: typescript and eagerEsModules.
4. Sample repository
I wrote a sample repository showing how to properly configure React Relay with Vite.js and TypeScript, you can find it here.

vue-router showing blank page when built

I'm asking for help. I use vuejs to make my application. Everything works perfectly. But I do the npm run build, I extract the dist folder and I open index.html, I have a blank page, and when I look in the console, I have no errors.
main.js
import Vue from "vue";
import Vuex from "vuex";
import router from "./router";
import App from "./App.vue";
import vuetify from "./plugins/vuetify";
import store from "./store";
import {
ValidationObserver,
ValidationProvider,
extend,
localize
} from "vee-validate";
import fr from "vee-validate/dist/locale/fr.json";
import * as rules from "vee-validate/dist/rules";
// install rules and localization
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
localize("fr", fr);
// Install components globally
Vue.component("ValidationObserver", ValidationObserver);
Vue.component("ValidationProvider", ValidationProvider);
Vue.config.productionTip = false;
//load vue-moment
Vue.use(require("vue-moment"));
//Load vuex
Vue.use(Vuex);
//Load vueRouter
new Vue({
router,
vuetify,
store,
render: h => h(App)
}).$mount("#app");
router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Professeur from "../components/Professeur";
import Matiere from "../components/Matiere";
import Dashboard from "../components/Dashboard";
import Filiere from "../components/Filiere";
import Salle from "../components/Salle";
import Shedule from "../components/Shedule";
import SheduleLine from "../components/SheduleLine";
import Login from "../components/Login";
import Home from "../components/Home";
Vue.config.productionTip = false;
Vue.use(VueRouter);
const router = new VueRouter({
mode: "history",
routes: [
{
path: "/dashboard",
name: "dashboard",
component: Dashboard,
meta: {
requiresAuth: true
},
children: [
{
path: "personnel/professeurs",
name: "p_professeur",
component: Professeur
},
{
path: "",
name: "home",
component: Home
}
]
},
{
path: "/login",
name: "login",
component: Login,
meta: {
guest: true
}
}
]
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
let user = JSON.parse(localStorage.getItem("_GET_TOKEN"));
if (!user && !user.token) {
next({
name: "login"
});
} else {
next();
}
} else {
next();
}
});
export default router;
App.vue
<template>
<v-app>
<router-view/>
</v-app>
</template>
<script>
export default {
name: 'app',
}
</script>
Once I compile, I have no errors but a blank page.
Thanks for any help. I tried without the router view, I manage to launch the index.html once compiled for production and I have a rendering.
You're using history mode for your router, which means you'll access your pages with paths like /login or /dashboard or /dashboard/personnel/professeurs, which are the only routes you declared.
/ or /index.html does not display anything because the router doesn't know what they are.
However, in order to have history mode working, you cannot just have a static server. The server has to know that a request to /dashboard should return the index.html file.
If you used VueCLI, the docs here might be helpful:
If you are using Vue Router in history mode, a simple static file server will fail. For example, if you used Vue Router with a route for /todos/42, the dev server has been configured to respond to localhost:3000/todos/42 properly, but a simple static server serving a production build will respond with a 404 instead.
To fix that, you will need to configure your production server to fallback to index.html for any requests that do not match a static file. The Vue Router docs provides configuration instructions for common server setups.
If you don't want to deal with this, or don't have a server enabling you to do this, you can switch history to hash mode in your router. Your routes will be accessible at /index.html#/dashboard and so on.
If you are running into this issue (as I was) in 2022 with a serverless vue 3 application and vuex, you can configure the hash-histroy like so
import { createRouter, createWebHashHistory } from 'vue-router'
import { type RouteRecordRaw } from 'vue-router'
import { Admin, Welcome } from '/#/views'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Welcome',
component: Welcome
},
{
path: '/admin',
name: 'Admin',
component: Admin
}
]
const router = createRouter({
history: createWebHashHistory(), // <--- this is important
routes
})
export { router }
See also: docs
router/index.js :
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes
})
export default router
main_folder/vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
publicPath: ''
})
Important: use publicPath: '' and createWebHashHistory
That is all. You can now build. But remember that your links will appear as /index.html#/dashboard.

Babel React transform : Property value expected type of string but got null

I have an application that is working great client side (transpiled and compiled with Webpack/Babel).
I'm trying to render this app server side with Node, but I'm getting this error :
TypeError: C:/[PROJECT_PATH]/src/_base/common/components/general/AComponent.js: Property value expected type of string but got null
at Object.validate (C:\[PROJECT_PATH]\node_modules\babel-types\lib\definitions\index.js:153:13)
at validate (C:\[PROJECT_PATH]\node_modules\babel-types\lib\index.js:269:9)
at Object.builder (C:\[PROJECT_PATH]\node_modules\babel-types\lib\index.js:222:7)
at File.<anonymous> (C:\[PROJECT_PATH]\node_modules\babel-core\lib\transformation\file\index.js:329:56)
at File.addImport (C:\[PROJECT_PATH]\node_modules\babel-core\lib\transformation\file\index.js:336:8)
at C:\[PROJECT_PATH]\node_modules\babel-plugin-react-transform\lib\index.js:257:46
at Array.map (native)
at ReactTransformBuilder.initTransformers (C:\[PROJECT_PATH]\node_modules\babel-plugin-react-transform\lib\index.js:255:40)
at ReactTransformBuilder.build (C:\[PROJECT_PATH]\node_modules\babel-plugin-react-transform\lib\index.js:164:41)
at PluginPass.Program (C:\[PROJECT_PATH]\node_modules\babel-plugin-react-transform\lib\index.js:331:17)
It happens on any component imported.
I know the components themselves work because they do in client mode.
Here is my index.js (same babel config as in client side app) :
require('babel-register')({
presets:["es2015", "stage-0",'react'],
highlightCode: false,
sourceMaps: "both",
env: {
development: {
plugins: [
'transform-decorators-legacy',
["react-transform", {
transforms: [{
imports: ['react'],
locals: ['module']
}]
}]
]
}
}
});
require('./renderer.js');
Here is my renderer.js :
import React, { Component } from 'react'
import Router, {match, RoutingContext } from 'react-router'
// this works :
import AnyActions from 'path/to/actions/AnyActions'
// this don't
import AnyComponent from 'path/to/any/component'
Everything else is commented out !
I tried to import this simple AComponent :
import React, { Component, PropTypes } from 'react'
export default class AComponent extends Component {
render () { return (<p>Hello</p>)}
}
Same error !
I must miss something obvious ... but I don't see it !
Problem was with my Babel's React-Transform incorrect configuration : I was specifiying import and locals without any transform name ...
Removing this part solved my problem.
Here is my new index.js :
require('babel-register')({
presets:["es2015", "stage-0",'react'],
highlightCode: false,
sourceMaps: "both",
env: {
development: {
plugins: [
'transform-decorators-legacy'
]
}
}
});
require('./renderer.js');

Categories

Resources