1

i'm using nuxt 2.15.4 and I suddenly got a very odd issue. my code was working fine (actually still working fine on local <--dev & build--> ) but now on server after build it wont be loaded correctly and I get these errors : GET https://example.com/_nuxt/8bab19f.js net::ERR_ABORTED 404 (Not Found) . what is wrong? actually I have two clones of my app on other server and they works fine! can it be because of bundle size warnings on build? if so how can I reduce bundle size (practical answers with examples plz ;) )??

//nuxt.config.js
import colors from 'vuetify/es5/util/colors'
const env = require('dotenv').config()
const webpack = require('webpack')
export default {
  
  telemetry: false,

  srcDir: process.env.THEME_CUSTOMIZE === 'true' ? 'src/themes/customs/' : 'src/themes/'+process.env.THEME+'/',

  loading: {
    color: 'green',
    failedColor: 'red',
    height: '3px'
  },
  router: {
  },
  head: {
    title: process.env.SITE_TITLE + ' | ' + process.env.SITE_SHORT_DESC || '',
    htmlAttrs: {
      lang: process.env.SITE_LANGUAGE || 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'keywords', name: 'keywords', content: process.env.SITE_KEYWORDS || '' },
      { hid: 'description', name: 'description', content: process.env.SITE_DESCRIPTION || '' },
      { hid: 'robots', name: 'robots', content: process.env.SITE_ROBOTS || '' },
      { hid: 'googlebot', name: 'googlebot', content: process.env.SITE_GOOGLE_BOT || '' },
      { hid: 'bingbot', name: 'bingbot', content: process.env.SITE_BING_BOT || '' },
      { hid: 'og:locale', name: 'og:locale', content: process.env.SITE_OG_LOCALE || '' },
      { hid: 'og:type', name: 'og:type', content: process.env.SITE_OG_TYPE || '' },
      { hid: 'og:title', name: 'og:title', content: process.env.SITE_OG_TITLE || '' },
      { hid: 'og:description', name: 'og:description', content: process.env.SITE_OG_DESCRIPTION || '' },
      { hid: 'og:url', name: 'og:url', content: process.env.SITE_BASE_URL || '' },
      { hid: 'og:site_name', name: 'og:site_name', content: process.env.SITE_OG_SITENAME || '' },
      { hid: 'theme-color', name: 'theme-color', content: process.env.SITE_THEME_COLOR || '' },
      { hid: 'msapplication-navbutton-color', name: 'msapplication-navbutton-color', content: process.env.SITE_MSAPP_NAVBTN_COLOR || '' },
      { hid: 'apple-mobile-web-app-status-bar-style', name: 'apple-mobile-web-app-status-bar-style', content: process.env.SITE_APPLE_WM_STATUSBAR_STYLE || '' },
      { hid: 'X-UA-Compatible', 'http-equiv': 'X-UA-Compatible', content: process.env.SITE_X_UA_Compatible || '' },
      { hid: 'google-site-verification', name:'google-site-verification', content: '' },
      { hid: 'enamad' , name: 'enamad' , content: process.env.ENAMAD_META},
      { hid: 'samandehi' , name: 'samandehi' , content: process.env.SAMANDEHI_META},
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: process.env.SITE_FAVICON },
      { rel: 'canonical', href: process.env.SITE_BASE_URL },
    ]
  },
  css: [
      '~/assets/scss/vuetify.scss',
      '~/assets/scss/style.scss',
      '@mdi/font/css/materialdesignicons.css',
      'font-awesome/css/font-awesome.min.css',
      '@fortawesome/fontawesome-free/css/all.css',
      '~/assets/scss/media.scss',
      '~/assets/scss/customization.scss',
      '~/assets/scss/sweetalert.scss',
      '~/assets/scss/noty.scss',
      '~/assets/scss/flipclock.scss',
      '~/assets/scss/sorting.scss',
      '~/assets/scss/cropper.scss',
      '~/assets/scss/transitions.scss',
      '~/assets/scss/product-zoom.scss',
      'swiper/css/swiper.css',
  ],
  plugins: [
      'plugins/mixins/reqerrors.js',
      'plugins/mixins/user.js',
      'plugins/mixins/language.js',
      'plugins/mixins/shopinfo.js',
      'plugins/mixins/formattedprice.js',
      'plugins/mixins/utils.js',
      'plugins/mixins/cms.js',
      'plugins/mixins/client.js',
      'plugins/mixins/cart.js',
      'plugins/axios.js',
      'plugins/veevalidate.js',
      'plugins/noty.js',
      '@plugins/vuedraggable',
      '@plugins/vuedraggable',
      {src: 'plugins/vuepersiandatepicker.js', mode: 'client'},
      {src: 'plugins/cropper.js', mode: 'client'},
      {src: 'plugins/vue-product-zoomer.js', mode: 'client'},
      {src: 'plugins/vueeditor.js', mode: 'client'},
      {src: 'plugins/nuxt-swiper-plugin.js', mode: 'client' }
  ],
  buildModules: [
    '@nuxtjs/dotenv',
    '@nuxtjs/vuetify',
    '@nuxtjs/device',
    'nuxt-gsap-module',
  ],
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth',
    ['vue-sweetalert2/nuxt',
      {
        confirmButtonColor: '#29BF12',
        cancelButtonColor: '#FF3333'
      }
    ],
    'cookie-universal-nuxt',
    '@nuxtjs/gtm',
    '@nuxtjs/google-gtag'
  ],

  device: {
    refreshOnResize: true
  },

  gtm: {
    id: process.env.GOOGLE_TAGS_ID,
    debug: false,
  },
  'google-gtag': {
    id: process.env.GOOGLE_ANALYTICS_ID,
    debug: false,
  },
  dotenv: {
    path: './'
  },
  gsap: {
    extraPlugins: {
      cssRule: false,
      draggable: false,
      easel: false,
      motionPath: false,
      pixi: false,
      text: false,
      scrollTo: false,
      scrollTrigger: false
    },
    extraEases: {
      expoScaleEase: false,
      roughEase: false,
      slowMo: true,
    }
  },
  axios: {
    baseURL: process.env.API_BASE_URL,
  },
  auth: {
      strategies: {
        local: {
          endpoints: {
            login: { url: 'auth/login', method: 'post', propertyName: 'token' },
            logout: { url: 'auth/logout', method: 'post' },
            user: { url: 'auth/info', method: 'get', propertyName: '' }
          }
        }
      },
      redirect: {
        login: '/login',
        home: '',
        logout: '/login'
      },
      cookie: {
        prefix: 'auth.',
        options: {
          path: '/',
          maxAge: process.env.AUTH_COOKIE_MAX_AGE
        }
      }
  },

  publicRuntimeConfig: {
    gtm: {
      id: process.env.GOOGLE_TAGS_ID
    },
    'google-gtag': {
      id: process.env.GOOGLE_ANALYTICS_ID,
    }
  },

  vuetify:{
    rtl: process.env.SITE_DIRECTION === 'rtl' ? true : false ,
    customVariables: ['~/assets/scss/variables_vuetify.scss'],
    breakpoint: {
      thresholds: {
        xs: 600,
        sm: 960,
        md: 1366,
        lg: 1920,
      },
    },
    icons: {
      iconfont: 'mdi',
    },
    treeShake: true,
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    }
  },
  build: {
    transpile: ['vee-validate/dist/rules'],
    plugins: [
      new webpack.ProvidePlugin({
        '$': 'jquery',
        jQuery: "jquery",
        "window.jQuery": "jquery",
        '_': 'lodash'
      }),
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
    ],
    postcss: {
      preset: {
        features: {
          customProperties: false,
        },
      },
    },
    babel:{
      plugins: [
        ['@babel/plugin-proposal-private-methods', { loose: true }]
      ]
    },
    loaders: {
      scss: {
        additionalData: `
          $direction:${process.env.SITE_DIRECTION};
          $lang:${process.env.SITE_LANGUAGE};
          $theme_body_color:${process.env.THEME_BODY_COLOR};
          $theme_main_color:${process.env.THEME_MAIN_COLOR};
          $theme_main_color2:${process.env.THEME_MAIN_COLOR2};
          $theme_side_color:${process.env.THEME_SIDE_COLOR};
          $theme_side_color2:${process.env.THEME_SIDE_COLOR2};
          $theme_link_color:${process.env.THEME_LINK_COLOR};
        `
      }
    },
  }
}

