Knight Li design

Knight Li design

  • TOP
  • WORKS
  • STEP INTO TAINAN
  • BLOG
  • CONTACT
ALL TAGS
  • TOP
  • WORKS
  • STEP INTO TAINAN
  • BLOG
  • CONTACT

BLOG

Nuxt.js 相關配置

程式技術教學

PUBLIC DATE:2021.09.09

B-09202112
 
 Nuxt.js 相關配置





Nuxt.js Config 配置範例


配置 nuxt.config.js 文件前,可用 Yarn 安裝 @nuxtjs/dotenv 作為 Nuxt.js 的環境變數。



// 引用 Webpack
import webpack from 'webpack'

export default {

  // // 定義 Nuxt.js 應用程序的主目錄
  // srcDir: 'nuxt/',

  // // yarn generate 輸出後資料夾名稱
  // generate: {
    // dir: 'dist'
  // }

  // 監聽(建置 Docker 環境時需加入)
  watchers: {
    webpack: {
      // HMR,在生產模式下不使用(建置 Docker 環境時需加入才有作用)
      poll: process.env.NODE_ENV !== 'production'
    }
    // webpack: {
    //   // 第一次 Watch 監聽的 Delay 時間
    //   aggregateTimeout: 300,
    //   // Watch 的間隔時間
    //   poll: 1000
    // }
  },

  // 伺服器設定(建置 Docker 環境時需加入才有作用)
  server: {
    // Node.js 預設為 localhost(127.0.0.1)(process.env.NUXT_SERVER_HOST 當前環境變數設為 0.0.0.0)
    host: process.env.NUXT_SERVER_HOST,
    // Node.js 預設為 3000(process.env.NUXT_SERVER_PORT 環境變數不變)
    port: process.env.NUXT_SERVER_PORT
  },

  // Server Miiddleware
  serverMiddleware: [
    {
      path: process.env.API_PATH,
      handler: '~/server/routes/frontend.js'
    }, {
      path: `${process.env.API_PATH}/core`,
      handler: '~/server/routes/backend.js'
    }
  ],

  // // Route Miiddleware
  // router: {
    // middleware: ['']
  // },

  // Axios module configuration
  axios: {
    // 請求 URL 最後加入前輟
    prefix: process.env.API_PATH,
    // // 如單純 IP 位置,伺服器無反向代理時,取消註解,並把 proxy 改為 false 或註解與 nuxt.config.js 中的 proxy 項目改為註解或移除
    // // https://axios.nuxtjs.org/options/#baseurl
    // baseURL: process.env.BASE_URL,

    // 開啟伺服器(Nginx)反向代理,需安裝 @nuxtjs/proxy 套件
    // 注意:baseURL 與 proxy 不得同時使用。所以 proxy 在使用選項時,需要定義 prefix 而不是 baseURL,且不需要手動 nuxt.config.js 中的 modules 項目註冊 @nuxtjs/proxy
    // https://axios.nuxtjs.org/options/#proxy
    proxy: true
  },

  // 伺服器(Nginx)反向代理設定
  // https://github.com/nuxt-community/proxy-module
  proxy: [
    process.env.BASE_URL + process.env.API_PATH
  ],

  // Build Configuration(https://go.nuxtjs.dev/config-build)
  build: {
    // 解決 babel 在 Nuxt.js 的報錯。(Though the "loose" option was set to "false" in your @babel/preset-env config)當時為本機端無報錯,但上線後在 Linode VPS 運行中報錯。
    babel: {
      plugins: [
        ['@babel/plugin-proposal-private-property-in-object', {
          loose: true
        }]
      ]
    },
    // 關閉 Nuxt.js 加載屏(解決導致瀏覽器會持續跑loading/sse net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)的錯誤)
    // https://github.com/nuxt/loading-screen
    loadingScreen: false,
    // Webpack 加入 Plugins
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
      })
    ],
    postcss: {
      plugins: {
        // https://github.com/cuth/postcss-pxtorem
        'postcss-pxtorem': {
          // 初始 px
          rootValue: 16,
          // 小數點第幾位
          unitPrecision: 5,
          // 最小 px 值
          minPixelValue: 0,
          // 轉換哪些屬性('width', 'height', 'line-height'.....)
          propList: ['*']
        }
      }
    }
  },

  // Plugins to run before rendering page
  // https://go.nuxtjs.dev/config-plugins
  plugins: [
    '~/plugins/axios',
    { src: '~/plugins/gtm', mode: 'client' },
    { src: '~/plugins/object-fit-images', mode: 'client' },
    { src: '~/plugins/gsap-plugins', mode: 'client' },
    { src: '~/plugins/aos', mode: 'client' }
  ],

  // Modules for dev and build(recommended)
  // https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    '@nuxtjs/eslint-module',
    // https://github.com/nuxt-community/dotenv-module
    '@nuxtjs/dotenv',
    // https://github.com/nuxt-community/pwa-module
    '@nuxtjs/pwa',
    // https://github.com/nuxt-community/fontawesome-module
    '@nuxtjs/fontawesome',
    // https://github.com/pirony/nuxt-gsap
    'nuxt-gsap'
  ],

  // Modules(https://go.nuxtjs.dev/config-modules)
  modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios',
    // https://github.com/nuxt-community/style-resources-module
    '@nuxtjs/style-resources',
    // https://gitlab.com/broj42/nuxt-lazy-load
    ['nuxt-lazy-load', {
      directiveOnly: true
    }],
    // https://github.com/nuxt-community/auth-module
    '@nuxtjs/auth-next',
    // https://github.com/nuxt-community/recaptcha-module
    '@nuxtjs/recaptcha',
    // https://github.com/Developmint/nuxt-webfontloader
    'nuxt-webfontloader'
  ],

  // 自動導入 Components
  // https://go.nuxtjs.dev/config-components
  components: true,

  // 自訂載入頁面 Component
  loading: '~/components/Loading.vue',

  // Global CSS
  // https://go.nuxtjs.dev/config-css
  // assets 資料夾如果要使用 SCSS,請確保已安裝 yarn add node-sass sass-loader -D
  css: [
    '~/assets/scss/reset_css.scss',
    '~/assets/scss/app.scss'
  ],

  // SCSS 全局變數(供其它 SCSS 文件使用)
  // assets 資料夾如果要使用 SCSS 全局變數,請確保已安裝 yarn add @nuxtjs/style-resources -D
  styleResources: {
    scss: [
      '~/assets/scss/variables.scss'
    ]
  },

  // Global page headers
  // https://go.nuxtjs.dev/config-head
  // 補足 PWA 所沒有提供的部分
  head: {
    meta: [
      { hid: 'copyright', name: 'copyright', content: `${process.env.APP_NAME}, All Rights Reserved` }
    ]
  },

  // Global page PWA
  pwa: {
    meta: {
      // 初始值為 package.json 設定
      name: process.env.APP_NAME,
      short_name: process.env.APP_NAME,
      description: 'Web creation, Graphic design, Visual design',
      author: 'Knight Li',
      // 網站語系
      lang: 'zh-Hant-TW',
      // Viewport
      viewport: 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover',
      // 修改網站佈景顏色
      theme_color: '#161f28',
      // Apple 螢幕上方狀態列顏色
      appleStatusBarStyle: 'black',
      // OGP
      ogHost: process.env.BASE_URL,
      ogImage: `${process.env.BASE_URL}/images/ogp/ogp.png`,
      // Twitter Card
      twitterCard: 'summary_large_image',
      twitterSite: '@KnightLi_0617',
      twitterCreator: '@KnightLi_0617'
    },
    manifest: {
      // 初始值為 package.json 設定
      name: process.env.APP_NAME,
      short_name: process.env.APP_NAME,
      description: 'Web creation, Graphic design, Visual design',
      // 調整網站起始連結
      start_url: '/?standalone=true',
      // 網站顯示模式
      display: 'standalone',
      // 設定 Splash Screen 背景顏色
      background_color: '#161f28',
      // 修改網站佈景顏色
      theme_color: '#161f28',
      // 文字顯示方向,由左至右
      dir: 'ltr',
      // 網站語系
      lang: 'zh-Hant-TW',
      // 文件擴展名設置為 .json 或 .webmanifest
      useWebmanifestExtension: false
    }
  },

  // WebFont Loader
  webfontloader: {
    custom: {
      // Google Fonts字型
      families: [
        'Rubik:n4,n7',
        'Noto+Sans+TC:n4,n7',
        'Azeret+Mono'
      ],
      // Google Fonts 字型所對應的網址
      urls: [
        'https://fonts.googleapis.com/css?family=Rubik:400,700|Noto+Sans+TC:400,700|Azeret+Mono:500,700&display=swap'
      ]
    }
  },

  // Fontawesome Icons
  fontawesome: {
    // Template component 前綴:
    component: 'fa',
    // Template component 後綴:
    suffix: false,
    // 要引入的Icons
    icons: {
      // 需安裝 yarn add @fortawesome/free-solid-svg-icons -D
      solid: [
        'faSun', 'faMoon', 'faLaptop', 'faArrowUp', 'faArrowRight', 'faArrowLeft', 'faSearch', 'faSearchPlus', 'faTag', 'faPlusCircle', 'faInfoCircle', 'faHdd', 'faCaretLeft',
        'faCaretRight', 'faStepBackward', 'faStepForward', 'faAngleRight', 'faList', 'faUserLock', 'faUserCog', 'faClipboard', 'faLink', 'faUndoAlt',
        'faUser', 'faPhone', 'faEnvelope', 'faQuestionCircle', 'faLock', 'faExclamationCircle', 'faCheckCircle', 'faTimesCircle', 'faKey', 'faCheckSquare',
        'faPen', 'faSignOutAlt', 'faSignInAlt', 'faHome', 'faPaintBrush', 'faBook', 'faAddressBook', 'faBell', 'faUsers', 'faDatabase',
        'faCog', 'faMapMarkerAlt', 'faChartLine', 'faGlobeAmericas', 'faEllipsisH', 'faSave', 'faTrash', 'faListUl', 'faFolder', 'faFileAlt', 'faFolderOpen', 'faImage',
        'faDownload', 'faUserCircle'
      ],
      // 需安裝 yarn add @fortawesome/free-regular-svg-icons -D
      regular: ['faFolderOpen', 'faCalendarAlt', 'faClock', 'faEnvelope', 'faSquare', 'faWindowMaximize', 'faEye', 'faEyeSlash'],
      // 需安裝 yarn add @fortawesome/free-brands-svg-icons -D
      brands: ['faGithub', 'faFacebookSquare', 'faInstagram', 'faTwitter', 'faLine', 'faGoogle']
    }
  },

  // Google reCAPTCHA 驗證
  recaptcha: {
    hideBadge: true,
    siteKey: process.env.RECAPTCHA_SITE_KEY,
    version: 3
  },

  // Auth 驗證
  auth: {
    redirect: {
      login: false,
      logout: false,
      home: false,
      callback: false
    },
    strategies: {
      local: {
        scheme: 'refresh',
        token: {
          // Express 輸出 JSON 格式 res.json 名稱
          property: 'access_token',
          // 令牌到期時間,以秒為單位
          maxAge: (60 * process.env.AUTH_TOKEN_EXPIRE) || 0
        },
        refreshToken: {
          // Express 輸出 JSON 格式 res.json 名稱
          property: 'refresh_token',
          // 登入後,Express 能所訪問取得 Refresh Token 的名稱
          data: 'refresh_token',
          // 令牌到期時間,以秒為單位
          maxAge: (60 * 60 * process.env.AUTH_REFRESH_TOKEN_EXPIRE) || 0
        },
        user: {
          // Express 輸出 JSON 格式 res.json 名稱
          property: 'user',
          // endpoints.user 在成功登錄後立即發送請求,獲取用戶 JSON 資料
          autoFetch: true
        },
        endpoints: {
          login: {
            url: 'core/auth/login',
            method: 'post'
          },
          refresh: {
            url: 'core/auth/refresh',
            method: 'post'
          },
          user: {
            url: 'core/auth/user',
            method: 'post'
          },
          logout: false
        }
      }
    }
  }

}





