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 相关文章推荐
判断多个input type=file是否有已经选择好文件的代码
May 23 Javascript
jquery和css3实现的炫酷时尚的菜单导航
Sep 01 Javascript
node.js中的favicon.ico请求问题处理
Dec 15 Javascript
angularJS中$apply()方法详解
Jan 07 Javascript
JavaScript动态创建div等元素实例讲解
Jan 06 Javascript
微信小程序 特效菜单抽屉效果实例代码
Jan 11 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
Jun 11 Javascript
JS表单传值和URL编码转换
Mar 03 Javascript
解决vue中使用Axios调用接口时出现的ie数据处理问题
Aug 13 Javascript
使用FormData实现上传多个文件
Dec 04 Javascript
原生JS实现贪吃蛇小游戏
Mar 09 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
Nov 03 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新手上路(二)
2006/10/09 PHP
PHP判断变量是否为0的方法
2014/02/08 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
Zend Framework入门知识点小结
2016/03/19 PHP
mysql alter table命令修改表结构实例详解
2016/09/24 PHP
php更新cookie内容的详细方法
2019/09/30 PHP
jquery键盘事件介绍
2011/01/31 Javascript
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
JavaScript程序中的流程控制语句用法总结
2016/05/23 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
angular中使用Socket.io实例代码
2017/06/03 Javascript
JavaScript程序设计高级算法之动态规划实例分析
2017/11/24 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
详解vue-cli项目中怎么使用mock数据
2018/05/29 Javascript
vue2.0 中使用transition实现动画效果使用心得
2018/08/13 Javascript
vue select选择框数据变化监听方法
2018/08/24 Javascript
layui 弹出层回调获取弹出层数据的例子
2019/09/02 Javascript
[49:08]Secret vs VP 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python 可爱的大小写
2008/09/06 Python
Python Mysql数据库操作 Perl操作Mysql数据库
2009/01/12 Python
python获取指定路径下所有指定后缀文件的方法
2015/05/26 Python
python中的全局变量用法分析
2015/06/09 Python
CentOS6.5设置Django开发环境
2016/10/13 Python
Python3.9又更新了:dict内置新功能
2020/02/28 Python
使用pytorch 筛选出一定范围的值
2020/06/28 Python
Python中的面向接口编程示例详解
2021/01/17 Python
全球知名提供各类营养保健品的零售商:Vitamin Shoppe
2016/10/09 全球购物
上海期货面试题
2014/01/31 面试题
信息管理专业学生自荐信格式
2013/09/22 职场文书
日语系毕业生推荐信
2013/11/11 职场文书
建筑施工员岗位职责
2013/11/26 职场文书
幼儿园门卫制度
2014/01/29 职场文书
小学生十佳少年事迹材料
2014/08/20 职场文书
2015入党自荐书范文
2015/03/05 职场文书
2015年公务员工作总结
2015/04/24 职场文书
2016年圣诞节寄语(一句话)
2015/12/07 职场文书