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 相关文章推荐
又一个小巧的图片预加载类
May 05 Javascript
JSON.stringify 语法实例讲解
Mar 14 Javascript
JavaScript中OnLoad几种使用方法
Dec 15 Javascript
JS.findElementById()使用介绍
Sep 21 Javascript
jQuery如何防止这种冒泡事件发生
Feb 27 Javascript
基于Jquery和html5的7款个性化地图插件
Nov 17 Javascript
vue axios用法教程详解
Jul 23 Javascript
vue代理和跨域问题的解决
Jul 18 Javascript
react-router 路由切换动画的实现示例
Dec 03 Javascript
详解vue.js移动端配置flexible.js及注意事项
Apr 10 Javascript
JS中FormData类实现文件上传
Mar 27 Javascript
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
Mar 01 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
浅谈thinkphp的实例化模型
2015/01/04 PHP
ecshop 2.72如何修改后台访问地址
2015/03/03 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
thinkPHP模型初始化实例分析
2015/12/03 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
JS记录用户登录次数实现代码
2014/01/15 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
AngularJS入门教程(二):AngularJS模板
2014/12/06 Javascript
深入理解angularjs过滤器
2016/05/25 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
vue多级多选菜单组件开发
2020/09/08 Javascript
View.post() 不靠谱的地方你知道多少
2017/08/29 Javascript
浅谈Angular路由复用策略
2017/10/04 Javascript
angular 实现下拉列表组件的示例代码
2019/03/09 Javascript
小程序云开发实现数据库异步操作同步化
2019/05/18 Javascript
php结合js实现多条件组合查询
2019/05/28 Javascript
JS实现移动端可折叠导航菜单(现代都市风)
2020/07/07 Javascript
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
微信小程序自定义底部弹出框动画
2020/11/18 Javascript
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
python 的列表遍历删除实现代码
2020/04/12 Python
python 2.6.6升级到python 2.7.x版本的方法
2016/10/09 Python
python实现的二叉树定义与遍历算法实例
2017/06/30 Python
python抓取文件夹的所有文件
2018/02/27 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
2018/06/11 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
python变量命名的7条建议
2019/07/04 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
五四青年节的活动方案
2014/08/20 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
财务务虚会发言材料
2014/10/20 职场文书
《月光曲》教学反思
2016/02/16 职场文书
字典算法实现及操作 --python(实用)
2021/03/31 Python
浅谈MySQL user权限表
2021/06/18 MySQL
什么是clearfix (一文搞清楚css清除浮动clearfix)
2023/05/21 HTML / CSS