Including javascript globally using webpack - vue.js

I'm using webpack and Vuejs. I have several components in my application, and I want to use momentjs globally. Everything I've tried so far doesn't seem to work and throws and Undefined error in console. Is there a way to get set moment.js globally available to all components from main.js using webpack?
These are the things I've tried (in main.js):
import moment from 'moment';
Vue.prototype.$moment = moment;
In a component I try to access it via this.$moment but get an undefined error.
I also tried:
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
I also tried to access it via this.$moment, but get the same undefined error on this.$moment.
Am I missing a step or doing something wrong to include a javascript file globally to all components using webpack?
Thanks again for the help!
UPDATES
By the way, momentjs works fine if I import it in every component I want to use it in (as follows, however, this is what I'm trying to avoid):
import moment from 'moment';
...
let today_date = moment().format('YYYY-MM-DD');
UPDATES 2*
This is the exact error (with using this.):
Error in render function: "TypeError: Cannot read property '$moment' of undefined"
This is error (without using this.):
Error in render function: "ReferenceError: $moment is not defined"
Moment is added via dependencies in package.json:
...
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.0",
"css-loader": "^0.28.5",
"es6-promise": "^4.1.1",
"moment": "^2.18.1",
...
Code usage within a component:
...
filters: {
getYear(date) {
return this.$moment(date).format('YYYY');
},
getMonth(date) {
return this.$moment(date).format('MMM');
},
getDay(date) {
return this.$moment(date).format('D');
},
},
...

Related

Vue3 build error: At least one <template> or <script> is required in a single file component

I try to migrate a large existing codebase from Vue2 to Vue3 using Webpack. So I upgraded the necessary packages in package.json to looks like this (no problems here):
"vue": "^3.2.45",
"#vue/compat": "^3.2.45",
"#vue/cli-plugin-babel": "^5.0.8",
"#vue/cli-plugin-eslint": "^5.0.8",
"#vue/cli-plugin-typescript": "^5.0.8",
"#vue/cli-plugin-unit-jest": "^5.0.8",
"#vue/cli-service": "^5.0.8",
"#vue/compiler-sfc": "^3.2.0",
"vue-class-component": "^8.0.0-rc.1",
"vue-loader": "^17.0.1",
...
Now the Webpack build always fails with the error: "At least one template or script is required in a single file component.", no matter which single file component it tries to compile.
So I debugged the source of the error, which is the #vue\compiler-sfc\dist\compiler-sfc.cjs.js), and found out, that the the function parsing the component file gets called twice. First time with the actual code of my component, which works perfectly fine. Then a second time with an already compiled version which looks like this:
import { render } from "./deploymentInfos.vue?vue&type=template&id=1ced640a&ts=true"
import script from "./deploymentInfos.vue?vue&type=script&lang=ts"
export * from "./deploymentInfos.vue?vue&type=script&lang=ts"
import exportComponent from "\\node_modules\\vue-loader\\dist\\exportHelper.js"
const __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__file',"/deploymentInfos/deploymentInfos.vue"]])
/* hot reload */
if (module.hot) {
__exports__.__hmrId = "1ced640a"
const api = __VUE_HMR_RUNTIME__
module.hot.accept()
if (!api.createRecord('1ced640a', __exports__)) {
api.reload('1ced640a', __exports__)
}
...
Of course it fails to parse <script> and <template> from this and throws the error.
I assume I have some kind of misconfiguration but am not able to find it. Does anyone have clue where to look?
Solved ✓
The problem was that another webpack plugin also used the vue-loader. That was where the second call to parse the file came from.
So if you encounter the same error message, try checking your webpack config if there are multiple usages of vue-loader.

Getting: "ESLint: Unable to resolve path to module '#vercel/analytics/react'.(import/no-unresolved)" but package & path inside is actually present

As the title says, ESLint is complaining with this error message:
ESLint: Unable to resolve path to module '#vercel/analytics/react'.(import/no-unresolved)
In the line: import { Analytics } from '#vercel/analytics/react';
When following the instructions from this Vercel quickstart guide, using Next.js.
To sum up, the instructions are:
1- install package via NPM
npm install #vercel/analytics
2- in /pages/_app.tsx file, import it:
import { Analytics } from '#vercel/analytics/react';
function MyApp({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<Analytics />
</>
);
}
export default MyApp;
My packages used:
"next": "^12.1.0",
"react": "17.0.2",
"#typescript-eslint/eslint-plugin": "^4.33.0",
"#typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"eslint-config-next": "^12.2.5",
"eslint-config-prettier": "^6.15.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^5.10.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jest": "^24.7.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.27.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-testing-library": "^3.10.2",
The NPM package installed, has this folder structure:
/node_modules/#vercel
analytics/
dist/
react/
index.cjs
index.d.ts
index.js
index.cjs
index.d.ts
index.js
package.json
tsconfig.json
...
Notice how the path in node_modules actually is '#vercel/analytics/dist/react' rather than just '#vercel/anaylitics/react' as the instructions state to do in the code to use it.
But, when CTRL+click'ing on the variable imported Analytics, my IDE properly navigates me to the definition in node_modules, to the file #vercel/analytics/dist/react/index.d.ts, which is defined like so:
// ./node_modules/#vercel/analytics/dist/react/index.d.ts
// ...
declare function Analytics(props: AnalyticsProps): JSX.Element;
export { Analytics };
My ESLint config related to the import/ module is
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
paths: ['src'],
},
},
},
If I import it as this instead:
import { Analytics } from '#vercel/analytics/dist/react'
then ESlint doesn't complain, but TSC does, with this error message:
TS2305: Module '"#vercel/analytics/dist/react"' has no exported member 'Analytics'.
Which also doesn't seem to make sense as the IDE is still finding the definition, and I can also see how the export { Analytics } line is there, so it should work...
What ESlint config or steps should I take differently to make this work without any lint/compiler errors?
When using eslint you will need to use the plugin: eslint-import-resolver-typescript with version 3.1.0 or later.
We also merged this version into eslint-config-next in this Pull Request. So this issue should also be resolved by upgrading to the latest package (13.0.4)
There is also a issue on our Github repo which with the solution: https://github.com/vercel/analytics/issues/18#issuecomment-1318424277
I have a question into vercel for a solution as I have the same issue. Probably to be expected since this is a beta product. I added the following line to my _app.js file in the meantime which allowed me to bypass the linting error and deploy to vercel. I have tested and the analytics is showing so must simply be a bug.
...
// eslint-disable-next-line import/no-unresolved
import { Analytics } from "#vercel/analytics/react";
...
Try this way
//tsconfig.json
"compilerOptions": {
"baseUrl": "./",
"paths": {
"#vercel/analytics/react": ["./node_modules/#vercel/analytics/dist/react"]
}
}

