mdbootstrap / TW-Elements

𝙃π™ͺπ™œπ™š collection of Tailwind MIT licensed (free) components, sections and templates 😎
https://tw-elements.com
MIT License
12.9k stars 1.62k forks source link

Nuxt 2 integration - document is not defined #1710

Open BrunoGGM opened 1 year ago

BrunoGGM commented 1 year ago

It is not possible to make it work in with version 1.0.0-beta2, I am working with nuxt 2.17 and vue 2.7

The following error is displayed document is not defined

image

Uncaught InternalError: too much recursion
    tokenize http://app.home.test/test:990
    highlight http://app.home.test/test:990
    highlightElement http://app.home.test/test:990
    highlightAll http://app.home.test/test:990
    showFrameContext http://app.home.test/test:1049
    <anonymous> http://app.home.test/test:1063
    e https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js:2

image

Show your code

pages/test.vue

    <template>
      <div>
        <client-only placeholder="Loading...">
          <TestComponent></TestComponent>
        </client-only>
      </div>
    </template>

    <script setup></script>

    <style></style>

components/TestComponent.vue

    <template>
      <div class="relative mb-3" data-te-datepicker-init data-te-input-wrapper-init>
        <input
          type="text"
          class="peer block min-h-[auto] w-full rounded border-0 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 peer-focus:text-primary data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none dark:text-neutral-200 dark:placeholder:text-neutral-200 dark:peer-focus:text-primary [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0"
          placeholder="Select a date"
        />
        <label
          for="floatingInput"
          class="pointer-events-none absolute left-3 top-0 mb-0 max-w-[90%] origin-[0_0] truncate pt-[0.37rem] leading-[1.6] text-neutral-500 transition-all duration-200 ease-out peer-focus:-translate-y-[0.9rem] peer-focus:scale-[0.8] peer-focus:text-primary peer-data-[te-input-state-active]:-translate-y-[0.9rem] peer-data-[te-input-state-active]:scale-[0.8] motion-reduce:transition-none dark:text-neutral-200 dark:peer-focus:text-primary"
          >Select a date</label
        >
      </div>
    </template>

    <script setup>
    import { Datepicker, Input, initTE } from 'tw-elements';
    import { onMounted } from 'vue';

    onMounted(() => {
      setTimeout(() => {
        initTE({ Datepicker, Input });
      }, 1000);
    });
    </script>

    <style></style>

nuxt.config.js

export default {
      target: 'static',
      head: {
        htmlAttrs: {
          lang: 'es',
        },
        meta: [
          { charset: 'utf-8' },
          { name: 'viewport', content: 'width=device-width, initial-scale=1' },
          { hid: 'description', name: 'description', content: '' },
          { name: 'format-detection', content: 'telephone=no' },
        ],
        link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' }],
      },

      // server config
      server: {
        port: process.env.SERVER_PORT, // default: 3000
      },

      // Auto import components: https://go.nuxtjs.dev/config-components
      components: true,

      // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
      buildModules: [
        // https://go.nuxtjs.dev/typescript
        '@nuxt/typescript-build',
      ],

      // Modules: https://go.nuxtjs.dev/config-modules
      modules: ['@nuxtjs/axios', '@nuxtjs/auth-next', '@nuxtjs/i18n'],

      router: {
        middleware: ['auth'],
      },

      // Build Configuration: https://go.nuxtjs.dev/config-build
      build: {
        postcss: {
          postcssOptions: {
            plugins: {
              tailwindcss: {},
              autoprefixer: {},
            },
          },
        },
        analyze: true,
        extractCSS: true,
        standalone: true,
      },
    publicRuntimeConfig: {},
      watchers: {
        webpack: {
          ignored: /node_modules/,
        },
      },
    };

tailwind.config.js

/** @type {import('tailwindcss').Config} */

module.exports = {
  content: [
    './components/**/*.{js,vue,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './plugins/**/*.{js,ts}',
    './nuxt.config.{js,ts}',
    './node_modules/tw-elements/dist/js/**/*.js',
  ],
  plugins: [require('@tailwindcss/forms'), require('tw-elements/dist/plugin')],
};
juujisai commented 1 year ago

Hi! In nuxt 2 try using dynamic imports in the mounted option like this:

<template>
  <div class="relative mb-3" data-te-datepicker-init data-te-input-wrapper-init>
         ...
  </div>
</template>

<script>
export default {
  name: "Datepicker",
  mounted: async function () {
    const { Datepicker, Input, initTE } = await import("tw-elements");

    initTE({ Datepicker, Input });
  },
};
</script>

Hope it helps!

BrunoGGM commented 1 year ago

@juujisai Thank you for your time and your answer, your solution works.

But I'm a bit unhappy with the size of the final bundle, in 1.0.0-beta2 the size of the final bundle increases and it seems to now add a chart.es.js file.

1.0.0-beta2 image

1.0.0-beta1 image

juujisai commented 1 year ago

chart.es.js is necessary for our chart component. From what I've seen, vite is removing the chart.es.js if charts weren't used in the app, while webpack doesn't. This file may be removed if you did not use the charts.

I'll try to look at the webpack builds when I can.

Ischafak commented 1 year ago

hi mounted: async function () { const { Datepicker, Input, initTE } = await import("tw-elements");

initTE({ Datepicker, Input });

},

i am using nuxt 3 and this is working perfectly but should i add every file this command

is it possible for me to add globally