nuxt.js-ant-design-vue配置踩坑日记

最近开发一个带seo以及部分后台功能的项目,nuxt作为vue ssr框架可以非常好的完成这个需求,这里我选择了ant-design-vue作为UI组件库。

以下是踩坑的一些记录 :

首先介绍一下项目情况和需求:

  • Nuxt.js是一个 Vue.js 通用框架,预设了使用 Vue.js开发SSR的各种配置。项目中使用的是SSR模式,因此首屏是由服务端完成渲染
  • 项目仅用到少数的UI组件,因此我们希望使用按需加载组件,以减少网络开销。

1. 按需加载引入组件

首先我们移除掉 nuxt.config.js 

{
   css: ['ant-design-vue/dist/antd.css'],
   // 这里会全局引入所有样式,不是我们所希望的按需加载
}


参考官方文档antd-vue # 按需加载:

// 同时参考 Nuxt-cli 创建项目时 创建的 plugin/antd-ui.js
import Vue from 'vue'
import Button from 'ant-design-vue/lib/button';
import 'ant-design-vue/lib/button/style'; // 或者 ant-design-vue/lib/button/style/css 加载 css 文件

Vue.use(Button.name, Button)

编译未通过,提示错误:

// https://github.com/ant-design/ant-motion/issues/44
.bezierEasingMixin();
^
Inline JavaScript is not enabled. Is it set in your options?

根据报错所提供的信息,less升级到3.0 后,需要 less-loader配置一个功能,才能正常使用:

// nuxt.config.js
{
  build: {
    loaders: {
      less: {
        javascriptEnabled: true
      }
    }
  }
}

编译通过,打开页面,返回500,提示:

编译能通过,说明代码编译没有问题,但是server端执行时出现了错误。尝试注释掉plugin/antd-ui.js引入样式文件这行 import 'ant-design-vue/lib/button/style'; ,server首屏渲染能够正常启动,但引入的button组件样式丢失。

打开 ant-design-vue/lib/button/style/index.js 查看:

'use strict';
require('../../style/index.less');
require('./index.less');

// ant-design-vue/es/button/style/index.js
import '../../style/index.less';
import './index.less';

可以看到,antd-vue为生产环境提供了两种模块的代码。为了tree-shaking 我们优先选择 es 模块。

补充知识:现在的webpack@4+ 支持识别项目 packge.json module字段,使用ESModule的依赖更好的支持构建中的tree-shaking。

修改代码为 es/button/...,编译通过,但页面仍抛出一500服务端错误:

根据错误提示cannot use import statement和es包使用的ESModule语法,猜测服务端侧渲染页面时语法出错,Node.js 不能直接识别 .js文件内的ESModule语法。

// .nuxt.config.js
{
  plugins: [
    {
      src: '@/plugins/antd-ui',
      mode: 'client' // 仅 客户端使用plugin
    }
  ]
}


页面正常加载,但Vue.js 给出了错误提示

此时,我们再将plugin代码替换回lib以及移除mode: 'client ,错误又回到了最开始的 invalid or unexpected token

搜索Nuxt官方文档:

如果要使用Babel与特定的依赖关系进行转换,你可以在build.transpile中添加它们,transpile中的选项可以是字符串或正则表达式对象,用于匹配依赖项文件名。

添加配置:

{ // nuxt.config.js
  build: {
    transpile: [/ant-design-vue/]
  }
}

终于,服务端渲染正常,样式也正常加载。接着引入 ant-design-vue官方推荐使用的插件babel-plugin-import

// nuxt.config.js
{
  build: {
    babel: {
      plugins: [
        [
          'import',
          {
            libraryName: 'ant-design-vue',
            libraryDirectory: 'es',
            // 选择子目录 例如 es 表示 ant-design-vue/es/component
            // lib 表示 ant-design-vue/lib/component
           
            style: true
            // 默认不使用该选项,即不导入样式 , 注意 ant-design-vue 使用 js 文件引入样式
            // true 表示 import  'ant-design-vue/es/component/style'
            // 'css' 表示 import 'ant-design-vue/es/component/style/css'
          }
        ]
      ]
    }
  }
}

// plugins/antd-ui.js
import Vue from 'vue'
import { Button } from 'ant-dsign-vue'
// 这时,可以通过 简写的方式引入样式和组件

Vue.use(Button)


2. pages目录内引入组件

 

上图是在pages/index.vue内引入组件,npm run build && npm run start 执行后的线上环境,可以看到样式在刷新首屏时,会看到闪烁的现象,这里出现的问题在于入口文件并不包含组件,而是异步引入的,从编译结果上也可以看到 610kb 的包对应的chunk vendors.pages/index ,并不在entrypoint内,默认情况下Nuxt.js 路由页面已经被分配为dynamic import,同时style是通过js设置到style上的,而不是单独打包出来。经过测试,css单独打包后,UI组件仍是单独分包,即便是单独打包出来,依然会有按需加载的问题,首屏仍会闪烁。

build result

因此,如果组件被大多数页面使用,推荐在 plugin内注册,或者通过 nuxt.config.js的css相关文件直接引入对应的组件样式,同时关闭babel-import-plugin 的 style选项。 (吐槽一句,iView只能引入单一全局样式,不能按需加载样式,1.5m的大小非常恐怖)

除此以外,可以考虑配置webpacksplitchunks配置,实现自己的需求。

3. 解决antd-icon 过大(传统艺能

前面生产环境的包可以发现,只使用了一个Button,却打包了600kb的依赖,检查后发现是引入了@ant-design/icon 包。

参考: https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo

{ // nuxt.config.js
  build: {
    extend(config, ctx) {
      config.resolve.alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './assets/icon/antd-icon.js') // 引入需要的
    }
  }
}


题外话

“按需引入”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Nuxt.js中使用vue-seamless-scroll,首先需要在plugins目录下创建一个vue-seamless-scroll.js文件,并在文件中导入Vue和SeamlessScroll组件,然后使用Vue.use(SeamlessScroll)进行注册。 接下来,在nuxt.config.js文件中的plugins配置项中添加如下内容: ```javascript plugins: [ '@/plugins/element-ui', '@/plugins/axios', { src: '@/plugins/vue-seamless-scroll', ssr: false }, ] ``` 这样就可以将vue-seamless-scroll插件引入到Nuxt.js项目中了。 然后,在需要使用滚动组件的文件中,使用`<vue-seamless-scroll>`标签,并传入相应的数据和类名等参数。例如: ```html <vue-seamless-scroll :data="runningData" :class-option="scrollOption" class="scroll-container"> <div class="flex-row" v-for="item in runningData" :key="item.id"> <span class="row-1 row-nomal">{{ item.mbShowName }}</span> <span class="row-2 row-nomal">{{ item.mbShowVal }}</span> <span class="row-3 row-nomal">{{ item.updateTime | dateFilter }}</span> </div> </vue-seamless-scroll> ``` 这样就可以在Nuxt.js中使用vue-seamless-scroll组件了。 如果你在公司的基于Nuxt.js的项目中使用滚动组件后刷新页面出现"window is not defined"的错误,可能是因为滚动组件依赖于浏览器环境,而在服务器端渲染时无法访问到window对象。解决这个问题可以将ssr选项设置为false,如前面的配置所示。这样就可以避免在服务器端渲染时出现该错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [在 Nuxt中使用滚动组件 vue-seamless-scroll](https://blog.csdn.net/weixin_44769310/article/details/116144924)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

短暂又灿烂的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值