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的漂亮的代码片段
Jun 05 Javascript
javascript避免数字计算精度误差的方法详解
Mar 05 Javascript
动态加载jQuery的两种方法实例分析
Jul 17 Javascript
有关jQuery中parent()和siblings()的小问题
Jun 01 Javascript
JS实现的手机端精简幻灯片效果
Sep 05 Javascript
javascript匀速动画和缓冲动画详解
Oct 20 Javascript
快速掌握jQuery插件WebUploader文件上传
Nov 07 Javascript
JavaScript实现前端分页控件
Apr 19 Javascript
vue封装一个简单的div框选时间的组件的方法
Jan 06 Javascript
Vue数字输入框组件的使用方法
Oct 19 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
Nov 01 Javascript
微信小程序点击view动态添加样式过程解析
Jan 21 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数组函数序列之array_intersect() 返回两个或多个数组的交集数组
2011/11/10 PHP
php cc攻击代码与防范方法
2012/10/18 PHP
ExtJS中文乱码之GBK格式编码解决方案及代码
2013/01/20 Javascript
js判断选择时间不能小于当前时间的示例代码
2013/09/24 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
js类式继承的具体实现方法
2013/12/31 Javascript
JQuery实现动态适时改变字体颜色的方法
2015/03/10 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
微信支付 JS API支付接口详解
2016/07/11 Javascript
解决node.js安装包失败的几种方法
2016/09/02 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
Jquery获取radio选中的值
2017/05/05 jQuery
node.js中express-session配置项详解
2017/05/31 Javascript
jQuery幻灯片插件owlcarousel参数说明中文文档
2018/02/27 jQuery
react 创建单例组件的方法
2018/04/26 Javascript
vue.js 实现输入框动态添加功能
2018/06/25 Javascript
NodeJS如何实现同步的方法示例
2018/08/24 NodeJs
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
JS函数进阶之继承用法实例分析
2020/01/15 Javascript
vue-cli设置css不生效的解决方法
2020/02/07 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
python 中的列表解析和生成表达式
2011/03/10 Python
python编程培训 python培训靠谱吗
2018/01/17 Python
pandas 如何分割字符的实现方法
2019/07/29 Python
python中有关时间日期格式转换问题
2019/12/25 Python
Python使用configparser读取ini配置文件
2020/05/25 Python
详解Python 循环嵌套
2020/07/09 Python
python实现登录与注册系统
2020/11/30 Python
美国轮胎网站:Priority Tire
2018/11/28 全球购物
护理专业推荐信
2013/11/07 职场文书
行政助理的岗位职责
2014/02/18 职场文书
学校消防演习方案
2014/02/19 职场文书
采购员岗位职责
2015/02/03 职场文书
个人工作年终总结
2015/03/09 职场文书
论语读书笔记
2015/06/26 职场文书