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之dhDataGrid Ver2.0.0代码
Jul 01 Javascript
基于jQuery实现点击同时更改两个iframe的网址
Jul 01 Javascript
js中判断控件是否存在
Aug 25 Javascript
在javascript中执行任意html代码的方法示例解读
Dec 25 Javascript
Visual Studio中js调试的方法图解
Jun 30 Javascript
Bootstrap所支持的表单控件实例详解
May 16 Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 Javascript
jquery 标签 隔若干行加空白或者加虚线的方法
Dec 07 Javascript
JavaScript校验Number(4,1)格式的数字实例代码
Mar 13 Javascript
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
Aug 16 Javascript
Vue.js实现大屏数字滚动翻转效果
Nov 29 Javascript
Vue仿Bibibili首页的问题
Jan 21 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出现web系统多域名登录失败的解决方法
2014/09/30 PHP
利用php操作memcache缓存的基础方法示例
2017/08/02 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
JavaScript Event学习第七章 事件属性
2010/02/07 Javascript
js查错流程归纳
2012/05/04 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
2014/01/09 Javascript
浅谈javascript中this在事件中的应用
2015/02/15 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
20分钟轻松创建自己的Bootstrap站点
2016/05/12 Javascript
JS原型与原型链的深入理解
2017/02/15 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
2017/08/31 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
2017/11/15 Javascript
JavaScript实现单例模式实例分享
2017/12/22 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
使用Angular9和TypeScript开发RPG游戏的方法
2020/03/25 Javascript
Node.js API详解之 console模块用法详解
2020/05/12 Javascript
vue+高德地图实现地图搜索及点击定位操作
2020/09/09 Javascript
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
Python实现抓取网页并且解析的实例
2014/09/20 Python
Python实现的ini文件操作类分享
2014/11/20 Python
python实现根据用户输入从电影网站获取影片信息的方法
2015/04/07 Python
用pycharm开发django项目示例代码
2019/06/13 Python
对Python中一维向量和一维向量转置相乘的方法详解
2019/08/26 Python
python print 格式化输出,动态指定长度的实现
2020/04/12 Python
如何快速理解python的垃圾回收机制
2020/09/01 Python
python实现双人五子棋(终端版)
2020/12/30 Python
CSS3中的5个有趣的新技术
2009/04/02 HTML / CSS
HTML5图片预览实例分享
2014/06/04 HTML / CSS
iframe与window.onload如何使用详解
2020/05/07 HTML / CSS
介绍一下RMI的基本概念
2016/12/17 面试题
大型活动组织方案
2014/05/10 职场文书
先进事迹材料范文
2014/12/29 职场文书
2015年机关党委工作总结
2015/05/23 职场文书
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis
修改Nginx配置返回指定content-type的方法
2022/09/23 Servers