Using a Vue2 component into a Vite/Vue3 app

I'm using Vite/Vue3 (TypeScript if that matters), and I'd like to use the following Vue2 component: https://github.com/tylerkrupicka/vue-json-component
After importing it with the following declaration:
import JSONView from 'vue-json-component'
and using it like so:
<JSONView:data="{foo:'bar',toto:'baz'}" root-key="root" class="tree" />
The following error is reported by Vite:
✘ [ERROR] No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "default"
node_modules/vue-json-component/dist/index.module.js:2:7:
2 │ import Vue from 'vue';
My understand is that Vite does not play well with Vue2. I've been trying to find a solution to declare Vue2 components, or "wrap" them to make them work with Vite/Vue3, without success.
I'd like to avoid forking the project if possible to rewrite it for Vue3.
Thanks
In your package.json, add the following:
"dependencies": {
- "vue": "^2.6.12",
+ "vue": "^3.1.0",
+ "#vue/compat": "^3.1.0"
...
},
"devDependencies": {
- "vue-template-compiler": "^2.6.12"
+ "#vue/compiler-sfc": "^3.1.0"
}

Quasar 2 + Apollo: Error: Apollo client with id default not found. Use provideApolloClient() if you are outside of a component setup

followed the steps in https://github.com/quasarframework/app-extension-apollo/tree/v2 to install Apollo extension to Quasar 2.4.9:
"devDependencies": {
"#babel/eslint-parser": "^7.13.14",
"#quasar/app": "^3.0.0",
"#quasar/quasar-app-extension-apollo": "^2.0.0-beta.3",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^7.0.0",
"eslint-webpack-plugin": "^2.4.0"
},
found two files generated which are related to apollo:
src/boot/apollo.js
src/apollo/index.js, where I modified the process.env.GRAPHQL_URI to be mine GraphQL server endpoint
I also created apollo.provider.js under root manually with :
// apollo.config.js
module.exports = {
client: {
service: {
name: "my-app",
// URL to the GraphQL API
url: "http://localhost:4000/graphql",
},
// Files processed by the extension
includes: ["src/**/*.vue", "src/**/*.js"],
},
};
in My Vue file, I have the following code:
<script>
import { useQuery } from "#vue/apollo-composable";
import gql from "graphql-tag";
export default {
setup() {
const { result } = useQuery(gql`
query GetAllBooks {
getAllBooks {
id
name
}
}
`);
},
...
However, running this code led to the following error:
index.esm.js?0df5:48 Uncaught (in promise) Error: Apollo client with id default not found. Use provideApolloClient() if you are outside of a component setup.
at resolveClient (index.esm.js?0df5:48:1)
at start (index.esm.js?0df5:277:1)
at immediate (index.esm.js?0df5:493:1)
at callWithErrorHandling (runtime-core.esm-bundler.js?9e79:6737:1)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?9e79:6746:1)
at job (runtime-core.esm-bundler.js?9e79:7154:1)
at doWatch (runtime-core.esm-bundler.js?9e79:7199:1)
at watch (runtime-core.esm-bundler.js?9e79:7040:1)
at useQueryImpl (index.esm.js?0df5:491:1)
at useQuery (index.esm.js?0df5:228:1)
Any idea which part's wrong?
I found this post I am using vue 3 with apollo/client but getting an error, seems Ricky Vadala's also using Quasar and following the same steps. However, the following doesn't work:
import { apolloClients } from 'src/extensions/apollo/boot'
as 'src/extensions/apollo/boot' does not exist.
Also, I cannot find your-app\node_modules#quasar\quasar-app-extension-apollo\README.md. Maybe Ricky Vadala was using an older version?
Please kindly shed some light on this. Surprisingly I cannot find an example of Quasar 2 + Apollo from the Internet.
Got help from Scott in here.
End of the day, it's an RTFM issue. I didn't read README carefully:
The extension will add a configuration file into src/apollo and a boot file. You'll need to manually register the latter into quasar.conf.js > boot.
Translate that to real-world action, I need to modify quasr.conf.js, find the boot part, and modify it to be:
boot: ["apollo.js"],
After that, the error went away, and I could see the call to my GraphQL endpoint from Chrome dev tools.

