webpack4 配置 ssr 环境遇到“document is not defined”

最近使用 webpack 4 配置 ssr 环境,发现的问题:

ReferenceError: document is not defined

本次package.json使用版本信息:

{

"vue-loader": "^15.4.2",

"mini-css-extract-plugin": "^0.4.3",

"webpack": "^4.20.2",

"webpack-cli": "^3.1.2"

...

}

相关代码

问题原因:

在服务端渲染打包的配置中使用了mini-css-extract-plugin是的server bundle中会使用到document,node环境中不存在window对象,所以报错。

解决办法:

在webpack.base.config.js中不配置样式相关的loader:

# 基本配置

const path = require('path')

const webpack = require('webpack')

const {VueLoaderPlugin} = require('vue-loader')

const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

const resolve = dir => path.join(__dirname, '../', dir)

const isProd = process.env.NODE_ENV === 'production'

const base = {

mode: isProd ? 'production' : 'development',

devtool: isProd ? false : 'cheap-eval-source-map',

output: {

path: path.resolve(__dirname, '../dist'),

publicPath: '/dist/',

filename: '[name].[chunkhash].js'

},

resolve: {

alias: {

'vue$': 'vue/dist/vue.esm.js',

'public': path.resolve(__dirname, '../public')

}

},

module: {

noParse: /es6-promise\.js$/, // avoid webpack shimming process

rules: [

{

test: /\.vue$/,

loader: 'vue-loader',

include: resolve("src")

},

{

test: /\.js$/,

loader: 'babel-loader',

exclude: file => (

/node_modules/.test(file) && !/\.vue\.js/.test(file)

)

},

{

test: /\.(png|jpg|gif|svg)$/,

loader: 'url-loader',

options: {

limit: 10000,

name: '[name].[ext]?[hash]'

}

}

]

},

plugins: setPlugin()

}

function setPlugin() {

const base = [new VueLoaderPlugin()]

const dev = [new FriendlyErrorsPlugin()]

const prod = []

return base.concat(isProd ? prod : dev)

}

module.exports = base;

在webpack.client.config.js中使用mini-css-extract-plugin:

# 只展示先关配置

const webpack = require('webpack')

const merge = require('webpack-merge')

const base = require('./webpack.base.config')

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')

const isProd = process.env.NODE_ENV === 'production'

const config = merge(base, {

module: {

rules: [

{

test: /\.styl(us)?$/,

use: [

isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',

{

loader: 'css-loader'

},

'stylus-loader'

],

},

{

test: /\.(le|c)ss$/,

use: [

isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',

{

loader: 'css-loader'

},

'less-loader',

],

}

]

},

plugins: [

new MiniCssExtractPlugin({

filename: isProd ? '[name].[chunkhash].css' : '[name].css',

chunkFilename: isProd ? '[id].[chunkhash].css': '[id].css',

}),

new VueSSRClientPlugin()

]

})

module.exports = config

在webpack.server.config.js中不使用mini-css-extract-plugin:

# 只展示先关配置

const webpack = require('webpack')

const merge = require('webpack-merge')

const base = require('./webpack.base.config')

const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')

module.exports = merge(base, {

target: 'node',

module: {

rules: [

{

test: /\.styl(us)?$/,

use: [

'vue-style-loader',

{

loader: 'css-loader'

},

'stylus-loader'

],

},

{

test: /\.(le|c)ss$/,

use: [

'vue-style-loader',

{

loader: 'css-loader'

},

'less-loader',

],

}

]

},

plugins: [

new VueSSRServerPlugin()

]

})

参考Demo:

tiodot/vnews

相关issues:

vue-loader@15.0.0-rc.1 in a server bundle

webpack-contrib/mini-css-extract-plugin

结语:

由于本次webpack4版本比较新,周边的插件没能及时做出相应更新;

相信经过社区的不断努力,整个生态会更加健壮。

以上是 webpack4 配置 ssr 环境遇到“document is not defined” 的全部内容, 来源链接: utcz.com/z/312352.html

回到顶部