Vue.js and Nuxt.js - javascript

Holla, first of all thanks to those who are answering to this question. this question might be silly to ask.
i am switching my spa from vue.js to nuxt provided by vue.js but write now i am in trobule beacuse of 0% visiblity between how whole nuxt works.
Question:
how to register global component.
how to switch layouts in nuxt on certain user of client-side behaviour.
where to write vue.use(someplugin).
how to write middle ware export of method which connects to server with user ip deatils than load page.
how to deal with enviornment variables in vue.js
how to transfer data from any middle ware and plugin to components which i am using.
is there any way to seperate vue component and there respective methods and data.
CURRENT PROBLEM DUE TO WHICH I HAVE NO WAY TO PROCEED ON MY PROJECT
Registering modules using vue.use(plugins) in ~plugins/registerPlugin.js ex:
'use strict';
/*
MODULE IMPORTS
*/
// npm modules.
import Vue from 'vue';
// temp modules. ex modules for registration.
import __vueCookie from 'vue-cookies'; // npm: provide cookie set and get.
import __veeValidate from 'vee-validate'; // npm: provide field validation.
import __moment from "vue-moment"; // npm: filter plugin for vue.js.
import __vueLocalStorage from 'vue-localstorage'; // npm: provide local storage api.
import __vueSessionStorage from 'vue-session'; // npm: module for managing session storage.
import __vueResource from 'vue-resource'; // npm: vue resource library.
/*
PLUGIN REGISTRATION
*/
// use vue resource library.
Vue.use(__vueResource);
// vue validate for input validation.
Vue.use(__veeValidate);
// vue filter plugin for date and time.
Vue.use(__moment);
// cookie plugin manager for vue.
Vue.use(__vueCookie);
// local storeAge manager for vue.
Vue.use(__vueLocalStorage);
// session storage manager for vue.
Vue.use(__vueSessionStorage);

Here my answers for questions 1-5. 6 and 7 are not completely clear to me. Perhaps you would like to rewrite them?
how to register global component.
Make a plugin file in /plugins and then add it in nuxt.config.js
plugins: ['~/plugins/components.js']
Have a look here.
how to switch layouts in nuxt on certain user of client-side
behaviour.
Have a look into this discussion
where to write vue.use(someplugin)
You would add them as a "nuxt" plugin and add them also in nuxt.config.js. Have a look here how to do it.
how to deal with enviornment variables in vue.js
You set them also in nuxt.config.js. See here.

Related

Tree-shakeable strategy pattern in Typescript

I have been trying to build a library that requires its consumers to use a specific strategy per target. My current architecture follows:
[Application] -> contains -> [player] -> contains -> [renderer]
Currently, Renderer is an interface which needs to be replaced for different platforms:
Mobile -> uses MobileRenderer
Web -> uses WebRenderer
I have the freedom to use any bundlers - currently using Webpack for the app and Rollup for the lib - and what I could achieve follows:
My lib exports a Player interface and a createPlayer function which returns a PlayerInterface. Then, on the application side I have a Webpack alias that resolves the correct platform library based on a build input.
e.g:
import { createPlayer } from "my-lib";
const player = createPlayer()
Then we build the application with
npm run build --platform=web
to which webpack will transform the my-lib import into my-lib/platforms/web, which also contains an exported createPlayer function which uses the correct renderer.
My question is the, from the application's point of view, how can we make sure that we import the correct renderer per platform on build time while allowing tree-shaking (so only including the correct sources)? I find that using the build system to do that is quite obscure, as it doesn't leave a clear trace of what's going on.
Is there a better way of doing this?
Best,
You have a couple options. I'd recommend against having a compile-time switch, since that requires you to distribute multiple copies of your library (which isn't idiomatic). However, if you really wanted to do this, I'd suggest using webpack's ProvidePlugin or resolve.alias config field to dynamically link your code to the appropriate renderer at build time.
A more pragmatic approach, in my opinion, would be to have two entry points to your application, and allow the implementor to choose which entry point to use. This is similar to how react-dom switches between browser rendering and server rendering (i.e., react-dom versus react-dom/server):
// index.js
export * from './shared';
export {default as renderer} from './renderers/web';
// mobile/index.js
export * from '../shared';
export {default as renderer} from '../renderers/mobile';
Then, someone using your library could import {renderer, foo} from 'your-lib' or import {renderer, foo} from 'your-lib/mobile'.
Both of the above approaches work at build time.
While the latter approach normally forces you to choose which version of the library to use in your code, you can use webpack's resolve.alias configuration field to force imports to your-lib be redirected to your-lib/mobile.

