3

I'm trying to add Vue-Splide to my Nuxt project, after following the Vue-Splide documentation to install the plugin, and registering it as a Nuxt plugin I get the error Cannot use import statement outside a module.

nuxt.config.js

buildDir: '../functions/nuxt',
build: {
  publicPath: '/public/',
  vendor: [''],
  extractCSS: true,
  babel: {
    presets: [
      '@babel/preset-env'
    ],
    plugins: [
      ["@babel/plugin-transform-runtime"]
    ]
  }
},
plugins: [
  { src: '~/plugins/splide.client.js', mode: "client" }
],

splide.client.js

import Vue from 'vue';
import VueSplide from '@splidejs/vue-splide';
import '@splidejs/splide/dist/css/themes/splide-default.min.css';

Vue.use(VueSplide);

template

<splide :options="{ rewind: true }" class="banner-container">
  <splide-slide class="slide" v-for="slide in slides" :key="slide.id">
    <img :src="slide.imagen" :alt="slide.tombre" />
   </splide-slide>
</splide>

After transpiling Vue-Splide I now get the error window is not defined, and the stacktrace shows it's happening on node_modules\@splidejs\splide\dist\js\splide.js, I tried surrounding the splide tags with <client-only></client-only>, but that didn't seem to work.

What else am I missing here?

Updating to include my dependencies

"dependencies": {
  "@nuxtjs/firebase": "^7.6.1",
  "@splidejs/vue-splide": "^0.3.5",
  "firebase": "^8.9.1",
  "isomorphic-fetch": "^3.0.0",
  "nuxt": "^2.0.0"
},
"devDependencies": {
  "@babel/plugin-transform-runtime": "^7.15.0",
  "@babel/preset-env": "^7.15.6",
  "@babel/runtime": "^7.15.4",
  "@nuxtjs/tailwindcss": "^4.2.1",
  "autoprefixer": "^10.4.0",
  "babel-eslint": "^10.0.1",
  "babel-plugin-module-resolver": "^4.1.0",
  "eslint": "^4.19.1",
  "eslint-friendly-formatter": "^4.0.1",
  "eslint-loader": "^4.0.2",
  "eslint-plugin-vue": "^7.19.1",
  "firebase-tools": "^9.22.0",
  "node-sass": "^6.0.1",
  "postcss": "^8.3.11",
  "sass-loader": "^12.3.0",
  "tailwindcss": "^2.2.19"
}
kissu
  • 40,416
  • 14
  • 65
  • 133
Danyx
  • 574
  • 7
  • 34
  • I've edited your question with some highlight and removed `~/plugins/splide.client.js` in favor of `~/plugins/splide.js`, `mode: 'client'` doing already that, there is no point double-telling that we want it only on the client. I've also removed irrelevant parts of code. Feel free to edit it yourself if you find it inappropriate. – kissu Nov 30 '21 at 02:03
  • Also, totally unrelated but could you please give a look to my answer on your [other question](https://stackoverflow.com/a/70075647/8816585)? I'm still waiting some feedback if it solved your issue or not. – kissu Nov 30 '21 at 02:09
  • @kissu my apologies, I haven't been able to get back on the other issue as I'm now prioritizing this one. – Danyx Nov 30 '21 at 19:29

2 Answers2

1

The documentation of the vue-splide integration is clearly talking about Vue3 composition API.

Checking in the github issues of vue-splide, I found this one which is referencing a solution that you've linked above. Meanwhile, when trying this, those are the warnings that I do have in my CLI.

Those are also related to Vue3 (which is not compatible with Nuxt2, only Nuxt3 supports Vue3). Looking at the date of all the posts, it looks like it was matching somewhat the time-frame when Vue3 was still in a beta-limbo and probably not adopted by everybody.

At some point, I guessed that the package maybe lost some retro-compatibility with Vue2 in the next months. I then tried to install the version 0.3.5 of @splidejs/vue-splide rather than the latest one and it's working perfectly fine with it!


Here is the whole setup to have it working with Nuxt2 nuxt.config.js

plugins: [{ src: '~/plugins/splide.js', mode: 'client' }],

PS: no need for a transpile because this is not the issue at all here

/plugins/splide.js

import Vue from 'vue'
import VueSplide from '@splidejs/vue-splide'
import '@splidejs/splide/dist/css/themes/splide-default.min.css'

Vue.use(VueSplide)

/pages/index.vue

<template>
  <client-only>
    <Splide :options="{ rewind: true }">
      <SplideSlide>
        <img
          src="https://images.unsplash.com/photo-1638204958375-4824be216720?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=776&q=80"
          alt="Sample 1"
        />
      </SplideSlide>
      <SplideSlide>
        <img
          src="https://images.unsplash.com/photo-1638176061592-d8475d970c19?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80"
          alt="Sample 2"
        />
      </SplideSlide>
    </Splide>
  </client-only>
</template>

It works perfectly fine


I've reported the issue in the github issue, if somebody wants to have more up-to date info or an official answer from the mantainer.
EDIT: we received a confirmation on the non retro-compatibility. Also, the usage of <client-only> is also required to prevent DOM mismatch.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • I'm still running into the same issue, transpiling vue-splide throws me ` window is not defined `, if I don't I get ` Cannot use import statement outside a module`, I already had vue-splide version 0.3.5 installed. I'm updating my post to include my dependencies – Danyx Nov 30 '21 at 19:29
  • @Danyx you don't need to transpile it as I told. Also, using the plugin as I showed and wrapping the whole thing into a `client-only` is enough. Tried it with `ssr: true` and it's working fine on my side. Also, be sure that you're using node with a LTS version, I am on `14.18.1`. This may come from here maybe. – kissu Nov 30 '21 at 19:52
  • I have the Splide element wrapped by , and also just upgraded from node v14..17.6 to v.16.13.0 to see if that was the case, still getting `Cannot use import statement outside a module` – Danyx Nov 30 '21 at 20:38
  • @Danyx add `"type": "module"` to your package.json as [shown here](https://stackoverflow.com/a/59399717/8816585) to fix this issue. Also, are you using TS? I'm not sure where this issue comes from but it's not the first time I see it, do you use a `require` somewhere in your code maybe? – kissu Dec 01 '21 at 03:07
  • already tried adding `"type": "module"` to the root of my package.json and it also didn't work, I'm not using TypeScript, and have no requires anywhere in my source code. – Danyx Dec 01 '21 at 03:36
  • @Danyx I'm not sure how to help more here. Try to narrow down the issue by creating a brand new project and send us the github link, that way we will be able to look at it. Hard to say why this is not working on your side. It's not an issue with the package at least. – kissu Dec 01 '21 at 09:10
  • was just thinking about that, thank you so much for helping with this, I'll set up a new project and go from there – Danyx Dec 01 '21 at 13:57
1

Issue was caused by the configuration required for Firebase hosting if following Firebase's Server-Side Render Vue Apps with Nuxt.js video.

By removing the line buildDir: '../functions/nuxt' in the nuxt.config.js file the project runs fine locally, however, in order to deploy to Firebase you have to:

  1. Replace publicPath: '/public/' with publicPath: '/', both in src/nuxt.config.js, and functions/index.js.
  2. Run npm run build.
  3. Copy the contents of src/.nuxt to functions/nuxt.
  4. Copy the contents of src/.nuxt/dist/client and src/.nuxt/dist/server to public/.

For the moment I do not know if there's a way for vue-splide to work while building to the functions folder, as I already tried installing vue-splide on the functions project with no success.

Danyx
  • 574
  • 7
  • 34