package.json

{
  "name": "nuxt",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate"
  },
  "dependencies": {
    "@nuxtjs/auth": "^4.9.1",
    "@nuxtjs/axios": "^5.13.1",
    "@nuxtjs/device": "^2.1.0",
    "@nuxtjs/google-gtag": "^1.0.4",
    "@nuxtjs/gtm": "^2.4.0",
    "chart.js": "^2.9.3",
    "cookie-universal-nuxt": "^2.1.4",
    "core-js": "^3.9.1",
    "jquery": "^3.5.1",
    "nuxt": "2.15.4",
    "swiper": "^5.4.5",
    "v-viewer": "^1.5.1",
    "vee-validate": "^3.3.7",
    "vue-awesome-swiper": "^4.1.1",
    "vue-chartjs": "^3.5.0",
    "vue-cropperjs": "^4.1.0",
    "vue-easy-dnd": "^1.10.2",
    "vue-persian-datetime-picker": "^2.2.0",
    "vue-product-zoomer": "^3.0.1",
    "vue-sweetalert2": "^4.2.1",
    "vue2-editor": "^2.10.2",
    "vuedraggable": "^2.24.0"
  },
  "devDependencies": {
    "@fortawesome/fontawesome-free": "^5.15.1",
    "@mdi/font": "^5.9.55",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/vuetify": "1.11.3",
    "flipclock": "^0.10.8",
    "font-awesome": "^4.7.0",
    "noty": "^3.2.0-beta",
    "nuxt-gsap-module": "^1.2.1",
    "sass": "1.32.13"
  }
}