Sequelize ORM 設定


   目錄、文件所在位置:



 nuxt-app
  ┣ ─── 省略 ───
  ┣  server
    ┣  config
      ┗  config.js
    ┣  migrations
    ┣  models
      ┗  index.js
    ┗  seeders
  ┣ ─── 省略 ───
  ┗  .sequelizerc

   .sequelizerc:


指定 Sequelize ORM 目錄文件路徑。



  const path = require('path')
module.exports = {
  'config': path.resolve('server/config', 'config.js'),
  'migrations-path': path.resolve('server', 'migrations'),
  'models-path': path.resolve('server', 'models'),
  'seeders-path': path.resolve('server', 'seeders')
}

   nuxt-app/server/config/config.js:


DB 環境設定文件。



  // 引入 .env
require('dotenv').config()

module.exports = {
  development: {
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    dialect: 'mariadb',
    timezone: '+08:00',
    logging: false,
    define: {
      charset: 'utf8',
      dialectOptions: {
        collate: 'utf8mb4_unicode_ci'
      }
    }
  },
  test: {
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    dialect: 'mariadb',
    timezone: '+08:00',
    logging: false,
    define: {
      charset: 'utf8',
      dialectOptions: {
        collate: 'utf8mb4_unicode_ci'
      }
    }
  },
  production: {
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    dialect: 'mariadb',
    timezone: '+08:00',
    logging: false,
    define: {
      charset: 'utf8',
      dialectOptions: {
        collate: 'utf8mb4_unicode_ci'
      }
    }
  }
}

   nuxt-app/server/models/index.js:


