-
Notifications
You must be signed in to change notification settings - Fork 9
Translate build-config.md via GitLocalize #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
# ビルド設定 | ||
|
||
クライアントサイドで完結するプロジェクトのwebpack設定は既に知っての通りでしょう。 SSRプロジェクトにおいても大枠は似たようなものですが、設定ファイルを3つのファイル( *ベース*、 *クライアント* 、 *サーバ* )に分けることを提案しています。 ベース設定は出力パス、エイリアス、ローダーのような両方の環境(TO DO:どれとどれ?)に共有される設定を含み、サーバ設定とクライアント設定は単純に、 [webpack-merge](https://github.com/survivejs/webpack-merge)を使って、ベース設定を拡張することができるものです。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
## サーバ設定 | ||
|
||
サーバ設定は`createBundleRenderer`に渡されるサーババンドルを生成するために作られるもので、次のようになります: | ||
|
||
```js | ||
const merge = require('webpack-merge') | ||
const nodeExternals = require('webpack-node-externals') | ||
const baseConfig = require('./webpack.base.config.js') | ||
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin') | ||
module.exports = merge(baseConfig, { | ||
// Point entry to your app's server entry file | ||
entry: '/path/to/entry-server.js', | ||
// This allows webpack to handle dynamic imports in a Node-appropriate | ||
// fashion, and also tells `vue-loader` to emit server-oriented code when | ||
// compiling Vue components. | ||
target: 'node', | ||
// For bundle renderer source map support | ||
devtool: 'source-map', | ||
// This tells the server bundle to use Node-style exports | ||
output: { | ||
libraryTarget: 'commonjs2' | ||
}, | ||
// https://webpack.js.org/configuration/externals/#function | ||
// https://github.com/liady/webpack-node-externals | ||
// Externalize app dependencies. This makes the server build much faster | ||
// and generates a smaller bundle file. | ||
externals: nodeExternals({ | ||
// do not externalize dependencies that need to be processed by webpack. | ||
// you can add more file types here e.g. raw *.vue files | ||
// you should also whitelist deps that modifies `global` (e.g. polyfills) | ||
whitelist: /\.css$/ | ||
}), | ||
// This is the plugin that turns the entire output of the server build | ||
// into a single JSON file. The default file name will be | ||
// `vue-ssr-server-bundle.json` | ||
plugins: [ | ||
new VueSSRServerPlugin() | ||
] | ||
}) | ||
``` | ||
|
||
`vue-ssr-server-bundle.json`が生成されたら、ファイルパスを `createBundleRenderer`に渡すだけです: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
```js | ||
const { createBundleRenderer } = require('vue-server-renderer') | ||
const renderer = createBundleRenderer('/path/to/vue-ssr-server-bundle.json', { | ||
// ...other renderer options | ||
}) | ||
``` | ||
|
||
別の方法として、 バンドルをオブジェクトとして`createBundleRenderer`に渡すことも可能で、これはホットリロード開発中に有効です。 参考として [HackerNewsの設定](https://github.com/vuejs/vue-hackernews-2.0/blob/master/build/setup-dev-server.js) を見てみてください。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
### 外部警告 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
CSSファイルを`externals`オプションにホワイトリスト登録していることに注目してください。その理由は、依存関係からインポートされるCSS はwebpackによって管理されないといけないからです。 もし同じようにwebpackに依存する他のタイプのファイルをインポートしているなら、 (例: `*.vue`, `*.sass`)、 それらも同じようにホワイトリストに加えなければいけません。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
ホワイトリスト登録する他のタイプのモジュールは、例えば `babel-polyfill`のような`global`を修正するポリフィルです。なぜなら、サーババンドルの中のコードは独自の ** `global` **オブジェクトを持っているからです。Node 7.6+を使っていればサーバに`babel-polyfill`はあまり必要ないので、単純にクライアントエントリーにインポートする方が簡単です。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
## クライアント設定 | ||
|
||
クライアント設定はベース設定とほぼ同じままです。言うまでもなく、クライアント側のエントリーファイルに`entry`を示す必要があります。またそれとは別に、もし`CommonsChunkPlugin`使っていたら、それがクライアント設定だけで使われていることを確認しておかないといけません。なぜなら、サーババンドルは単一のエントリーチャンクを要求するからです。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
### `clientManifest` の作成 | ||
|
||
> 必須 version 2.3.0+ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
サーババンドルに加えて、クライアントビルドマニフェストを作成することもできます。レンダラーは、クライアントマニフェストとサーババンドルでサーバ 側*と*クライアント側の両方のビルド情報を持つことになり、 レンダーされたHTMLに[preload / prefetch directives](https://css-tricks.com/prefetching-preloading-prebrowsing/)やCSSのlinkやscriptタグを自動的に挿入することができます。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
これには2重の恩恵があります: | ||
|
||
1. 生成されたファイル名にハッシュがある時に、正しいURLをセットする`html-webpack-plugin` の代替になります。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
2. webpackのオンデマンドコード分割機能を利用するバンドルをレンダリングする時に、最適なチャンクがpreloaded / prefetchedされるのを保証でき、かつ、クライアントに対するウォーターフォールリクエストを避けるために、必要な非同期チャンクに`<script></script>`タグを挿入することができます。そのようにしてTTI (time-to-interactive)が改善します。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
クライアントマニフェストを利用するためには、クライアント設定はこのようになります: | ||
|
||
```js | ||
const webpack = require('webpack') | ||
const merge = require('webpack-merge') | ||
const baseConfig = require('./webpack.base.config.js') | ||
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin') | ||
module.exports = merge(baseConfig, { | ||
entry: '/path/to/entry-client.js', | ||
plugins: [ | ||
// Important: this splits the webpack runtime into a leading chunk | ||
// so that async chunks can be injected right after it. | ||
// this also enables better caching for your app/vendor code. | ||
new webpack.optimize.CommonsChunkPlugin({ | ||
name: "manifest", | ||
minChunks: Infinity | ||
}), | ||
// This plugins generates `vue-ssr-client-manifest.json` in the | ||
// output directory. | ||
new VueSSRClientPlugin() | ||
] | ||
}) | ||
``` | ||
|
||
これで、作成されたクライアントマニフェストをページテンプレートと一緒に利用できるようになります。 | ||
|
||
```js | ||
const { createBundleRenderer } = require('vue-server-renderer') | ||
const template = require('fs').readFileSync('/path/to/template.html', 'utf-8') | ||
const serverBundle = require('/path/to/vue-ssr-server-bundle.json') | ||
const clientManifest = require('/path/to/vue-ssr-client-manifest.json') | ||
const renderer = createBundleRenderer(serverBundle, { | ||
template, | ||
clientManifest | ||
}) | ||
``` | ||
|
||
この設定で、コード分割されたビルドのためにサーバ側でレンダリングされるHTMLはこのようになります(すべて自動でインジェクトされます)。 | ||
|
||
```html | ||
|
||
|
||
<!-- chunks used for this render will be preloaded --> | ||
<link rel="preload" href="/manifest.js" as="script"> | ||
<link rel="preload" href="/main.js" as="script"> | ||
<link rel="preload" href="/0.js" as="script"> | ||
<!-- unused async chunks will be prefetched (lower priority) --> | ||
<link rel="prefetch" href="/1.js" as="script"> | ||
|
||
|
||
<!-- app content --> | ||
<div data-server-rendered="true"><div data-segment-id="282354">async</div></div> | ||
<!-- manifest chunk should be first --> | ||
<script src="/manifest.js"></script> | ||
<!-- async chunks injected before main chunk --> | ||
<script src="/0.js"></script> | ||
<script src="/main.js"></script> | ||
|
||
` | ||
``` | ||
|
||
### 手動でのアセットインジェクション | ||
|
||
デフォルト設定で、アセットインジェクションはあなたが作成した`template`レンダーオプションで自動に行われます。 しかし、アセットがどのようにテンプレートにインジェクトされるかをより細かくコントロールしたい時もあるでしょうし、あるいはテンプレートを使わない時もあるかもしれません。そのような場合にはレンダラーを作る時に`inject: false`を渡せば、手動でアセットインジェクションを行うことができます。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
渡した`context`オブジェクトは`renderToString`コールバックで、 次のメソッドを持ちます: | ||
|
||
- `context.renderStyles()` | ||
|
||
これは、レンダー中に使われた`*.vue`コンポーネントから集めた全てのクリティカルCSSを含んだ`<style></style>` タグを返します。詳細は [CSS Management](./css.md)の章を見てください。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
もし `clientManifest` が提供されたら、返ってきたストリングはwebpackが放出したCSSファイルの`<link rel="stylesheet">`タグも含みます。 (例 : `extract-text-webpack-plugin`から抽出されたCSSや、`file-loader`でインポートされたCSS) | ||
|
||
- `context.renderState(options?: Object)` | ||
|
||
このメソッドは `context.state` をシリアライズし、 `window.__INITIAL_STATE__`ステートとして埋め込まれたインラインスクリプトを返します。 | ||
|
||
contextのステートキーとwindowのステートキーはどちらとも、オプションオブジェクトとして渡すことでカスタマイズできます。 | ||
|
||
```js | ||
context.renderState({ | ||
contextKey: 'myCustomState', | ||
windowKey: '__MY_STATE__' | ||
}) | ||
// -> <script>window.__MY_STATE__={...}</script> | ||
``` | ||
|
||
- `context.renderScripts()` | ||
- 必須 `clientManifest` | ||
|
||
このメソッドはクライアントアプリケーションを起動するのに必要な ` <script></script>` タグを返します。コードの中に非同期コード分割を使っている時、このメソッドは賢くも、インクルードされるべき正しい非同期チャンクを察します。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
- `context.renderResourceHints()` | ||
- 必須 `clientManifest` | ||
|
||
このメソッドは、今レンダーされているページに必要な`<link rel="preload/prefetch">` リソースヒントを返します。 デフォルト設定このようになります: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
- ページに必要なJavaScriptやCSSファイルをプリロードする | ||
- あとで必要な非同期JavaScriptチャンクをプリフェッチする | ||
|
||
ファイルのプリロードは[`shouldPreload`](./api.md#shouldpreload) オプションによってさらにカスタマイズが可能です。 | ||
|
||
- `context.getPreloadFiles()` | ||
- 必須 `clientManifest` | ||
|
||
このメソッドはストリングを返さない代わりに、プリロードされるべきアセットを表すファイルオブジェクトの配列を返します。これは HTTP/2サーバプッシュをプログラムで行うときに使えるでしょう。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
`createBundleRenderer`に渡された`template`は`context`を使って挿入されるので、これらのメソッドをテンプレート内で(`inject: false`で)使用することができます: | ||
|
||
```html | ||
|
||
|
||
<!-- use triple mustache for non-HTML-escaped interpolation --> | ||
{{{ renderResourceHints() }}} | ||
{{{ renderStyles() }}} | ||
|
||
|
||
<!--vue-ssr-outlet--> | ||
{{{ renderState() }}} | ||
{{{ renderScripts() }}} | ||
|
||
|
||
``` | ||
|
||
もし `template` を全く使っていないのなら、自分自身でストリングを結合することができます。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ここもですね。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base, client and server
を*ベース*、 *クライアント* 、 *サーバ*
と訳していますが、vue-ssr-docs
では、それら3つは原文のまま(base, client, server)にしておいた方がいいでしょう。実際、vueのSSRのexample的なvue-hackernews-2.0においては、この通りに設定が別れているので、参照したときに分かりやすいので。なので、
ベース
、クライント
、サーバ
は、この文章においては、base
、client
、server
にしておきましょう!