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 相关文章推荐
JS检测图片大小的实例
Aug 21 Javascript
Javascript数组与字典用法分析
Dec 13 Javascript
jQuery中before()方法用法实例
Dec 25 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
Jan 19 Javascript
浅谈JavaScript中Date(日期对象),Math对象
Feb 05 Javascript
Jquery树插件zTree用法入门教程
Feb 17 Javascript
JS实现表格数据各种搜索功能的方法
Mar 03 Javascript
跟我学习javascript的最新标准ES6
Nov 20 Javascript
使用JQuery选择HTML遍历函数的方法
Sep 17 Javascript
easyui combogrid实现本地模糊搜索过滤多列
May 13 Javascript
JavaScript实现单击网页任意位置打开新窗口与关闭窗口的方法
Sep 21 Javascript
JavaScript设计模式之构造函数模式实例教程
Jul 02 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
PHP下MAIL的另一解决方案
2006/10/09 PHP
PHP 选项及相关信息函数库
2006/12/04 PHP
IIS环境下快速安装、配置和调试PHP5.2.0
2006/12/17 PHP
用PHP 快速生成 Flash 动画的方法
2007/03/06 PHP
PHP中限制IP段访问、禁止IP提交表单的代码
2011/04/23 PHP
Yii实现多数据库主从读写分离的方法
2014/12/29 PHP
php获取远程文件大小
2015/10/20 PHP
详细分析PHP 命名空间(namespace)
2020/06/30 PHP
jQuery随便控制任意div隐藏的方法
2013/06/28 Javascript
jQuery trigger()方法用法介绍
2015/01/13 Javascript
深入浅析react native es6语法
2015/12/09 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
JQuery validate插件Remote用法大全
2016/05/15 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
JavaScript实现网页留言板功能
2020/11/23 Javascript
[56:42]完美世界DOTA2联赛循环赛 Matador vs Forest 第二场 11.06
2020/11/06 DOTA
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Python操作mongodb数据库的方法详解
2018/12/08 Python
python SVM 线性分类模型的实现
2019/07/19 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
Python + Requests + Unittest接口自动化测试实例分析
2019/12/12 Python
python中使用you-get库批量在线下载bilibili视频的教程
2020/03/10 Python
python smtplib发送多个email联系人的实现
2020/10/09 Python
CSS3五个技巧给你的网站带来出色的效果
2009/04/02 HTML / CSS
世界上最大的餐具公司:Oneida
2016/12/17 全球购物
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
两道JAVA笔试题
2016/09/14 面试题
大学生应聘自荐信
2013/10/11 职场文书
金融行业务员的自我评价
2013/12/13 职场文书
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
2016年中秋节慰问信
2015/12/01 职场文书
Python保存并浏览用户的历史记录
2022/04/29 Python