VueのSSRサーバーサイドレンダリング例の詳細な説明

VueのSSRサーバーサイドレンダリング例の詳細な説明

サーバーサイドレンダリング (SSR) を使用する理由

  • 検索エンジンのクローラーが完全にレンダリングされたページを直接表示できるため、SEO が向上します。
    なお、現時点では、Google と Bing は同期 JavaScript アプリケーションを問題なくインデックスします。ここで、同期が鍵となります。アプリケーションが最初に読み込み中のデイジー画像を表示し、その後 Ajax 経由でコンテンツを取得する場合、クローラーはページ コンテンツを取得する前に非同期の完了を待機しません。ただし、SEO がサイトにとって重要であり、ページがコンテンツを非同期的に取得する場合は、この問題を解決するためにサーバー側レンダリング (SSR) が必要になる場合があります。
  • 特に低速ネットワークや低速デバイス上で、コンテンツまでの時間が短縮されます。サーバーでレンダリングされたマークアップを表示する前にすべての JavaScript がダウンロードされて実行されるのを待つ必要がないため、ユーザーは完全にレンダリングされたページをより速く見ることができます。これにより、通常、ユーザー エクスペリエンスが向上し、コンテンツ表示までの時間がコンバージョン率に直接相関するアプリケーションにとって重要になります。

サーバー側レンダリング (SSR) を使用する場合、いくつかのトレードオフもあります。

  • 開発条件によって制限されます。特定のライフサイクル フックでのみ使用できるブラウザ固有のコード。一部の外部ライブラリでは、サーバー レンダリングされたアプリケーションで実行するために特別な処理が必要になる場合があります。
  • ビルドのセットアップとデプロイメントに関する追加の要件。任意の静的ファイル サーバーにデプロイできる完全に静的なシングル ページ アプリケーション (SPA) とは異なり、サーバー レンダリング アプリケーションでは、環境で実行するために Node.js サーバーが必要です。
  • サーバー側の負荷が増加します。 Node.js で完全なアプリケーションをレンダリングすると、静的ファイルを提供するだけの場合よりも CPU への負荷が明らかに高くなります。そのため、トラフィック量の増加が予想される場合は、それに応じてサーバーの負荷に備え、キャッシュ戦略を賢く使用してください。

ディレクトリ構造

1. パッケージコマンドと開発コマンドを定義する

開発コマンドはクライアント開発に使用されます

パッケージングコマンドはサーバー側開発のデプロイに使用されます

–watchはファイルを変更して自動的にパッケージ化するのに便利です

"client:build": "webpack --config scripts/webpack.client.js --watch",
"server:build": "webpack --config scripts/webpack.server.js --watch",
"run:all": "同時に \"npm run client:build\" \"npm run server:build\""

client:buildとserver:buildを同時に実行するには

1.1 パッケージ.json

{
  "名前": "11.vue-ssr",
  "バージョン": "1.0.0",
  "説明": ""、
  "メイン": "index.js",
  「スクリプト」: {
    "client:dev": "webpack サーブ --config スクリプト/webpack.client.js",
    "client:build": "webpack --config scripts/webpack.client.js --watch",
    "server:build": "webpack --config scripts/webpack.server.js --watch",
    "run:all": "同時に \"npm run client:build\" \"npm run server:build\""
  },
  「キーワード」: [],
  "著者": ""、
  「ライセンス」: 「ISC」、
  「依存関係」: {
    「同時に」: 「^5.3.0」、
    "コア": "^2.13.1",
    "koa-ルーター": "^10.0.0",
    "koa-static": "^5.0.0",
    "vue": "^2.6.12",
    "vue-router": "^3.4.9",
    "vue-server-renderer": "^2.6.12",
    "vuex": "^3.6.0",
    "webpack-merge": "^5.7.3"
  },
  「devDependencies」: {
    "@babel/core": "^7.12.10",
    "@babel/プリセット環境": "^7.12.11",
    "バベルローダー": "^8.2.2",
    "css-loader": "^5.0.1",
    "html-webpack-プラグイン": "^4.5.1",
    "vue-loader": "^15.9.6",
    "vue-style-loader": "^4.1.2",
    "vue-テンプレートコンパイラ": "^2.6.12",
    "ウェブパック": "^5.13.0",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  }
}

1.2 webpack.base.js の基本設定

