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 相关文章推荐
Javascript拓展String方法小结
Jul 08 Javascript
返回顶部按钮响应滚动且动态显示与隐藏
Oct 14 Javascript
JavaScript实现判断图片是否加载完成的3种方法整理
Mar 13 Javascript
js+cookies实现悬浮购物车的方法
May 25 Javascript
jquery实现仿Flash的横向滑动菜单效果代码
Sep 17 Javascript
基于canvas实现的绚丽圆圈效果完整实例
Jan 26 Javascript
JavaScript中的原型继承基础学习教程
May 06 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 Javascript
Node绑定全局TraceID的实现方法
Nov 14 Javascript
JavaScript实现Tab标签页切换的最简便方式(4种)
Jun 28 Javascript
Javascript实现单选框效果
Dec 09 Javascript
原生JS封装vue Tab切换效果
Apr 28 Vue.js
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
PHP函数spl_autoload_register()用法和__autoload()介绍
2012/02/04 PHP
php实现批量下载百度云盘文件例子分享
2014/04/10 PHP
PHP Cookie学习笔记
2016/08/23 PHP
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
JavaScript XML操作 封装类
2009/07/01 Javascript
JS常见问题整理(持续更新)
2013/08/06 Javascript
jQuery获得内容和属性方法及示例
2013/12/02 Javascript
使用jQuery实现图片遮罩半透明坠落遮挡
2015/03/16 Javascript
JavaScript中字符串分割函数split用法实例
2015/04/07 Javascript
Javascript闭包(Closure)详解
2015/05/05 Javascript
js实现新年倒计时效果
2015/12/10 Javascript
javascript函数自动执行常用方法汇总
2016/03/28 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
2016/06/17 Javascript
微信小程序block的使用教程
2018/04/01 Javascript
Vue创建头部组件示例代码详解
2018/10/23 Javascript
详解JavaScript 中的批处理和缓存
2020/11/19 Javascript
[01:20:37]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
[03:01]完美世界DOTA2联赛PWL S2 集锦第二期
2020/12/03 DOTA
python生成器的使用方法
2013/11/21 Python
python 专题九 Mysql数据库编程基础知识
2017/03/16 Python
django实现前后台交互实例
2017/08/07 Python
Python多线程原理与用法详解
2018/08/20 Python
python3 requests库实现多图片爬取教程
2019/12/18 Python
python实现AdaBoost算法的示例
2020/10/03 Python
Python使用tkinter制作在线翻译软件
2021/02/22 Python
一款基于css3麻将筛子3D翻转特效的实例教程
2014/12/31 HTML / CSS
Volcom英国官方商店:美国殿堂级滑板、冲浪、滑雪服装品牌
2019/03/13 全球购物
Why we need EJB
2016/10/20 面试题
计算机专业毕业生的自我评价
2013/11/18 职场文书
《去年的树》教学反思
2014/04/11 职场文书
白岩松演讲
2014/05/21 职场文书
纪律教育月活动总结
2014/08/26 职场文书
五四青年节比赛演讲稿
2015/03/18 职场文书
2015初中教导处工作总结
2015/07/21 职场文书
JavaScript实现登录窗体
2021/06/22 Javascript
使用CSS实现小三角边框原理解析
2021/11/07 HTML / CSS