![](https://habrastorage.org/webt/8q/ab/wl/8qabwlstgtbibz-j7p0ltkhkiv0.png)
( イラスト )
シニアWeb開発者のアントンとアレクセイは、Nuxtとの困難な闘いの物語を続けています。 このフレームワークとの戦いの前のラウンドで 、彼らは皆が幸せになるようにNuxtでプロジェクトを立ち上げる方法を示しました。 新しい記事では、フレームワークの実際のアプリケーションについて説明します。
私たちは大きな技術的負債でプロジェクトを書き直し始めました。 毎月のオーディエンスは600万から700万のユニークビジターでしたが、既存のプラットフォームでは多くの問題が発生しました。 したがって、彼女を退職させることにした。 もちろん、パフォーマンスが最大の関心事でしたが、SEOを無駄にしたくもありませんでした。
数回の議論の後、彼らはサーバー側レンダリングのみの従来のアプローチに依存しないことを決めましたが、クライアント側レンダリングに自分自身を閉じ込めることはしませんでした。 その結果、 Nuxt.jsに基づくソリューションの構築を開始しました。
古き良きNuxt.js
ユニバーサルクライアントサーバーアプリケーションを構築するためのVue.jsに基づく前回の記事で既に知られている「フレームワークのフレームワーク」を採用します。 私たちの場合、アプリケーションはかなり複雑なAPI(マイクロサービスの複雑さ、しかしそれについて)とキャッシュのいくつかのレイヤーと連携して動作し、エディターによって編集可能なコンテンツをレンダリングし、超高速パフォーマンスのために既に静的コンテンツを返します。 いいですね
実際、ここには新しいものは何もありません。 しかし、Nuxt.jsを興味深いものにしているのは、クライアントサーバーレンダリングを使用してプロジェクトをすばやく開始できることです。 フレームワークの確立されたフレームワークに反する必要がある場合があります。 それが私たちがしたことです。
説明し、一度構築し、多くを展開する時間はありません!
ある日、テクライドが私たちに近づき、困惑しました。リポジトリに変更をプッシュするたびに、各環境(開発環境、ステージ環境、および製品環境)を個別に構築する必要があります。 遅かった。 しかし、これらのビルドの違いは何ですか? はい、環境変数でのみ! そして、彼がやろうとしたことは論理的で合理的だった。 しかし、最初の反応はO_o
一度構築すれば、ソフトウェア開発の世界では多くの戦略を展開できます。 しかし、Javascriptの世界では...コンパイラ、トランスパイラー、プリプロセッサとポストプロセッサ、さらにテストとリンターが揃っています。 これらはすべて、環境ごとに構成するのに時間がかかります。 さらに、機密データの漏洩には多くの潜在的な問題があります(構成に保存できる秘密、APIキーなど)。
そして始めた
もちろん、Googleでの検索から始めました。 その後、Nuxt.jsのメンテナーと話しましたが、あまり成功しませんでした。 対処方法-StackOverflowからコピーするのではなく、自分で解決策を考え出さなければなりませんでした(これが私たちの活動の基礎ですよね?)。
Nuxt.jsがどのように行うかを見てみましょう。
Nuxt.jsには、予想される名前nuxt.config.jsの構成ファイルがあります。 プログラムで構成をアプリケーションに転送するために使用されます。
const config = require('nuxt.config.js') const nuxt = new Nuxt(config)
env変数を使用して環境を設定することができます。 一般的に、かなり一般的な方法は、構成ファイルを動的に接続することです。 次に、これらはすべてdefinePlugin webpackに転送され、次のようなクライアントとサーバーで使用できます。
process.env.propertyName
//または
context.env.propertyName。
これらの変数はアセンブリ中にベイク処理されます 。詳細については、 Nuxt.js env pageを参照してください 。
Webpackに気づきましたか? はい、それはコンパイルを意味し、それは私たちが望んでいるものではありません。
別に試してみましょう
Nuxt.jsの仕組みを理解することは、私たちにとって次のことを意味します。
- nuxt.config.js内でenvを使用できなくなりました。
- 他の動的変数(head.meta内など)は、実行時にnuxt.config.jsオブジェクトに渡す必要があります。
サーバー/ index.jsのコード:
const config = require('../nuxt.config.js')
変更先:
// Nuxt.js const config = require('./utils/extendedNuxtConfig.js').default
utils / extendedNuxtConfig.js:
import config from 'config' import get from 'lodash/get' // Nuxt.js const defaultConfig = require('../../nuxt.config.js') // const extendedConfig = {} // Nuxt.js const nuxtConfig = { ...defaultConfig, ...extendedConfig } // // if (get(nuxtConfig, 'head.meta')) { nuxtConfig.head.meta.push({ hid: 'og:url', property: 'og:url', content: config.get('app.canonical_domain') }) } export default nuxtConfig
象にも気付かなかった
さて、nuxt.config.jsの構成オブジェクトのenvプロパティの外部から動的変数を取得する問題を解決しました。 しかし、元の問題はまだ解決されていません。
いくつかの抽象的なsharedEnv.jsが以下のために使用されるという仮定がありました。
- クライアント-グローバルにダウンロードされるenv.jsファイル(window.env.envKey)を作成し、
- サーバー-モジュールにインポートされます。必要に応じて、
- 同型コード、次のようなもの
context.isClient? window.env [キー]:global.sharedEnv [キー]。
どういうわけか素晴らしい。 この抽象化は、最も深刻な問題-機密データのクライアントアプリケーションへの漏洩を解決します。これは、価値を意識的に追加する必要があるためです。
Vuexがお手伝いします
問題の調査中に、Vuexストアがウィンドウオブジェクトにエクスポートされていることに気付きました。 このソリューションは、Nuxt、jsの同型をサポートすることを余儀なくされています。 Vuexは、Vue.jsアプリケーション専用に設計されたFluxにヒントを得たデータウェアハウスです。
それでは、共有変数に使用してみませんか? これは、よりオーガニックなアプローチです。グローバルリポジトリのデータが適しています。
server / utils / sharedEnv.jsから始めましょう。
import config from 'config' /** * , * , * , * * @type {Object} */ const sharedEnv = { // ... canonicalDomain: config.get('app.canonical_domain'), } export default sharedEnv
上記のコードはサーバーの起動時に実行されます。 次に、それをVuexリポジトリに追加します。
/** * . * * . * https://nuxtjs.org/guide/vuex-store/#the-nuxtserverinit-action * * @return {Object} Shared environment variables. */ const getSharedEnv = () => process.server ? require('~/server/utils/sharedEnv').default || {} : {} // ... export const state = () => ({ // ... sharedEnv: {} }) export const mutations = { // ... setSharedEnv (state, content) { state.sharedEnv = content } } export const actions = { nuxtServerInit ({ commit }) { if (process.server) { commit('setSharedEnv', getSharedEnv()) } } }
サーバーの初期化中にnuxtServerInitが起動されるという事実に依存します。 いくつかの困難があります。getSharedEnvメソッドに注意してください。ここでは、サーバーでの繰り返し実行のチェックが追加されます。
どうした
次のようなコンポーネントで抽出できる一般的な変数を取得します。
this。$ store.state.sharedEnv.canonicalDomain
勝利!
いえいえ プラグインはどうですか?
一部のプラグインでは、構成するために環境変数が必要です。 そして、それらを使用したい場合:
Vue.use(MyPlugin、{someEnvOption: 'vuexストアにアクセスできません'})
素晴らしい競合状態。Vue.jsはNuxt.jsがVuexリポジトリにsharedEnvobjectを登録する前に自身を初期化しようとします。
プラグインを登録する関数は、リポジトリリンクを含むContextオブジェクトへのアクセスを提供しますが、sharedEnvはまだ空です。 これは非常に簡単に解決されます-プラグインを非同期関数にして、nuxtServerInitが実行されるのを待ちましょう:
import Vue from 'vue' import MyPlugin from 'my-plugin' /** * MyPlugin . */ export default async (context) => { // , sharedEnv await context.store.dispatch('nuxtServerInit', context) const env = { ...context.store.state.sharedEnv } Vue.use(MyPlugin, { option: env.someKey }) }
今が勝利です。