// webpack によってパッケージ化されたエントリファイルは設定をエクスポートする必要があります // webpack webpack-cli
// @babel/core babel のコア モジュール // babel-loader は webpack と babel のブリッジです // @babel/preset-env は es6+ を低レベルの構文に変換します // vue-loader vue-template-compiler は .vue ファイルを解析してテンプレートをコンパイルします // vue-style-loader css-loader は CSS スタイルを解析してスタイル タグに挿入します。vue-style-loader はサーバー側のレンダリングをサポートします const path = require('path');
HtmlWebpackPlugin は 'html-webpack-plugin' を必要とします。
const VueLoaderPlugin = require('vue-loader/lib/plugin')
モジュール.エクスポート = {
    モード: '開発'、
    出力: {
        ファイル名: '[name].bundle.js' , // デフォルトは main、デフォルトは dist ディレクトリ パス: path.resolve(__dirname,'../dist')
    },
    モジュール: {
        ルール: [{
            テスト: /\.vue$/,
            使用: 'vue-loader'
        }, {
            テスト: /\.js$/,
            使用: {
                ローダー: 'babel-loader', // @babel/core -> preset-env
                オプション:
                    presets: ['@babel/preset-env'], // プラグインのコレクション}
            },
            exclude: /node_modules/ // node_modules の下のファイルを検索する必要がないことを示します}, {
            テスト: /\.css$/,
            使用方法: ['vue-style-loader', {
                ローダー: 'css-loader',
                オプション:
                    esModule: false, // vue-style-loaderは、
                }
            }] // 右から左へ実行します }]
    },
    プラグイン: [
        新しい VueLoaderPlugin() // 修正済み]
}

1.3 webpack.client.js構成はクライアント開発構成であり、通常のvue spa開発モード構成です。

const {merge} = require('webpack-merge');
定数 base = require('./webpack.base');
定数パス = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = merge(base,{
    エントリー: {
        クライアント:path.resolve(__dirname, '../src/client-entry.js')
    },
    プラグイン:[
        新しいHtmlWebpackプラグイン({
            テンプレート: path.resolve(__dirname, '../public/index.html'),
            ファイル名:'client.html'
            // デフォルト名はindex.htmlです
        })、
    ]
})

1.4 webpack.server.js 構成はパッケージ化後のサーバー展開に使用されます

定数 base = require('./webpack.base')
const {merge} = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin')
定数パス = require('path')
module.exports = merge(base,{
    ターゲット: 'ノード',
    エントリー: {
        server:path.resolve(__dirname, '../src/server-entry.js')
    },
    出力:{
        libraryTarget:"commonjs2" // module.exports export},
    プラグイン:[
        新しいHtmlWebpackプラグイン({
            テンプレート: path.resolve(__dirname, '../public/index.ssr.html'),
            ファイル名:'server.html',
            除外チャンク:['server'],
            縮小:false、
            クライアント:'/client.bundle.js'
            // デフォルト名はindex.htmlです
        })、
    ]
})

excludeChunks:['server']はserver.bundle.jsパッケージをインポートしません

クライアントは変数です
minifyは圧縮されません

ファイル名はパッケージ化後に生成されるHTMLファイルの名前です。

テンプレート: テンプレートファイル

2. HTMLファイルを書く

2人分:

2.1 パブリック/index.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
</head>
<本文>
    <div id="アプリ"></div>
</本文>
</html>

2.2 パブリック/index.ssr.html

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
</head>
<本文>
    <!--vue-ssr-outlet-->

    <!-- ejs テンプレート -->
    <script src="<%=htmlWebpackPlugin.options.client%>"></script>
</本文>
</html>
<!--vue-ssr-outlet--> は、サーバーがDOMをレンダリングするために使用する固定スロット位置です。<%=htmlWebpackPlugin.options.client%> は、htmlwebpackplugin の変数を埋めます。

3. 通常のVue開発に従って、対応するファイルを記述します。

app.jsファイルを定義する

src/app.js

エントリを関数に変換する目的は、サーバーがレンダリングされるたびにこのファクトリー関数を通じて新しいインスタンスを返し、訪問者全員が自分のインスタンスを取得できるようにすることです。

'vue' から Vue をインポートします。
'./App.vue' からアプリをインポートします。
'./router.js' から createRouter をインポートします。
'./store.js' から createStore をインポートします。
// エントリを関数に変換する目的は、サーバーがレンダリングされるたびにこのファクトリ関数を通じて新しいインスタンスを返すことです。これにより、訪問者全員が自分のインスタンスを取得できるようになります。 export default () => {
    定数ルーター = createRouter();
    定数ストア = createStore()
    constアプリ = 新しいVue({
        ルーター、
        店、
        レンダリング: h => h(App)
    });
    {アプリ、ルーター、ストア} を返します
}

src/app.vue

<テンプレート>
  <div id="アプリ">
    <router-link to="/">foo</router-link>
    <router-link to="/bar">バー</router-link>
    <ルータービュー></ルータービュー>
  </div>
</テンプレート>
<スクリプト>
デフォルトをエクスポートします {};
</スクリプト>

src/コンポーネント/Bar.vue

<テンプレート>
  <div>
    {{$store.state.name}}  
   
  </div>
</テンプレート>

<スタイル スコープ="true">
div {
  背景: 赤;
}
</スタイル>

<スクリプト>
エクスポートデフォルト{
    asyncData(store){ // メソッドはサーバー上で実行されますが、このメソッドはバックエンドで実行されます console.log('server call')
       // axios.get('/サーバーパス')
        Promise.resolve('success') を返します。
    },
    マウントされた(){ // ブラウザは実行し、バックエンドは無視します}
}
</スクリプト>

src/コンポーネント/Foo.vue

<テンプレート>
    <div @click="show">フード</div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
    方法:{
        見せる(){
            警告(1)
        }
    }
}
</スクリプト>

src/ルーター.js

'vue' から Vue をインポートします。
'vue-router' から VueRouter をインポートします。
'./components/Foo.vue' から Foo をインポートします。
'./components/Bar.vue' から Bar をインポートします。
Vue.use(VueRouter); // 2つのグローバルコンポーネントが内部的に提供されます Vue.component()


//サーバーにアクセスするすべての人がルーティングシステムを生成する必要があります export default ()=>{
    ルーター = new VueRouter({
        モード: '履歴',
        ルート:[
            {パス:'/',コンポーネント:Foo},
            {path:'/bar',component:Bar}, // 遅延読み込み。パス {path:'*',component:{ に従って対応するコンポーネントを動的に読み込みます。
                レンダリング:(h)=>h('div',{},'404')
            }}
        ]
    });
    リターンルーター;
}




