vue的ssr在生产环境中依然执行了客户端和服务端代码的比较,导致页面加载了两次

发布于 2022-09-11 23:07:28 字数 4626 浏览 24 评论 0

image.png
请问在官方文档中,这里的生产模式是通过什么去判断的?是通过process.env.NODE_ENV吗?另外,如果server side和client side渲染出来的dom节点属性顺序不一致,是否会被判定为dismatch,如图:
image.png

本项目基于vue-cli3,vue.config.js如下
`const path = require('path')
const webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const CopyWebpackPlugin = require('copy-webpack-plugin')
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
const nodeExternals = require('webpack-node-externals')

function resolve (dir) {
return path.join(__dirname, './' + dir)
}

const isProd = process.env.NODE_ENV === 'production'
const isServerEntry = process.env.VUE_ENV === 'server'
module.exports = {
pages: {

index: {
  entry: './src/' + process.env.VUE_ENV + '-entry.js'
}

},
// 基本路径
publicPath: '/',
assetsDir: 'static',
// 输出文件目录
outputDir: 'dist',
// eslint-loader 是否在保存的时候检查
lintOnSave: true,
chainWebpack: config => {

config.mode(process.env.NODE_ENV)
// config.entry('index').add('babel-polyfill')
config.module
  .rule('images')
  .use('url-loader')
  .loader('url-loader')
  .tap(options =>
    Object.assign(options, {
      limit: 100
    })
  )
//务必添加 https://github.com/vuejs/vue-loader/issues/885
config.module
  .rule("vue")
  .use("vue-loader")
  .tap(options => {
    Object.assign(options, {
      optimizeSSR: false,
      extractCSS: isProd && !isServerEntry
    });
  });
if (isProd) {
  //<!--vue-ssr-outlet-->在不能够在构建的过程中被删去
  config
    .plugin('html-index')
    .tap(args => {
      args[0].minify.removeComments = false
      return args
    })
  if(isServerEntry) {
    //务必添加 https://github.com/vuejs/vue/issues/8488
    config.optimization.delete('splitChunks')
  }
}

},
configureWebpack: config => {

let options = {
  mode: process.env.NODE_ENV,
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src')
    }
  },
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/),
    new CopyWebpackPlugin([
      {
        from: './src/copy',
        to: 'static/'
      }
    ]),
    new VueSSRClientPlugin()
  ]
}
if(isServerEntry) {
  Object.assign(options, {
    target: 'node',

    // 对 bundle renderer 提供 source map 支持
    devtool: 'source-map',
  
    // 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports)
    output: {
      libraryTarget: 'commonjs2'
    },
  
    // https://webpack.js.org/configuration/externals/#function
    // https://github.com/liady/webpack-node-externals
    // 外置化应用程序依赖模块。可以使服务器构建速度更快,
    // 并生成较小的 bundle 文件。
    externals: nodeExternals({
      // 不要外置化 webpack 需要处理的依赖模块。
      // 你可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件,
      // 你还应该将修改 `global`(例如 polyfill)的依赖模块列入白名单
      whitelist: /\.css$/
    }),
    // 这是将服务器的整个输出
    // 构建为单个 JSON 文件的插件。
    // 默认文件名为 `vue-ssr-server-bundle.json`
    plugins: [
      new VueSSRServerPlugin()
    ]
  })
}
if (process.env.VUE_APP_ENV === 'ana') {
  options.plugins.push(new BundleAnalyzerPlugin())
}
return options

},
// 生产环境是否生成 sourceMap 文件
productionSourceMap: true,
// css相关配置
css: {

// 是否使用css分离插件 ExtractTextPlugin
// CSS 提取应该只用于生产环境, 但是服务器端不能提取,否则会报[vue-router] Failed to resolve async component default: ReferenceError: document is not defined
// 这样我们在开发过程中仍然可以热重载
extract: isProd && !isServerEntry,
// 开启 CSS source maps?
// 需要注意,css是否开启sourcemap和js是否开启sourcemap必须保持一致,参考https://github.com/vuejs/vue/issues/9488
sourceMap: isProd,
// css预设器配置项
loaderOptions: {
  css: {
    onlyLocals: isProd && isServerEntry
  },
  less: {
    javascriptEnabled: true
  }
},
// 启用 CSS modules for all css / pre-processor files.
modules: false

},
pluginOptions: {

'style-resources-loader': {
  preProcessor: 'scss',
  patterns: [path.resolve(__dirname, './src/styles/variable.scss')]
},
proxy: {
  enabled: true,
  context: [
    '/**',
    '!/**.json',
    '!/**.js',
    '!/static/**',
    '!/favicon.ico'
  ],
  options: {
    target: 'http://127.0.0.1:9000'
  }
}

},
devServer: {

hotOnly: true,
disableHostCheck: true,
// open: true, // 配置自动启动浏览器
writeToDisk: true,

}
}
`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文