Skip to content

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

Merged
merged 3 commits into from
Jun 6, 2017
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 202 additions & 0 deletions ja/build-config.md
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)を使って、ベース設定を拡張することができるものです。
Copy link
Collaborator

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においては、この通りに設定が別れているので、参照したときに分かりやすいので。

なので、ベースクライントサーバは、この文章においては、baseclientserverにしておきましょう!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

両方の環境(TO DO:どれとどれ?) ですが、client と server ですね。client と server 両方の環境 と訳しておいた方がユーザーフレンドリーでいいと思います。


## サーバ設定

サーバ設定は`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`に渡すだけです:
Copy link
Collaborator

Choose a reason for hiding this comment

The 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) を見てみてください。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはホットリロード開発中に有効です。ではなく、これは開発中のホットリロードに対して便利です。の方が原文どおりの訳になるので、このように訳しましょう!


### 外部警告
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Externals Caveatsの訳ですが、webpackの externals オプションについてなので、ここでは、そのまま externalsにしておきましょう!

Caveats については、警告というより、注意 の方が内容的に分かりやすいと思います。


CSSファイルを`externals`オプションにホワイトリスト登録していることに注目してください。その理由は、依存関係からインポートされるCSS はwebpackによって管理されないといけないからです。 もし同じようにwebpackに依存する他のタイプのファイルをインポートしているなら、 (例: `*.vue`, `*.sass`)、 それらも同じようにホワイトリストに加えなければいけません。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handled管理される としていますが、ここでは 処理されるでしょうか。


ホワイトリスト登録する他のタイプのモジュールは、例えば `babel-polyfill`のような`global`を修正するポリフィルです。なぜなら、サーババンドルの中のコードは独自の ** `global` **オブジェクトを持っているからです。Node 7.6+を使っていればサーバに`babel-polyfill`はあまり必要ないので、単純にクライアントエントリーにインポートする方が簡単です。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node 7.6+Node 7.6 以降の方が読み手に分かりやいですね。


## クライアント設定

クライアント設定はベース設定とほぼ同じままです。言うまでもなく、クライアント側のエントリーファイルに`entry`を示す必要があります。またそれとは別に、もし`CommonsChunkPlugin`使っていたら、それがクライアント設定だけで使われていることを確認しておかないといけません。なぜなら、サーババンドルは単一のエントリーチャンクを要求するからです。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

クライアント設定はベース設定 は最初でコメントしたとおり、ここでは client 設定は base 設定 にしておきましょう!


### `clientManifest` の作成

> 必須 version 2.3.0+
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2.3.0+2.3.0以降にしましょう!


サーババンドルに加えて、クライアントビルドマニフェストを作成することもできます。レンダラーは、クライアントマニフェストとサーババンドルでサーバ 側*と*クライアント側の両方のビルド情報を持つことになり、 レンダーされたHTMLに[preload / prefetch directives](https://css-tricks.com/prefetching-preloading-prebrowsing/)やCSSのlinkやscriptタグを自動的に挿入することができます。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

レンダーされたレンダリングされたにしておきましょう!


これには2重の恩恵があります:

1. 生成されたファイル名にハッシュがある時に、正しいURLをセットする`html-webpack-plugin` の代替になります。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

injectingセットではなく、ここでは原文に従って注入するにしておきましょう!

2. webpackのオンデマンドコード分割機能を利用するバンドルをレンダリングする時に、最適なチャンクがpreloaded / prefetchedされるのを保証でき、かつ、クライアントに対するウォーターフォールリクエストを避けるために、必要な非同期チャンクに`<script></script>`タグを挿入することができます。そのようにしてTTI (time-to-interactive)が改善します。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

オンデマンドコード分割機能は括弧注釈としてwebpackでよく使われる(code spliting)という用語を入れておきましょう!


クライアントマニフェストを利用するためには、クライアント設定はこのようになります:

```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`を渡せば、手動でアセットインジェクションを行うことができます。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

render optionレンダーオプションではなく、レンダリングオプションとしておいてください。


渡した`context`オブジェクトは`renderToString`コールバックで、 次のメソッドを持ちます:

- `context.renderStyles()`

これは、レンダー中に使われた`*.vue`コンポーネントから集めた全てのクリティカルCSSを含んだ`<style></style>` タグを返します。詳細は [CSS Management](./css.md)の章を見てください。
Copy link
Collaborator

Choose a reason for hiding this comment

The 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>` タグを返します。コードの中に非同期コード分割を使っている時、このメソッドは賢くも、インクルードされるべき正しい非同期チャンクを察します。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<script></script> に先頭にスペースが入っているので除去お願いします!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

infer察しますというよりは、プログラミング言語で一般的に使われる推論するの方がいいかと分かりやすいですね。


- `context.renderResourceHints()`
- 必須 `clientManifest`

このメソッドは、今レンダーされているページに必要な`<link rel="preload/prefetch">` リソースヒントを返します。 デフォルト設定このようになります:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今レンダーより現在レンダリングの方が分かりやすいと思います。


- ページに必要なJavaScriptやCSSファイルをプリロードする
- あとで必要な非同期JavaScriptチャンクをプリフェッチする

ファイルのプリロードは[`shouldPreload`](./api.md#shouldpreload) オプションによってさらにカスタマイズが可能です。

- `context.getPreloadFiles()`
- 必須 `clientManifest`

このメソッドはストリングを返さない代わりに、プリロードされるべきアセットを表すファイルオブジェクトの配列を返します。これは HTTP/2サーバプッシュをプログラムで行うときに使えるでしょう。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ストリングより、stringの方が一般的ですので、そちらでお願いします!


`createBundleRenderer`に渡された`template`は`context`を使って挿入されるので、これらのメソッドをテンプレート内で(`inject: false`で)使用することができます:

```html


<!-- use triple mustache for non-HTML-escaped interpolation -->
{{{ renderResourceHints() }}}
{{{ renderStyles() }}}


<!--vue-ssr-outlet-->
{{{ renderState() }}}
{{{ renderScripts() }}}


```

もし `template` を全く使っていないのなら、自分自身でストリングを結合することができます。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもですね。
ストリングではなくstringでお願いします!