//フロントエンドルーティングハッシュ履歴の2つの方法

// ハッシュ # 

// ルーティングとは、異なるパスに応じて異なるコンポーネントをレンダリングすることです。ハッシュ値の特徴は、ハッシュ値の変更によってページが再レンダリングされないことです。ハッシュ値の変更を監視して、対応するコンポーネントを表示できます(履歴を生成できます)。hashApi の特徴は、醜いことです(サーバーがハッシュ値を取得できない)

// historyApi H5 の API は美しいです。問題は、更新すると 404 が生成されることです。 

src/store.js

'vue' から Vue をインポートします。
'vuex' から Vuex をインポートします。

Vue.js で Vuex をビルドします。
// サーバー上の vuex を使用してグローバル変数 window にデータを保存し、サーバーによってレンダリングされたデータをブラウザによってレンダリングされたデータに置き換えます export default ()=>{
    ストア = 新しい Vuex.Store({
        州:{
            名前:'zhufeng'
        },
        突然変異:
            changeName(状態、ペイロード){
                state.name = ペイロード
            }
        },
        アクション:{
            changeName({commit}){// store.dispatch('changeName')
                新しい Promise を返します ((resolve,reject)=>{
                    タイムアウトを設定する(() => {
                        コミット('changeName','jiangwen');
                        解決する();
                    }, 5000);
                })
            }
        }

    });

    if(typeof window!='undefined' && window.__INITIAL_STATE__){
        // ブラウザがレンダリングを開始します // バックエンドのレンダリング結果をフロントエンドのコアメソッドに同期します vuex store.replaceState(window.__INITIAL_STATE__); // サーバーによってロードされたデータに置き換えます}
    返品ストア;
}

4. エントリファイルを定義する

クライアント パッケージのパッケージ エントリ ファイル:

src/client-entry.jsはクライアントのjsエントリファイルです

'./app.js' から createApp をインポートします。
app を createApp() します。
app.$mount('#app'); // クライアント側のレンダリングでは client-entry.js を直接使用できます

src/server-entry.js サーバーエントリファイル

