相关文章和阅读顺序
搭建Typescript+React项目模板(1) --- 项目初始化
搭建 Typescript+React 项目模板 (2) --- 提升开发体验
搭建 Typescript+React 项目模板 (3) --- 整理项目和杂项
搭建 Typescript+React 项目模板 (4) --- 项目打包
搭建 Typescript+React 项目模板 (5) --- 团队规范
文章已同步更新到掘金专栏(https://juejin.im/user/5a77c815f265da4e9518bebc/posts)
项目地址
前言
本章主要介绍的是建立在项目初始化的基础上如何优化开发体验
内容包含如下:
- 支持
sass
- 支持
css module
- 配置公用的
sass
属性 - 支持装饰器
- 路径优化
- 构建缓存
- 构建加速
支持sass
什么是sass
sass是一款css预处理语言,支持变量,嵌套,mixin和导入等功能,可以极大地方便和简化css写法。支持sass
支持sass首先需要安装sass-loader
和node-sass
npm install -D node-sass sass-loader
另外还需要安装style-loader
和css-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
文件类型的编译配置即可:
-
查看效果
这时候我们在src下面新建一个index.scss
,然后在index.tsx
里面引入这个文件查看效果
效果如图:
支持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的配置修改为如下:
-
使用和问题
这个时候我们将index.tsx
文件修改为如下:
修改为这样既可,但是同时我们也发现一个问题:
这个问题导致的原因是因为.scss
文件中并没有类似export
这样的关键词用于导出一个模块,所以也就导致报错找不到模块,这个问题可以通过ts的模块声明(declare module
)来解决。 -
解决模块声明问题
这时候我们在根目录下新建一个typings
文件夹,用于存放.scss
的模块声明,以及后续需要用到的全局校验接口,然后新建typed-css-modules.d.ts
文件用于存放.scss
模块声明,目录结构和声明内容如下:
-
效果
这个时候回到index.tsx
文件中你会发现错误标红消失了,然后我们在index.scss
文件中新增如下代码
保存后你会发现当前目录下新增了一个index.scss.d.ts
文件,打开里面可以发现是针对每个类名的类型校验,当以后新增类名的时候,typed-css-modules.d.ts
都会自动在index.scss.d.ts
里面新增对应的类型校验:
这时候回到页面查看,你会发现类名变成了一个hash值,这样可以有效地避免类名全局污染问题:
配置公共sass
属性
既然已经可以使用sass
进行更加简便的css代码编写,那么我们也可以将常用的一些样式代码和sass变量写入公共文件中,当使用的时候就可以直接引入使用,这可以提高一定的效率节约时间:
-
新建公共样式目录
首先在src目录下新建styles文件夹,然后在styles文件夹下新建var.scss
文件用于存放样式变量。
之后在var.scss
文件里写入一个颜色变量和一个样式:
-
查看效果
然后在index.scss
文件里面引入var.scss
,接着就可以直接使用里面的变量了:
效果:
-
优化
上面的效果其实已经达成,但还是存在一个不好的问题,就是在引入var.scss
的路径上要根据每个文件夹的路径相对来引入非常麻烦,那么我们能否做到只需要@import var.scss
就行呢?答案是可以的,我们可以使用一个node-sass
的属性includePaths
进行路径优化:
支持装饰器
-
前置工作
在src目录下新建一个components文件夹,用于存放通用组件,然后在components文件及里面新建一个组件Test,然后在网页入口引入这个组件,如下图所示:
-
什么是装饰器,为什么需要装饰器
装饰器本质上就是一个函数,这个函数对类(class)本身进行一些处理,也可以将装饰器的写法当做一种语法糖,如果不用装饰器的话,可以写成下图这样:
但是如果装饰器多的话就会变成如下样子:
这样会导致代码非常难以理解,于是装饰器就登上舞台了。这在今后使用了mobx(or redux)的时候也是非常有用的。 -
设置装饰器可用
根据装饰器的语法,我们可以将上面的代码写成如下:
但是你会发现这里报了一个错误,这是因为装饰器语法在es6标准中还只是一个提案,并未正式支持,但是在ts中,装饰器已经被正式支持了,不用ts的可以自行安装babel
相关包进行支持。
那么怎么解决这个错误呢?我们根据错误提示进入到tsconfig
文件中,将experimentalDecorators
设置为true
即可,然后回到页面查看log装饰器已经生效了:
优化路径
- 为什么
在上面的例子中我们新建了components
文件夹,然后在入口处引入了其中的Test
组件
但是这时候需要考虑到一个问题,如果以后在一个层级比较深的文件中引入这个组件会不会产生如下这种情况呢?
import Test from '../../../../components/Test'
这样不仅书写起来麻烦还容易出错,因此这时候就需要进行一些路径上的优化,使得无论在哪个地方引入这些组件都能用同一种写法,例如:
import Test from '@comonents/Test'
- 路径优化
这里针对路径的优化有两种方案,第一种是直接在webpack.resolve.alias
中进行路径配置:
但是在这里我们使用了ts,所以还需要在tsconfig
中进行配置:
这样也能用,不过我们还可以用tsconfig-paths-webpack-plugin
这个包将tsconfig
中对路径的设置映射到webpack配置中去,这样就不需要在webpack中再进行一次路径的配置了,首先安装:
npm install -D tsconfig-paths-webpack-plugin
然后就采用前面tsconfig
里面对baseUrl
和paths
的配置。
之后进入webpack配置中,引入tsconfig-paths-webpack-plugin
接着在webpack.resolve
中新增配置项plugins
(这里要注意的是新增的不是webpack.plugins
,而是webpack.resolve.plugins
),配置如下代码:
接着我们就可以愉快地使用简化后的路径了:
构建缓存
什么是构建缓存
我们一般会使用webpack-dev-server
来进行项目开发,当我们运行webpack-dev-server
的时候它会在内存中进行项目的构建,但是当使用了babel
之类的代码转换工具后,会对项目构建产生较大的性能影响,这是因为每一次的构建都会对代码进行重新转换。
而构建缓存就是将构建的公用代码缓存在磁盘上,这样做的效果就是第一次构建的时间花销会比不用缓存的构建大,但是在之后每次构建的时间花销都会大大减少。-
对比
我们拿一个较大的项目来看区别。
注: 左边是没有设置构建缓存,右边进行了构建缓存。
首先进行对比的是第一次构建时候的时间花销:
然后是第二次构建的时间花销:
可以看出在第二次构建的时候时间花销减少了百分之五十以上。 设置构建缓存
在设置构建缓存之前我们首先要考虑的是那些地方需要进行设置,那么在前面的配置过程中,可以看出花销较大的地方有对ts(x)
的转换并且以后还会添加对应的babel进去,然后还有针对sass
类型的转换,那么我们就先对这两个地方的转换进行配置
- 对ts(x)的转换
这里因为我们使用的是awesome-typescript-loader
,这个库本身自带了开启缓存的选项useCache
,然后我们需要指定一个保存缓存文件的地方cacheDirectory
,所以配置改为如下:
- 对
sass
类型的转换
这个地方我们需要使用到一个库cache-loader
npm install -D cache-loader
,
然后在对.scss
文件类型的转换配置中使用它,在这里我们主要是针对转换出来的css进行缓存,所以需要写在typings-for-css-modules-loader
配置的前面:
这样就配置好当前的构建缓存了,当你npm run dev
的时候会发现根目录下生成了缓存文件.cache-loader
。
打开它看会发现有对应的缓存代码:
不过现在只是根据目前需要进行的缓存配置,当后面集成antd
等相关库的时候因为需要使用到less
类型,所以以后还需要根据需要进行添加。
此外,在构建这方面的知识在后面的项目打包部分也是非常有用的。