I know it is possible to imports component from a bundled webpack file like this
import {componentA, componentB} from '../component.bundle';
Is it possible to achieve this same as a dynamic import, like this.
const url = '${window.location.origin}/assets/default/js/bundle/vue_data.bundle.js';
this.getAxiosInstance().get(url).then(response => {
const {Add, Edit, Filter, View} = () => import(response.data);
});
If yes, please how? Thank you
Yes, using dynamic imports:
To dynamically import a module, the import keyword may be called as a function. When used this way, it returns a promise.
I'm assuming from your url example that your import is in the assets directory of your project (i.e. src > assets) and not actually on an external domain. In that case, you don't need axios. You would do it like this:
const path = 'assets/default/js/bundle/vue_data.bundle.js';
import('#/' + path).then(module => {
const {Add, Edit, Filter, View} = module;
});
You need to hardcode the #/ portion or there will be issues, e.g. if you tried to do import(path) with const path = '#/assets/default/js/bundle/vue_data.bundle.js'
Related
I'm looking for a way to use a component in a dynamic way:
const getDynamicComponent = (componentName) => dynamic(() => import(${componentName}), {
ssr: false,
loading: () => <p>Loading...</p>,
});
const Test = () => {
const router = useRouter();
const { component } = router.query;
const DynamicComponent = getDynamicComponent(component);
return <DynamicComponent />
}
Obiovusly if I specify a folder name there like components/${componentName} it searches ALL components.. and not the one specified in the variable.
I know the documentation states explicitly that template strings are not an option for dynamic imports, but I would like to know how I would be able to import a specific component from node_modules, without importing all node_modules folder 🙂
Only static strings are permitted?
I have a dynamic route file as [componentId].js which should import its component from node_modules based on the route name.. any ideas?
Should I try to configure babel in a specific way to make this work?
Thanks!
PS: I know it was asked here, but those answers are not quite correct as the whole folder is trying to get imported, not just the component specified.
I want to write some complicated guard logics in vue-router in Vue 3 to protect entering some routes according to store and my other provided modules. For example, I want to check if user profile info is present or not:
router.afterEach((to, from) => {
console.log('store: ', useStore());
const puex = usePuex();
puex.isReady().then(() => {
const me = puex.me.compute();
watch(me, (...params) => console.log('router: ', ...params));
});
});
In the above code, useStore and usePuex both try to inject store and puex instances from Vue app which are provided while being used in main.js bootstrap. But both use functions return undefined and I guess that the inject in this scope searches a different place where app-level provided instances do not exist.
So how can I inject them in the router file, or in other words how can I get store and puex instance using useStore and usePuex here?
I have found a way according this question but I still don't know if it is the best available solution. I can export the app instance from main.js file and then use app.$store and app.$puex instead. Although it works, I still think about a better solution to inject the store and puex instance using use functions (inject).
You still can add the navigation guards after that your app has mounted in main.js/ts, the code would look like:
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
const vm = createApp(App)
.use(puex)
.use(router)
.mount('#app');
router.afterEach((to, from) => {
const me = vm.puex.me.compute();
watch(me, (...params) => console.log('router: ', ...params));
});
You still can export that vm, to import it in the router file and use it the same way, but I really find somehow confusing, as main.js/ts is already importing the router file.
I have been trying to import a simple function that says "Blah Blah" to my express server.
Unfortunately I am getting the error: SyntaxError: Cannot use import statement outside a module.
I have tried to google this issue the whole day, tried to change the file to .mjs and more, but the server keeps crashing with this error regardless of the methods I found online.
ExpressServer.js :
//start express server
const express = require("express");
const server = express();
const path = require("path");
var bodyParser = require("body-parser");
//Require functions that saves to DB
import {saveToDB} from './saveToDB.js';
// parse application/x-www-form-urlencoded
server.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
server.use(bodyParser.json());
server.listen(5000, () => {
console.log("express server is running..");
});
//Send form details to DB
server.get("/save", (req, res) => {
phone = req.body.number;
name = req.body.name;
saveToDB();
});
saveToDB.js
const saveToDB = () => {
console.log(`Blah blah blah`);
};
export default saveToDB;
The error:
import {saveToDB} from ('./saveToDB.js');
^^^^^^
SyntaxError: Cannot use import statement outside a module
First, check what Node version you are using. If it's 13 or above, ES6 and thus the import statement is supported. Else, you have to update your node version or use the ES5 way (require) instead of import.
Second: If the version is 13 or above, you can either change your file extension to .mjs or add { "type": "module" } to you package.json file.
Third: Always put your import statements at the top of the file. Also, I would probably not mix require with import, but that's personal preference.
Problem was fixed, apparently the problem starts when you try to use import on server side instead of require. If you still wish to use import you can update your node version and edit the type in package.json.
If you choose to go with the first route, you will also have to change all the "Require" in your file to import, otherwise you will get "ReferenceError: require is not defined"
The easier solution would be to change:
import {saveToDB} from './saveToDB.js';
With
const saveToDB = require("./saveToDB.js");
And in the exported module, use the older exporting method:
module.exports = saveToDB;
I need to test if a module works both under Windows and Linux. The module is resolving a path and depending on the OS the path contains a forward slash or backslash. It uses the path.sep to determine which slash to use. In my test case I want to test both OS's. My problem is I cannot figure out how to change the value of path.sep as it is a property and not a function.
Am I missing something? How can I mock the path.sep property? I hope someone can shred some light on this.
Here is a simple working example:
code.js
const path = require('path');
export const func = () => path.sep === '/' ? 'foo' : 'bar';
code.test.js
const path = require('path');
import { func } from './code';
test('func', () => {
path.sep = '/';
expect(func()).toBe('foo'); // Success!
path.sep = '\\';
expect(func()).toBe('bar'); // Success!
});
Looks like it also works if you use
import path from 'path';
...but it doesn't work (at least in my environment) with
import * as path from 'path';
(Since path isn't currently an ES6 module the transpiler has to do some work to make the ES6 import syntax work and import * as path from 'path'; must get transpiled in a way that breaks the approach above.)
I have a question regarding importing an anime.js into my vue project. I am using vue cli. How do I include animejs to my project? I tried it this way:
import anime from 'animejs'
Vue.use(anime);
but I get an error in the console that says:
Uncaught TypeError: a.hasOwnProperty is not a function. . .
can you guys help me?
Vue.use() is used only for plugins designed for Vue.js. You can't simply add a library there, it won't work.
My suggestion is that you create that plugin and use it on your project to make anime.js acessible everywhere.
You could do it like this:
//vue-anime.js
import anime from 'animejs';
const VueAnime = {
install (Vue, options) {
Vue.prototype.$animeJS = anime;
}
}
export default VueAnime
Then later
import VueAnime from './vue-anime';
Vue.use(VueAnime);
Now every Vue component will be able to use anime acessing this.$animeJS.
Or simply -
import Vue from "vue";
import anime from 'animejs/lib/anime.min.js';
Vue.prototype.$anime = anime;
Then this.$anime in all components
#Phiter's answer looked good at first, but I wasn't able to get it to work in my vue-cli 3 environment. The below code worked though, so I think it may work for you. This is just a simple way to install an external library into your Vue app and expose it through a prototype:
// animejs.js
import anime from 'animejs'
const install = (Vue, options) => {
Vue.prototype.$animejs = anime
}
export default install
// Then, in your main.js (at least for me)
import VueAnime from './animejs'
Vue.use(VueAnime)
Now, when you need to access the library, just use this.$animejs in your project.
or simply like this in main.js after npm install:
import anime from 'animejs';
Object.defineProperty(Vue.prototype, '$anime', { value: anime });
then use this.$anime tu use it.
To use AnimeJS globally in Vue 3 project, just create a plugin (plugins/anime.js):
import anime from 'animejs';
export default {
install(app, options) {
app.config.globalProperties.$anime = anime;
},
};
Then include it (main.js or elsewhere):
import VueAnime from './plugins/anime';
createApp(App)
.use(VueAnime)
.mount('#app');
And now, it's accessible everywhere by this.$anime.
Please notice that a minor change from the previous version is installing the plugin for Vue 3.