サーバーからの要求に応じてサーバーによって実行される機能です。

// サーバーエントリ import createApp from './app.js';


// サーバー側レンダリングは関数を返すことができます export default (context) => { // サーバーはメソッドを呼び出すときに url 属性を渡します // このメソッドはサーバー上で呼び出されます // ルーティングは非同期コンポーネントなので、ここでルートが読み込まれるのを待つ必要があります const { url } = context;
    return new Promise((resolve, reject) => { // renderToString()
        let { app, router, store } = createApp(); // vue-router
        router.push(url); // 永続的なジャンプ/パスを示します router.onReady(() => { // ルートのジャンプが完了し、コンポーネントがトリガーする準備ができるまで待機します const matchComponents = router.getMatchedComponents(); // /abc


            if (matchComponents.length == 0) { //フロントエンドルートに一致しません return deny({ code: 404 });
            } それ以外 {
                // matchComponents はルートに一致するすべてのコンポーネント (ページレベルのコンポーネント) を参照します
                Promise.all(matchComponents.map(コンポーネント => {
                    if (component.asyncData) { // サーバーはレンダリング時にデフォルトでページレベルコンポーネント内のasyncDataを見つけ、サーバー上にvuexを作成してasyncDataに渡します。
                        コンポーネント.asyncData(store) を返します。
                    }
                })).then(()=>{ // デフォルトではウィンドウの下に変数が生成されます。これはデフォルトで実行されます // "window.__INITIAL_STATE__={"name":"jiangwen"}"
                    context.state = store.state; // サーバーが実行されると、最新の状態が store.state に保存されます。resolve(app); // app はデータを取得したインスタンスです。 })
            }
        })
    })



    // アプリは newVue に対応しており、ルーターによって管理されていません。ルーターがジャンプするまで待ってからサーバー側のレンダリングを実行したい // ユーザーが存在しないページにアクセスしたときに、フロントエンドのルートを一致させる方法 // 毎回新しいアプリケーションを生成できます}

// ユーザーが bar: にアクセスすると、サーバー側レンダリングがサーバー上で直接実行され、レンダリングされた結果がブラウザーに返されます。 ブラウザはjsスクリプトを読み込み、パスに従ってjsスクリプトを読み込み、バーを再レンダリングします。

component.asyncData は非同期リクエストです。リクエストが完了するまで待ってから、context.state = store.state; を設定します。この時点では " window.INITIAL_STATE = {"name": "jiangwen"}" です。
クライアントのストアは、 window.INITIAL_STATEを取得して再割り当てすることができます。

5. ノードでデプロイされたサーバー側のファイルserver.jsを定義し、対応するテンプレートファイルを要求します。

リクエスト処理にはkoaとkoa-routerを使用する

vue-server-rendererはサーバーサイドレンダリングに必須のパッケージです

Koa-staticはjsファイルなどの静的リソースのリクエストを処理します

serverBundleはパッケージ化されたjsです

テンプレートは、サーバエントリserver:buildの後にパッケージ化されたHTMLです。

const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
定数ルーター = 新しいルーター();
const VueServerRenderer = require('vue-server-renderer')
const static = require('koa-static')

定数 fs = require('fs');
定数パス = require('path')
定数 serverBundle = fs.readFileSync(path.resolve(__dirname, 'dist/server.bundle.js'), 'utf8')
const テンプレート = fs.readFileSync(path.resolve(__dirname, 'dist/server.html'), 'utf8');


// インスタンスに基づいてレンダラーを作成し、パッケージ化された js とテンプレートファイルを渡します。const render = VueServerRenderer.createBundleRenderer(serverBundle, {
    テンプレート
})

// localhost:3000/ へのリクエスト url パラメータ - 》 {url:ctx.url} に従って、それを serverBundle に渡すと、サーバー上のパッケージ化された .js ルーティング システムに従ってルートの完全な DOM 分解を含むページがレンダリングされます。router.get('/', async (ctx) => {
    console.log('ジャンプ')
    ctx.body = 新しい Promise((resolve, reject) => {を待ちます
        render.renderToString({url:ctx.url},(err, html) => { // CSS を有効にするには、コールバック メソッドのみを使用できます if (err) deny(err);
            解決(html)
        })
    })
    // const html = await render.renderToString(); // 文字列を生成する // console.log(html)
})