Export vuejs components to reuse

I created an api. And for him, I created a one-page interface using vuecli. My plans are to embed it in the projects I need. The question is what needs to be done to export the written application and reuse it where necessary?
The structure of the project is shown in the screenshot.
src/main.js - connect and configure axios
src/App.vue - I describe the main component of the application
(maybe I need to put it in a separate component in the components
folder)
src/components/OneDay.vue is the second component that is mainly
called src/App.vue several times.
src/mixins/dateHandler.js - several functions common to the two
components, which are connected as mixins.
I have not modified any other files. How can I prepare this correctly so that I can connect these components to my other applications using composer? I connect, configure some variables (api address, for example) and display it in the right place on the page - this is how I see it.
You can try to create a web component using VUE CLI 3 to use it later in a different code base. Just make sure your main.js file looks like this
import Vue from 'vue';
import wrap from '#vue/web-component-wrapper';
import VueWebComponent from './components/VueWebComponent';
const CustomElement = wrap(Vue, VueWebComponent);
window.customElements.define('my-custom-element', CustomElement);
and build it using vue-cli-service build with --target wc
You can read more precise instructions there:
https://github.com/vuejs/vue-web-component-wrapper
https://vuejsdevelopers.com/2018/05/21/vue-js-web-component/

import jquery webpack react Gatsby

I am using Gatsby and importing jquery.
When I run Gatsby build I get the following error:
WebpackError: jQuery requires a window with a document.
This is due to Gatsby doing server side rendering.
I have read through a number of issues on GitHub (this one being the best one I could find).
My code looks like the following:
import React, { Component } from 'react'
import Link from 'gatsby-link'
import LandingScreen from '../components/LandingScreen'
import $ from 'jquery'
import 'fullpage.js/dist/jquery.fullPage.js'
import 'fullpage.js/dist/jquery.fullpage.css'
class TestPage extends Component {
componentDidMount() {
$('#fullpage').fullpage({
verticalCentered: false
});
}
render(){
return (
<main id="fullpage">
<LandingScreen />
</main>
)
}
}
export default TestPage
This is breaking so I tried the following based on the GitHub thread above, but this also fails:
if (typeof window !== 'undefined') {
import $ from 'jquery'
}
Can anyone advise how to import jquery?
Gatsby's components will run on both Node (no window object there) in order to produce static HTML and on the client's browser as React components. This is why you get this error.
The plugin you are trying to use needs to run only on the client because it needs the actual viewport dimensions to operate. Gatsby has a special API for this that you can use to run the plugin only on client side. A quick solution would be to load jQuery there and initialize your plugin on onClientEntry.
I would also suggest you find a more lightweight plugin that does the same thing without the jQuery dependency. It's a pity to use jQuery in a React stack. Maybe somebody else can recommend one.
Peter, I recently reported this to jQuery maintainers, but they politely told me... well... to kick rocks. Would be good, if you could badger them about this a bit, too.
Currently jquery absolutely requires window object, so it won't work on Node.js as a dependency. (with one exception: if you don't need a global jquery object, but just a local instance in one module, you can manually initialise it with JSDom, but that's probably not your use case)
Your way around this whole problem is that you don't actually have to import jQuery or its plugins on server side. So my approach was to create 2 separate entry point files - app.jsx and server.jsx - for client bundle and server-side bundle respectively and Layout.jsx as a shared root component.
app.jsx and server.jsx are entry points for client-side bundle and server-side bundle respectively, while Layout.jsx contains shared code with html.
I import jquery only in app.jsx bundle, so on client side it is present. On server side it is never imported and not included in server bundle.
You can take a look at my blog's code, how I set up Webpack in it and how do server rendering.