Mojtaba Barari
  • 1,127
  • 1
  • 15
  • 49

1 Answers1

1

Some things that may be improved in your nuxt.config.js configuration:

  • const env = require('dotenv').config() is not needed because it is already baked into Nuxt
  • not an issue but rather a style, use es6 template literals for interpolation, it is more readable
  • your google-site-verification is hardcoded, probably not wanted
  • you do have a LOT of things into your css property, I'm pretty sure that you don't need all of them on every single page. So you could call them only when needed and have a global.scss file to make it a bit more ordered for the remaining (mandatory) global CSS
  • same goes for plugins, a lot of things there (@plugins/vuedraggable is written twice)
  • mixins should not be in plugins but loaded per component, and are actually deprecated in Vue3
  • @nuxtjs/dotenv should be removed from buildModules and package.json
  • you should remove some options in your gsap key because the default options are already the ones that you're passing, just keep slowMo
  • axios should be configured by using runtimeConfigs as explained here: https://stackoverflow.com/a/67983038/8816585
  • your auth key probably works with URL like auth/login but I'd probably be sure that this is fine with something like /auth/login
  • vuetify's RTL is dictated by an env variable? Should be dynamic and depending of the HTML IMO
  • plugin-proposal-private-methods was a pretty ugly fix, it was fixed at 2.15.5 but because of security reasons, I'd rather update it to 2.15.7
  • not sure what are the scss loaders but I think that this can be dynamic with "CSS variables"
  • I'm not sure how you are actually loading lodash, I just hope that you are not bringing the whole library when you're actually only using only a few methods
  • and of course, in my opinion, I'll ditch jQuery totally when using Vue because it's not useful when using this framework, at all.
kissu
  • 40,416
  • 14
  • 65
  • 133
  • Tanx a lot man!! some questions: 1- you said to remove dotenv package? does Nuxt read my `.env` file out of box?? 2- about css and plugins, does it cause heavy load?? (newbie mistake actually) . and about loadash and jQuery, yeah should remove them as never used them!! they were there from the beginning of my app!! one last thing; my mixins are more like utils that i may use every where in my project so i declared them globally (so my scss) , u say it's better practice to use only when needed because of heavy init load ?? and what happened to mixins in Vue3 ?? – Mojtaba Barari Jun 17 '21 at 07:24
  • 1. yep, this is the case. 2. Everything in `css` or `plugins` will be loaded at the beginning of your Nuxt app (so it can slow down the initial loading time of your page) and will be available globally. This is overkill to load a whole 8kB of Slideshow CSS if you only use on the checkout page. Rather load it when you arrive there (no issues, you are allowed to be new to Nuxt man). You can load per your SCSS mixins on demand (`style` section). It is deprecated for a lot of reasons: https://v3.vuejs.org/guide/mixins.html#drawbacks – kissu Jun 17 '21 at 08:07
  • 1
    I knew about style section. all my main styles are in `style.scss` . i separated them in my new theme, but the old one is ........ !! actually i did it for maintenance reasons but now it's gonna kill me!! XD – Mojtaba Barari Jun 18 '21 at 17:30
  • Hi again. one last question. as you mentioned, nuxt now has a built-in dotenv. so I can remove `dotenv` package. Is there anyway to change .env file path like `dotenv` ?? as you can see in my nuxt.config.js there is a `env:{path: './'}` option. – Mojtaba Barari Jul 10 '21 at 10:28
  • @MojtabaBarari do you mean to change the path actually or just keep `./`? – kissu Jul 10 '21 at 10:36
  • nuxt internal env looks for `.env` file in srcDir which by default is '/' . i changed that to 'src/' so it will look for .env in 'src' folder. but my `.env` file is in root dir beside nuxt.config . by `dotenv` package you can change `.env` path by `const env = require('dotenv').config()` and `env:{path: './'}` in nuxt.config file. can it be done with nuxt internal env too?? – Mojtaba Barari Jul 11 '21 at 14:41
  • @MojtabaBarari I've created a whole new question for this. You can find both the question and the answer here: https://stackoverflow.com/q/68338031/8816585 – kissu Jul 11 '21 at 16:23
  • What part of this solution was your resolution? I see a lot of best practice, but not a clear cause/fix – catalpa May 10 '23 at 03:49