建立 DB 連線模塊。



  'use strict'

// 檔案模組(Node.js 內建)
const fs = require('fs')
// 路徑設定(Node.js 內建)
const path = require('path')
// Sequelize ORM 資料庫模組
const Sequelize = require('sequelize')
// 獲取檔名
const basename = path.basename(__filename)
// 環境變量執行方式(node 或 sequelize config.js)
const env = process.env.NODE_ENV || 'development'
// sequelize DB 環境設定文件
const config = require(`${__dirname}/../config/config.js`)[env]

// 建立 DB
const db = {}
// 建立 Sequelize ORM 資料庫
let sequelize

// 資料庫連線(是否在 sequelize config.js 有使用 process.env 方式)
if (config.use_env_variable) {
  // 在 config.js 裡有加入 use_env_variable 的鍵值來產生 sequelize instance
  // 範例:'use_env_variable': 'mysql://DB_USER:DB_PASSWORD@DB_HOST/DB_NAME'
  sequelize = new Sequelize(process.env[config.use_env_variable], config)
} else {
  // 在 config.js 預設鍵值來產生 sequelize instance
  sequelize = new Sequelize(config.database, config.username, config.password, config)
}

// fs 將會把相同目錄底下的 .js 以 model.name 當索引值放到 DB 物件中。執行每一個 model 的 define 資料表與 JS 對應上。
fs
  .readdirSync(__dirname)
  .filter((file) => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')
  })
  .forEach((file) => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes)
    db[model.name] = model
  })