How to asynchronously import components in VueJS by full URL

I need to import a Vue component asynchronously by the full URL opposed to relative URL. The following example taken from the VueJS documentation works just fine for components within the same project
Vue.component(
'app-component-one',
() => import('./component-from-app-one')
)
However, my goal is to import components from a separate project that's deployed on the same server. I was hoping I could use the full URL and do something like...
Vue.component(
'app-component-two',
() => import ('http://sample-domain.com/project-2/components/component-from-app-two.vue')
)
but it results in and error:
This dependency was not found:
* http://sample-domain.com/app-2/components/component-from-app-two.vue in ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./src/components/SampleComponent.vue
Is importing components by full URL possible? Thanks in advance!
The example you referenced from the Vue website is leveraging the code-splitting functionality from WebPack, so it will NOT work to load files that are not part of the same project.
What you are trying to do is typically called "dynamic/asynchronous ES6 module loading". Not to get too deep in to it.. but the current import blah from X only support static imports. If you care more about the nitty-gritty details of this.. there is a TC39 proposal for dynamic imports in JS
In the mean time... us mortals have to depend on tools like SystemJS which will do exactly what you are asking for.
But like #divine mentioned... you need some type of build-process that generates the stand-alone Vue component. You can use either WebPack or RollUp to export it as a UMD and the use SystemJS to import that component by referencing the full URL (you could even import it from a different domain! assuming that domain supports CORS)

Attempting to load a JavaScript sdk into an Angular2 application. Can't find all dependencies

I'm attempting to make use of this library: https://github.com/MagicTheGathering/mtg-sdk-javascript in an Angular2 application.
Unfortunately, I've been going in circles trying to load it into my application.
Firstly, on the TypeScript side if I import it using:
import { } from 'mtgsdk';
there are no types to load into the {}.
If I attempt to load it using something similar to:
import * as mtg from 'mtgsdk'
I'm unable to because it says that it's unable to find a module named mtgsdk.
I've installed the module using
npm install --save mtgsdk
Also, npm installs work fine for other modules.
The application compiles fine if I load it in using require via something similar to this:
var mtg = require('mtgsdk');
Taking that approach, I'm able to compile and launch but in the browser I get a number of errors about modules that it can't find. I figure they are prerequisites for the sdk that didn't get loaded so I start bringing them in via package.json.
For every one that I bring in, I then have to go to systemjs.config.js and add an entry pointing to the module's entry point and often have to specify a default extension using blocks like this:
pointer
'mtgsdk': 'npm:mtgsdk/lib/index.js',
'request-promise': 'npm:request-promise/lib/rp.js',
'ramda': 'npm:ramda/dist/ramda.js',
'emitter20': 'npm:emitter20/index.js',
'bluebird': 'npm:bluebird/js/browser/bluebird.js',
'request': 'npm:request/index.js'
default extension
'request-promise':
{
defaultExtension: 'js'
}
I'm not sure if that's the right approach though because the more dependencies I add, the more that I end up requiring. At one point I had literally gotten up to 50 extra dependencies added because every time I launched, the browser console would find more that were needed.
Is there any easier way to load all of these in?
Also, some of them (such as tough-cookie and request-promise-core) were very problematic to load and I couldn't get the browser console to stop complaining about them. Finally, some of them seemed very basic such as url, http, https. Those seem like they should already be present.
Using systemjs was utilized in the previous versions of Angular 2, However Angular 2 has evolved to Angular 4, with super new features like Angular CLI.
I recommend your use Angular CLI, with #angular/cli.
Importing Node modules
Since mtgsdk is a node-module, you can easily import it using
import * as mtg from 'mtgsdk'
However for your program to compile, you must install a type definition for it. or declare one for it in /typings.json or your app might not build.
Importing Client Scripts
For client scripts like firebase.js you won't need to add client scripts as entries in systemjs.config.js again.
Using #angular/cli, you would easily add them in the scripts[] array in your angular-cli.json for automatic compilation.
Then access them like this
declare const firebase: any;
Here is a quickstart tutorial to set up Angular with #angular/cli.

Categories

Resources