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实现瀑布流展现照片(自动适应窗口大小)
Apr 08 Javascript
jQuery制作仿腾讯web qq用户体验桌面
Aug 20 Javascript
验证控件与Button的OnClientClick事件详细解析
Dec 04 Javascript
JSON格式化输出
Nov 10 Javascript
angularjs中的e2e测试实例
Dec 06 Javascript
JS动态显示表格上下frame的方法
Mar 31 Javascript
jQuery插件ajaxFileUpload异步上传文件
Oct 19 Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 Javascript
JavaScript实现修改伪类样式
Nov 27 Javascript
微信小程序实现自动定位功能
Oct 31 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
Feb 27 Javascript
jQuery实现倒计时功能完整示例
Jun 01 jQuery
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
探讨如何使用SimpleXML函数来加载和解析XML文档
2013/06/07 PHP
一个简洁实用的PHP缓存类完整实例
2014/07/26 PHP
php中动态变量用法实例
2015/06/10 PHP
Yii2中如何使用modal弹窗(基本使用)
2016/05/30 PHP
php实现博客,论坛图片防盗链的方法
2016/10/15 PHP
jQuery帮助之筛选查找 children([expr])
2011/01/31 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
jQuery Migrate 1.1.0 Released 注意事项
2014/06/14 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
基于JS快速实现导航下拉菜单动画效果附源码下载
2016/10/27 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
解决jquery appaend元素中id绑定事件失效的问题
2017/09/12 jQuery
JS交互点击WKWebView中的图片实现预览效果
2018/01/05 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
nodejs二进制与Buffer的介绍与使用
2019/07/11 NodeJs
Pthon批量处理将pdb文件生成dssp文件
2015/06/21 Python
Python 实现简单的shell sed替换功能(实例讲解)
2017/09/29 Python
Python实现PS滤镜特效之扇形变换效果示例
2018/01/26 Python
TensorFlow实现创建分类器
2018/02/06 Python
python之django母板页面的使用
2018/07/03 Python
python处理数据,存进hive表的方法
2018/07/04 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
Django模板语言 Tags使用详解
2019/09/09 Python
matplotlib.pyplot画图并导出保存的实例
2019/12/07 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
怎样声明接口
2014/09/19 面试题
一套C#面试题
2013/10/09 面试题
服务生自我鉴定
2014/01/22 职场文书
军训考核自我鉴定
2014/02/13 职场文书
医学专业应届生的自我评价
2014/02/28 职场文书
十佳护士先进事迹
2014/05/08 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书
毕业欢送晚会主持词
2019/06/25 职场文书
SQL实现LeetCode(178.分数排行)
2021/08/04 MySQL