// 執行每一個 model 關聯的初始化與設定(static associate (models){},[modelName] 為關聯式資料庫的 foreign key 的設定與 JS 對應上)
Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db)
  }
})

// sequelize 全域物件與類別,加入至 DB
db.sequelize = sequelize
db.Sequelize = Sequelize

// 輸出 DB
module.exports = db





Docker 下的 Nuxt.js Config 設定


   nuxt.config.js - HMR 設定:



export default {
  // 監聽
  watchers: {
    webpack: {
      // HMR,在生產模式下不使用
      poll: process.env.NODE_ENV !== 'production'
    }
    // webpack: {
    //   // 第一次 Watch 監聽的 Delay 時間
    //   aggregateTimeout: 300,
    //   // Watch 的間隔時間
    //   poll: 1000
    // }
  }
}

   nuxt.config.js - Host & Port 設定:


Docker Server IP【127.0.0.1】與【0.0.0.0】之差別。
更多詳細說明:說明連結


127.0.0.1指【Container 容器】非指【Machine 機器】。
如果從容器綁定到 127.0.0.1 ,它將返回到同一個容器,且不接受來自外部的連接。
0.0.0.0指【所有接口】。如果將容器綁定到特殊 0.0.0.0,容器可接受來自外部的連接。


export default {
  server: {
    // Node.js 預設為 localhost(127.0.0.1)
    host: 0.0.0.0,
    // Node.js 預設為 3000
    port: 3000
  }
}





Nuxt.js Axios Https 協議禁用證書校驗


當時在 VPS 架設上線時,Yarn 運行當中在 CMD 得到了【 unable to verify the first certificate 】的錯誤,此問題為 Axios 通信時所發生的 SSL 證書問題。


   目錄、文件所在位置:



 nuxt-app
  ┣ ─── 省略 ───
  ┣  plugins
    ┗  axios.js
  ┣ ─── 省略 ───
  ┗  nuxt.config.js

※※※※※ 注意事項 ※※※※※
這裡我是用反向代理 Proxy 方式,在 nuxt.config.js 文件中的 axios 無法 create baseURL Http 或 Https 的方式(上方有 nuxt.config.js 文件中的 axios 項目配置說明)。而是採用下方禁用證書校驗方式。


   nuxt-app/plugins/axios.js:



// 引用 https
import https from 'https'

export default ({ $axios, error }) => {
  // 上線佈署,Axios Https 禁用證書校驗
  // https://t-kuni-tech.com/2021/04/04/nuxt-axios%E3%81%A7unable-to-verify-the-first-certificate%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E6%99%82%E3%81%AE%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95/
  // https://cloud.tencent.com/developer/article/1648407
  if (process.env.NODE_ENV === 'production') {
    // Https 證書校驗
    $axios.defaults.httpsAgent = new https.Agent({ rejectUnauthorized: false })
  }
}

TAGSALL TAGS

  • # Nuxt.js
  • # JavaScript
  • # Docker

SHARE

https://knight-li.com/blog/B-09202112/detail

RELATED

  • Nuxt.js 相關配置

    2021.09.14

    Laravel 相關配置

    程式技術教學

  • Nuxt.js 相關配置

    2019.11.13

    npm CLI

    程式技術教學

  • Nginx Config 設定

    PREV POST Nginx Config 設定

  • Linode VPS 無法收發郵件

    NEXT POST Linode VPS 無法收發郵件

Knight Li design

CONTACT

©Knight Li design, All Rights Reserved