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


Posted in Javascript onOctober 24, 2019

最近使用 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版本比较新,周边的插件没能及时做出相应更新;

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
CSDN轮换广告图片轮换效果
Mar 27 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
Apr 02 Javascript
jQuery中验证表单提交方式及序列化表单内容的实现
Jan 06 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
初步了解javascript面向对象
Nov 09 Javascript
初步使用Node连接Mysql数据库
Mar 03 Javascript
jquery radio的取值_radio的选中_radio的重置方法
Sep 20 Javascript
在localStorage中存储对象数组并读取的方法
Sep 24 Javascript
从0开始学Vue
Oct 27 Javascript
浅谈对Angular中的生命周期钩子的理解
Jul 31 Javascript
微信小程序搜索框样式并实现跳转到搜索页面(小程序搜索功能)
Mar 10 Javascript
Nuxt的路由动画效果案例
Nov 06 Javascript
vue项目使用.env文件配置全局环境变量的方法
Oct 24 #Javascript
微信小程序上传图片并等比列压缩到指定大小的实例代码
Oct 24 #Javascript
nest.js 使用express需要提供多个静态目录的操作方法
Oct 24 #Javascript
Vue 3.0双向绑定原理的实现方法
Oct 23 #Javascript
JavaScript判断数组类型的方法
Oct 23 #Javascript
Vue 2.0双向绑定原理的实现方法
Oct 23 #Javascript
p5.js绘制旋转的正方形
Oct 23 #Javascript
You might like
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
PHP中英混合字符串截取函数代码
2011/07/17 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
快速保存网页中所有图片的方法
2006/06/23 Javascript
window.location.hash 属性使用说明
2010/03/20 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
js改变文章字体大小的实例代码
2013/11/27 Javascript
js 设置缓存及获取设置的缓存
2014/05/08 Javascript
使用正则表达式的格式化与高亮显示json字符串
2014/12/03 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
2016/06/03 Javascript
JavaScript中清空数组的方法总结
2016/12/02 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
jquery网页加载进度条的实现
2017/06/01 jQuery
mpvue将vue项目转换为小程序
2018/09/30 Javascript
JointJS流程图的绘制方法
2018/12/03 Javascript
typescript配置alias的详细步骤
2020/08/12 Javascript
[01:05:56]2018DOTA2亚洲邀请赛3月29日 小组赛A组 Newbee VS VG
2018/03/30 DOTA
[13:25]VP vs VICI (BO3)
2018/06/07 DOTA
Python判断值是否在list或set中的性能对比分析
2016/04/16 Python
Python实现二维数组输出为图片
2018/04/03 Python
win8.1安装Python 2.7版环境图文详解
2019/07/01 Python
如何利用Python模拟GitHub登录详解
2019/07/15 Python
python3 dict ndarray 存成json,并保留原数据精度的实例
2019/12/06 Python
详解Python的三种拷贝方式
2020/02/11 Python
python实现AHP算法的方法实例(层次分析法)
2020/09/09 Python
python两种注释用法的示例
2020/10/09 Python
印度化妆品购物网站:Nykaa
2018/07/22 全球购物
学雷锋树新风演讲稿
2014/05/10 职场文书
我的中国梦演讲稿800字
2014/08/19 职场文书
政风行风整改报告
2014/11/06 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
项目经理岗位职责范本
2015/04/01 职场文书
golang通过递归遍历生成树状结构的操作
2021/04/28 Golang