Error occurs when applying vuetify and vue-loader together in vue-cli environment

My goal
I made my webpage with vue-cli and vuetify, and I tried to add vue-markdown-loader.
Actual results
But error occured After I add source about vue-loader in vue.config.js
This is error message.
[Vue warn]: Unknown custom element: <v-app> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
[Vue warn]: Unknown custom element: <v-navigation-drawer> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
...
This is my vue.config.js source
module.exports = {
"transpileDependencies": [
"vuetify"
],
chainWebpack: config => {
config.module.rule('md')
.test(/\.md/)
.use('vue-loader')
.loader('vue-loader')
}
}
What I tried
So, I made new simple project to test like next.
vue create test-vuetify
cd test-vuetify
vue add vuetify
and add same settings on vue.config.js
chainWebpack: config => {
config.module.rule('md')
.test(/\.md/)
.use('vue-loader')
.loader('vue-loader')
}
It also occur same error
How can I add vue-loader about markdown file and use vuetify together?
I saw semilar case at vuetify-loader github, and vue-markdown-loader github.
https://github.com/vuetifyjs/vuetify-loader/issues/106
https://github.com/QingWei-Li/vue-markdown-loader/issues/64
But I can't find answer. If anyone knows how to solve this problem, please share it with me.😥
version of modules
This is version of my modules
"#vue/cli-service": "~4.3.0",
"vue": "^2.6.11",
"vuetify": "^2.2.11",
"vuetify-loader": "^1.3.0"