vue的ssr在生产环境中依然执行了客户端和服务端代码的比较,导致页面加载了两次
请问在官方文档中,这里的生产模式是通过什么去判断的?是通过process.env.NODE_ENV吗?另外,如果server side和client side渲染出来的dom节点属性顺序不一致,是否会被判定为dismatch,如图:
本项目基于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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论