// ユーザーが存在しないサーバー パスにアクセスすると、ホームページに戻ります。フロントエンド js を介してレンダリングすると、コンポーネントはパスに従って再レンダリングされます。// ユーザーがリフレッシュする限り、サーバーにリクエストが送信されます。router.get('/(.*)', async (ctx)=>{
    console.log('ジャンプ')
    ctx.body = 新しい Promise((resolve, reject) => {を待ちます
        render.renderToString({url:ctx.url},(err, html) => { // サーバー側レンダリングによるレンダリング後に戻る if (err && err.code == 404) resolve(`not found`);
            コンソール.log(html)
            解決(html)
        })
    })
})


// クライアントがリクエストを送信すると、最初に dist ディレクトリを検索します。app.use(static(path.resolve(__dirname,'dist'))); // シーケンスの問題 app.use(router.routes());

// 静的ファイルを検索する前に、定義したルートを使用するようにしてください app.listen(3000);

5.1 localhost:3000/ へのリクエスト リクエスト URL パラメータ - 》 {url:ctx.url} に従って、それを serverBundle に渡すと、サーバー上のパッケージ化された .js ルーティング システムに従ってルートの完全な DOM 分解を含むページがレンダリングされます。

/に対応するコンポーネントはFooなので、ページにはFooが表示されます。



ウェブページのソースコードはDOMとして解析され、SEOに使用できます。

5.2 リクエストがhttp://localhost:3000/barの場合

ルートは/(.*)になります。

renderToStringはURLを渡します

行きます

server-entry.js ファイルのデフォルト関数も vue です。クライアントの本来のロジックをすべて含みますが、サーバー上で操作されます。

URLは/barです

ルート/barに従ってBarコンポーネントを削除します

ルーターは bar にジャンプし、ページは bar コンポーネントになります。

同時にasyncData関数を実行すると、ストアやその他のデータが書き換えられる可能性がある。

次に、context.state = store.state を割り当てて、ストアの状態オブジェクトをウィンドウに追加することを忘れないでください。

window.INITIAL_STATE = {"name":"jiangwen"}

