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与flash交互通信基础教程
Aug 07 Javascript
学习ExtJS Panel常用方法
Oct 07 Javascript
Javascript 函数parseInt()转换时出现bug问题
May 20 Javascript
JS设置CSS样式的方式汇总
Jan 21 Javascript
react native带索引的城市列表组件的实例代码
Aug 08 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
Oct 16 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
使用js在layui中实现上传图片压缩
Jun 18 Javascript
20个必会的JavaScript面试题(小结)
Jul 02 Javascript
layui实现数据表格隐藏列的示例
Oct 25 Javascript
JavaScript定时器使用方法详解
Mar 26 Javascript
vue 使用async写数字动态加载效果案例
Jul 18 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
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
PHP5.5迭代生成器用法实例详解
2016/03/16 PHP
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
2008/12/25 Javascript
jquery 图片轮换效果
2010/07/29 Javascript
JS实现在Repeater控件中创建可隐藏区域的代码
2010/09/16 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
完美实现仿QQ空间评论回复特效
2015/05/06 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
jquery分隔Url的param方法(推荐)
2016/05/25 Javascript
ES6中的数组扩展方法
2016/08/26 Javascript
适用于手机端的jQuery图片滑块动画
2016/12/09 Javascript
微信小程序 视图容器组件的详解及实例代码
2017/01/19 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
vue-cli中打包图片路径错误的解决方法
2017/10/26 Javascript
基于JavaScript实现简单的音频播放功能
2018/01/07 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
webpack下实现动态引入文件方法
2018/02/22 Javascript
微信小程序实现分享到朋友圈功能
2018/07/19 Javascript
JS中的两种数据类型及实现引用类型的深拷贝的方法
2018/08/12 Javascript
基于vue的tab-list类目切换商品列表组件的示例代码
2020/02/14 Javascript
Javascript call及apply应用场景及实例
2020/08/26 Javascript
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
python实现连连看辅助(图像识别)
2020/03/25 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
CSS3近阶段篇之酷炫的3D旋转透视
2016/04/28 HTML / CSS
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
Perfume’s Club意大利官网:欧洲美妆电商
2019/05/03 全球购物
C++:局部变量能否和全局变量重名
2014/03/03 面试题
创业计划书中包含的9个方面
2013/12/26 职场文书
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
三分钟演讲稿范文
2014/04/24 职场文书
优秀团员事迹材料2000字
2014/08/20 职场文书
2014年会计人员工作总结
2014/12/10 职场文书
2015年服务员工作总结
2015/04/08 职场文书
老乡会致辞
2015/07/28 职场文书