【vue系列】Vue服务端渲染SSR扩展,支持sass、typescript

1,326 阅读2分钟

历史回顾:

背景

我们组内组件库文档上的 demo 展现采用的 vue 服务端渲染实现。组内的小伙伴通过 Vue SSR 官方指南,目前已经可以渲染了。但是现在有点问题,不满足我们组件 demo 的编写环境,期望呢?可以支持 sasstypescript环境。这成了一个难点。刚好我目前处于阶段性忙的空闲期,赶紧研究研究。

基础环境:

  • node: v12.19.0
  • @vue/cli: 4.5.9
  • webpack: 4.0.0

一、实现支持 sass 预处理器

用过 sass 的肯定知道,支持 sass 预处理器需要安装 sass-loader、node-sass

看到这个两个npm包,有些小伙伴是不是傻傻分不清?

node-sass官网上的原话:

Node-sass是一个库,它将Node.js绑定到LibSass。它允许用户令人难以置信的速度将.scss文件本地编译为css,并通过连接中间件自动编译。

简单来说就是因为sass文件的编译需要用到 sass-loader,而 sass-loader 依赖于 node-sass,所以需要安装 node-sass

在搜索资料的时候,看到的都是这样的坑人配置:

反例: import SASS and SCSS #28

// webpack.base.config.js 
{
          test: /\.scss$/,
          use: [
              // fallback to style-loader in development
              process.env.NODE_ENV !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
              "css-loader",
              "sass-loader"
          ]
      },
      {
        test: /\.sass$/,
        use: [
            // fallback to style-loader in development
            process.env.NODE_ENV !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
            "css-loader",
            "sass-loader"
          ]
      },

反例: 如何添加scss支持 #13

查了几个vue ssr库的sass实现,以及还尝试了几个解决方案。都没有解决我的问题。在探索的过程了,我注意到 style-loader 与 vue-style-loader,很多人使用的很凌乱。在 Vue SSR指南 CSS管理 部分,明确指出:

在服务端渲染使用期间,通过 vue-style-loader 来将vue中的css通过 标签动态注入。

style-loader 使用与vue普通项目,不使用于vue服务端渲染。

最终现实

npm安装:

npm i node-sass@4.5.3 sass-loader@6.0.6

本文中npm包都会标识我使用的版本

webpack.base.conf.js配置:

resolve: {
    extensions: ['.js', '.vue', '.scss', '.sass'],
  },
module: {
    rules: [
	{
        test: /\.(css|scss|sass)$/,
        use: ['vue-style-loader', 'css-loader', "sass-loader"],
      },
  ]
}

二、支持 typescript

typescript 就比较麻烦了,到不是难,就是涉及到很多配置点,修改的文件比较多。我们开始吧。

typescript 相关 npm安装

npm i ts-loader@8.0.18 typescript@3.9.3 

vue class相关npm安装

npm i vue-class-component@7.2.5 vue-property-decorator@9.0.0  vuex@3.5.1 vuex-class@0.3.2 

创建tsconfig.json

具体配置很简单,可自行查看官网

webpack.*.conf.js

webpack.base.conf.js 配置:

resolve: {
    extensions: ['.js', '.vue', '.scss', '.sass', '.ts'],
  },
module: {
    rules: [
	{
        test: /\.ts$/,
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/],
        }
      },
  ]
}

entry入口配置

webpack.base.confi.jswebpack.client.confi.jswebpack.server.confi.js 中的 entry 设置成 entry-client.ts 或者 entry-server.ts

改文件后缀

  • entry-client.js -> entry-client.ts
  • entry-server.js -> entry-server.ts
  • app.js -> app.ts
  • server.js -> server.js 需要注意的是,entry-client.ts 中引用的 import { createApp } from './app’; 默认app为app.vue,需要我们指定为app.ts。entry-server.ts同理。

新增文件 sfc.d.ts

declare module "*.vue" {
    import Vue from "vue";

    export default Vue;
}

组件改造

首先是APP.vue,其次是其它页面和组件,改造完还是很清爽的。

<template>
  <div>
    <router-view></router-view>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component({})
export default class App extends Vue {
  mounted() {
    console.log('App mounted');
  }
}
</script>
<style>
</style>

重启项目

到这里,配置就结束啦。项目重启 npm run dev, ✌️,我们的vue服务端渲染就支持sass、typescript了。日常问题记录,希望对你有所帮助。