搭建Typescript+React项目模板(2) --- 提升开发体验

相关文章和阅读顺序

搭建Typescript+React项目模板(1) --- 项目初始化
搭建 Typescript+React 项目模板 (2) --- 提升开发体验
搭建 Typescript+React 项目模板 (3) --- 整理项目和杂项
搭建 Typescript+React 项目模板 (4) --- 项目打包
搭建 Typescript+React 项目模板 (5) --- 团队规范

文章已同步更新到掘金专栏(https://juejin.im/user/5a77c815f265da4e9518bebc/posts)

项目地址

前言

本章主要介绍的是建立在项目初始化的基础上如何优化开发体验
内容包含如下:

  1. 支持sass
  2. 支持css module
  3. 配置公用的sass属性
  4. 支持装饰器
  5. 路径优化
  6. 构建缓存
  7. 构建加速

支持sass

  • 什么是sass
    sass是一款css预处理语言,支持变量,嵌套,mixin和导入等功能,可以极大地方便和简化css写法。

  • 支持sass
    支持sass首先需要安装sass-loadernode-sass
    npm install -D node-sass sass-loader
    另外还需要安装style-loadercss-loader
    npm install -D style-loader css-loader

  • 配置webpack
    在这里有一个点是需要注意的,因为将sass代码编译成可用的样式代码需要用到三个loader,所以就会产生顺序问题,首先sass-loader将sass代码编译为css(默认使用node-sass),然后css-loader将编译出来的代码再次编译成为符合CommonJS的代码,最后style-loader将第二步编译出来的代码转为js代码,然后webpack进行loader编译的顺序是从下到上的:
    知道上面的顺序后我们在webpack中的配置就非常简单了,直接在module.rules下面加上.scss文件类型的编译配置即可:

    image.png

  • 查看效果
    这时候我们在src下面新建一个index.scss,然后在index.tsx里面引入这个文件查看效果

    目录结构

    index.tsx

    index.scss

    效果如图:
    image.png

支持css module

  • 什么是css module
    css module是针对css类名作用域做出限定的一种规范,用以解决css类名冲突的问题,此外还能避免一些爬虫进行数据爬取(当然厉害的爬虫除外),同等的还有BEM规范。

  • 安装对应的包
    因为在这里我们用的是TypeScript,所以可以用typings-for-css-modules-loader这个包,这个包也可以替代css-loader的功能,此外这个包还能根据.scss文件里面的类名自动生成对应的.d.ts文件:
    npm install -D typings-for-css-modules-loader

  • 配置webpack
    这个配置接非常简单了,因为要用typings-for-css-modules-loader替代css-loader的功能,所以直接替换即可,将前面sass的配置修改为如下:

    image.png

  • 使用和问题
    这个时候我们将index.tsx文件修改为如下:

    image.png

    修改为这样既可,但是同时我们也发现一个问题:
    image.png

    这个问题导致的原因是因为.scss文件中并没有类似export这样的关键词用于导出一个模块,所以也就导致报错找不到模块,这个问题可以通过ts的模块声明(declare module)来解决。

  • 解决模块声明问题
    这时候我们在根目录下新建一个typings文件夹,用于存放.scss的模块声明,以及后续需要用到的全局校验接口,然后新建typed-css-modules.d.ts文件用于存放.scss模块声明,目录结构和声明内容如下:

    image.png

  • 效果
    这个时候回到index.tsx文件中你会发现错误标红消失了,然后我们在index.scss文件中新增如下代码

    image.png

    保存后你会发现当前目录下新增了一个index.scss.d.ts文件,打开里面可以发现是针对每个类名的类型校验,当以后新增类名的时候,typed-css-modules.d.ts都会自动在index.scss.d.ts里面新增对应的类型校验:
    image.png

    这时候回到页面查看,你会发现类名变成了一个hash值,这样可以有效地避免类名全局污染问题:
    image.png

配置公共sass属性

既然已经可以使用sass进行更加简便的css代码编写,那么我们也可以将常用的一些样式代码和sass变量写入公共文件中,当使用的时候就可以直接引入使用,这可以提高一定的效率节约时间:

  • 新建公共样式目录
    首先在src目录下新建styles文件夹,然后在styles文件夹下新建var.scss文件用于存放样式变量。
    之后在var.scss文件里写入一个颜色变量和一个样式:

    image.png

  • 查看效果
    然后在index.scss文件里面引入var.scss,接着就可以直接使用里面的变量了:

    image.png

    效果:
    image.png

  • 优化
    上面的效果其实已经达成,但还是存在一个不好的问题,就是在引入var.scss的路径上要根据每个文件夹的路径相对来引入非常麻烦,那么我们能否做到只需要@import var.scss就行呢?答案是可以的,我们可以使用一个node-sass的属性includePaths进行路径优化:

    image.png

    image.png

支持装饰器

  • 前置工作
    在src目录下新建一个components文件夹,用于存放通用组件,然后在components文件及里面新建一个组件Test,然后在网页入口引入这个组件,如下图所示:


    image.png

    image.png
  • 什么是装饰器,为什么需要装饰器
    装饰器本质上就是一个函数,这个函数对类(class)本身进行一些处理,也可以将装饰器的写法当做一种语法糖,如果不用装饰器的话,可以写成下图这样:


    image.png

    但是如果装饰器多的话就会变成如下样子:


    image.png

    这样会导致代码非常难以理解,于是装饰器就登上舞台了。这在今后使用了mobx(or redux)的时候也是非常有用的。
  • 设置装饰器可用
    根据装饰器的语法,我们可以将上面的代码写成如下:

    image.png

    但是你会发现这里报了一个错误,这是因为装饰器语法在es6标准中还只是一个提案,并未正式支持,但是在ts中,装饰器已经被正式支持了,不用ts的可以自行安装babel相关包进行支持。
    image.png

    那么怎么解决这个错误呢?我们根据错误提示进入到tsconfig文件中,将experimentalDecorators设置为true即可,然后回到页面查看log装饰器已经生效了:
    image.png

优化路径

  • 为什么
    在上面的例子中我们新建了components文件夹,然后在入口处引入了其中的Test组件
    image.png

    但是这时候需要考虑到一个问题,如果以后在一个层级比较深的文件中引入这个组件会不会产生如下这种情况呢?
import Test from '../../../../components/Test'

这样不仅书写起来麻烦还容易出错,因此这时候就需要进行一些路径上的优化,使得无论在哪个地方引入这些组件都能用同一种写法,例如:

import Test from '@comonents/Test'
  • 路径优化
    这里针对路径的优化有两种方案,第一种是直接在webpack.resolve.alias中进行路径配置:
    image.png

    但是在这里我们使用了ts,所以还需要在tsconfig中进行配置:
    image.png

    这样也能用,不过我们还可以用tsconfig-paths-webpack-plugin这个包将tsconfig中对路径的设置映射到webpack配置中去,这样就不需要在webpack中再进行一次路径的配置了,首先安装:
    npm install -D tsconfig-paths-webpack-plugin
    然后就采用前面tsconfig里面对baseUrlpaths的配置。
    之后进入webpack配置中,引入tsconfig-paths-webpack-plugin
    image.png

    接着在webpack.resolve中新增配置项plugins(这里要注意的是新增的不是webpack.plugins,而是webpack.resolve.plugins),配置如下代码:
    image.png

    接着我们就可以愉快地使用简化后的路径了:
    image.png

构建缓存

  • 什么是构建缓存
    我们一般会使用webpack-dev-server来进行项目开发,当我们运行webpack-dev-server的时候它会在内存中进行项目的构建,但是当使用了babel之类的代码转换工具后,会对项目构建产生较大的性能影响,这是因为每一次的构建都会对代码进行重新转换。
    而构建缓存就是将构建的公用代码缓存在磁盘上,这样做的效果就是第一次构建的时间花销会比不用缓存的构建大,但是在之后每次构建的时间花销都会大大减少。

  • 对比
    我们拿一个较大的项目来看区别。
    注: 左边是没有设置构建缓存,右边进行了构建缓存。
    首先进行对比的是第一次构建时候的时间花销:


    image.png

    然后是第二次构建的时间花销:


    image.png

    可以看出在第二次构建的时候时间花销减少了百分之五十以上。
  • 设置构建缓存
    在设置构建缓存之前我们首先要考虑的是那些地方需要进行设置,那么在前面的配置过程中,可以看出花销较大的地方有对ts(x)的转换并且以后还会添加对应的babel进去,然后还有针对sass类型的转换,那么我们就先对这两个地方的转换进行配置

  1. 对ts(x)的转换
    这里因为我们使用的是awesome-typescript-loader,这个库本身自带了开启缓存的选项useCache,然后我们需要指定一个保存缓存文件的地方cacheDirectory,所以配置改为如下:
    image.png
  2. sass类型的转换
    这个地方我们需要使用到一个库cache-loader
    npm install -D cache-loader,
    然后在对.scss文件类型的转换配置中使用它,在这里我们主要是针对转换出来的css进行缓存,所以需要写在typings-for-css-modules-loader配置的前面:
    image.png

    这样就配置好当前的构建缓存了,当你npm run dev的时候会发现根目录下生成了缓存文件.cache-loader
    image.png

    打开它看会发现有对应的缓存代码:
    image.png

    不过现在只是根据目前需要进行的缓存配置,当后面集成antd等相关库的时候因为需要使用到less类型,所以以后还需要根据需要进行添加。

此外,在构建这方面的知识在后面的项目打包部分也是非常有用的。

推荐阅读更多精彩内容

  • 1 Webpack 1.1 概念简介 1.1.1 WebPack是什么 1、一个打包工具 2、一个模块加载工具 3...
    Kevin_Junbaozi阅读 3,571评论 0 15
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 4,761评论 2 17
  • 目录第1章 webpack简介 11.1 webpack是什么? 11.2 官网地址 21.3 为什么使用 web...
    lemonzoey阅读 682评论 0 1
  • 从V1迁移到V2由于使用的是webpack版本是2.2.1,所以针对原文做了一些修改。针对webpack2的修改部...
    yzc123446阅读 326评论 0 1
  • 阅读、看电影,这些段时间去“体验”另一种生活的方法,特别过瘾。在过程中,你的注意力会完全陷入到角色中,仿佛跟着主角...
    saiyonana阅读 21评论 0 0