store.js(window.INITIAL_STATE を再処理することを忘れないでください

store.replaceState( window.INITIAL_STATE )はサーバーの状態をクライアントに置くことです

dist/server.htmlがパッケージ化された後、/client.bundle.jsが導入されるので、静的リクエスト処理を行うにはkoa-staticが必要です。

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
</head>
<本文>
    <!--vue-ssr-outlet-->

    <!-- ejs テンプレート -->
    <script src="/client.bundle.js"></script>
</本文>
</html>

6. 展開

6.1 npm run run:allコマンドを実行する

"run:all": "同時に \"npm run client:build\" \"npm run server:build\""

js html などを含むクライアントおよびサーバーのリソース パッケージをパッケージ化します。

次にserver.js全体をサーバー上に置きます

node server.jsを実行してノードサーバーを起動します。

6.2 server.js で指定されている server.bundle.js と server.html を、対応するサーバー フォルダーに指定するだけです。

コマンドの説明

client:devは SPA レンダリング モードで開発され、SSR は考慮されず、通常の SPA デプロイメントには client.bundle.js と client.html が使用されます。
run:allサーバーサイドレンダリングモードは、クライアントとサーバーの両方をパッケージ化します

サーバー側で使用する場合、ブラウザでは client.bundle.js が使用され、サーバーでは server.bundle.js が使用されます。

7. まとめ

1. SSR にはまずノード サーバーと vue-server-renderer パッケージが必要です。

2. beforeMount またはマウントされたライフサイクルはサーバー側では使用できないことを考慮して、通常の Vue 開発を使用します。

3. server.jsを作成し、koaまたはexpressを設定してリクエスト解析を行い、serverBundleとテンプレートを

VueServerRenderer.createBundleRenderer 関数

レンダリングを取得する

4. render.renderToStringは、/barなどの要求されたルートを渡します。

5. この時、serverBundle のデフォルト関数 (server-entry.js パッケージから派生) に入り、vue インスタンス アプリを作成し、ルーティング vue インスタンスを分析してからルートをジャンプします。 この時、変更されたのはサーバー側の vue インスタンスのみで、ページにはまだ反映されていません。

6. 対応するコンポーネントの asyncData 関数を実行します。これにより、store.state が変更される可能性があります。次に、その値を context.state に割り当てます。

7.resolve(app) このとき、server.js 内の render は、現時点での vue インスタンス app のルーティング状態に応じて DOM を解析し、ページに返します。ctx.body = ...resolve(html);

8. この時点で、ページは通常のルーティングマッチング後のDOM構造を取得します。

9. html にウィンドウが表示されます。INITIAL_STATE ={"name":"zhufeng"} は、サーバーストア ステータスを記録することと同じです。

10. クライアントがストアを実行すると、実際にはサーバー上の状態は変更されません。store.replaceState( window.INITIAL_STATE ); を実行して、サーバー上の状態を置き換えます。

11. 全体的な状況としては、サーバーとクライアントの両方に js パッケージがあります。事前にサーバー上で js パッケージを実行し、dom を解析して表示します。サーバーは終了し、残りのロジックはクライアントの js によって処理されます。

コンセプトマップ

公式サイト:

  • vue-server-renderer と vue のバージョンが一致している必要があります。
  • vue-server-renderer はいくつかの Node.js ネイティブ モジュールに依存しているため、Node.js でのみ使用できます。将来的には、他の JavaScript ランタイムで実行できる、よりシンプルなビルドを提供する予定です。

要約する

これで、vue の ssr サーバーサイドレンダリングに関するこの記事は終了です。vue ssr サーバーサイドレンダリングに関するその他の関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue で vue-router を使用する手順 (ssr での使用を含む)
  • vuecli プロジェクトに組み込まれた SSR サーバーサイドレンダリングの実装
  • vue-ssr プロジェクトの構築方法
  • Vue で SSR の代わりにプリレンダリングを使用する方法
  • Vue SSR ジャストインタイムコンパイル技術の実装
  • VueSSRの理解と詳細な設定

<<:  win10 での mysql5.7.21 の詳細なインストール手順

>>:  Nginx のアンチホットリンクを設定する方法

推薦する

VMware Workstation Pro でサーバー仮想マシンを構築する (グラフィック チュートリアル)

私が使用している VMware Workstation Pro のバージョンは次のとおりです。 1....

Dockerデータのバックアップとリカバリプロセスの詳細な説明

データのバックアップ操作は非常に簡単です。次のコマンドを実行します。 docker run --vo...

ウェブページの右下隅に「いいね!」カード効果を実現するための CSS (サンプルコード)

効果 HTML を実装するには、まずクリーンな HTML ページを準備し、ノードを記述します。 &l...

Linux で Redis のリモート接続を実装する方法

LinuxにRedisをインストールしたら、Javaを使って接続します。Javaコードは次のとおりで...

MySQL マスタースレーブレプリケーションの原理からインストールと設定までを包括的に解説します。

マスタースレーブレプリケーションがなぜ必要なのでしょうか? 1. 複雑な業務システムでは、SQL 文...

VMWare 仮想マシン 15.X LAN ネットワーク構成チュートリアル図

最近、分散型およびビッグデータ技術について学ぶために、いくつかの仮想マシンに取り組んでいます。まず、...

4 つの主要な SQL ランキング関数 ROW_NUMBER、RANK、DENSE_RANK、NTILE の使用方法の紹介

1. ROW_NUMBER()定義: ROW_NUMBER() 関数は、select によってクエリ...

uniapp プロジェクトの最適化方法と提案

目次1. 複雑なページデータ領域をコンポーネントにカプセル化する2. 大きな画像の使用を避ける3. ...

アルバムと写真をアルバムに保存するためのWeChatアプレット

私は現在、Xiao Nian Gao に似たビデオおよびツール アプリを開発しています。ユーザーが作...

Vueのカスタムイベントコンテンツ配信の詳細な説明

1. これは理解するのが少し複雑なので、原理を注意深く読んで自分で入力していただければ幸いです。 &...

HTML テーブルタグチュートリアル (20): 行の背景色属性 BGCOLOR

BGCOLOR 属性を使用して、行の背景色を設定できます。基本的な構文<TR BGcolor...

CentOS7 で Jenkins+Maven+Git 継続的インテグレーション環境を構築する方法

この記事では、Spring boot + Maven プロジェクトのデプロイメントを例に、Code ...

DockerコンテナでJupyterノートブックを設定する方法

Jupyter ノートブックは、主に Python コードの記述、より具体的にはディープラーニング開...

Nginxの書き換えモジュールの詳細な説明

書き換えモジュールは ngx_http_rewrite_module モジュールです。その主な機能は...