text: import {createApp} from './app'
  
  const isDev = process.env.NODE_ENV !== 'production'
  
  // This exported function will be called by `bundleRenderer`.
  // This is where we perform data-prefetching to determine the
  // state of our application before actually rendering it.
  // Since data fetching is async, this function is expected to
  // return a Promise that resolves to the app instance.
  export default context => {
    return new Promise((resolve, reject) => {
      // 时间戳
      const s = isDev && Date.now();
      const {app, router, store} = createApp();
      // 请求的url
      const {url} = context;
      // 和vue的router去匹配
      const {fullPath} = router.resolve(url).route;
      // 如果没有匹配
      if (fullPath !== url) {
        return reject({url: fullPath})
      }
      // 修改vue的router
      // set router's location
      router.push(url);
  
      // wait until router has resolved possible async hooks
      router.onReady(() => {
        // 匹配的vm
        const matchedComponents = router.getMatchedComponents()
  
        // console.log(matchedComponents)
        // 没有匹配路由
        if (!matchedComponents.length) {
          return reject({code: 404})
        }
        // 对所有匹配的路由组件调用 `asyncData()`
        Promise.all(matchedComponents.map(({asyncData}) => asyncData && asyncData({
          store,
          route: router.currentRoute
        }))).then(() => {
          isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`)
          // 在所有预取钩子(preFetch hook) resolve 后，
          // 我们的 store 现在已经填充入渲染应用程序所需的状态。
          // 当我们将状态附加到上下文，
          // 并且 `template` 选项用于 renderer 时，
          // 状态将自动序列化为 `window.__INITIAL_STATE__`，并注入 HTML。
          context.state = store.state;
          resolve(app)
        }).catch(reject)
      }, reject)
    })
  }
  