TypeScript在react项目中的实践 (2)

最后在client-src/utils/index.ts写上类似server端的处理就可以了

// client-src/utils/index.ts export * from '@Common/utils' // client-src/index.tsx import { comma } from './utils' console.log(comma(1234567)) // 1,234,567 环境的搭建

如果使用vs code进行开发,而且使用了ESLint的话,需要修改TS语法支持的后缀,添加typescriptreact的一些处理,这样才会自动修复一些ESLint的规则:

"eslint.validate": [ "javascript", "javascriptreact", { "language": "typescript", "autoFix": true }, { "language": "typescriptreact", "autoFix": true } ] webpack的配置

因为在前端使用了React,按照目前的主流,webpack肯定是必不可少的。
并没有选择成熟的cra(create-react-app)来进行环境搭建,原因有下:

webpack更新到4以后并没有尝试过,想自己耍一耍

结合着TS以及公司内部的东西,会有一些自定义配置情况的出现,担心二次开发太繁琐

但是其实也没有太多的配置,本次重构选用的UI框架为Google Material的实现:material-ui
而他们采用的是jss 来进行样式的编写,所以也不会涉及到之前惯用的scss的那一套loader了。

webpack分了大概如下几个文件:

file desc
common.js   公共的webpack配置,类似env之类的选项  
dll.js   用于将一些不会修改的第三方库进行提前打包,加快开发时编译效率  
base.js   可以理解为是webpack的基础配置文件,通用的loader以及plugins在这里  
pro.js   生产环境的特殊配置(代码压缩、资源上传)  
dev.js   开发环境的特殊配置(source-map)  

dll是一个很早之前的套路了,大概需要修改这么几处:

创建一个单独的webpack文件,用于生成dll文件

在普通的webpack文件中进行引用生成的dll文件

// dll.js { entry: { // 需要提前打包的库 vendors: [ 'react', 'react-dom', 'react-router-dom', 'babel-polyfill', ], }, output: { filename: 'vendors.dll.js', path: path.resolve(__dirname, '../../client-dist'), // 输出时不要少了这个option library: 'vendors_lib', }, plugins: [ new webpack.DllPlugin({ context: __dirname, // 向外抛出的`vendors.dll.js`代码的具体映射,引用`dll`文件的时候通过它来做映射关系的 path: path.join(__dirname, '../dist/vendors-manifest.json'), name: 'vendors_lib', }) ] } // base.js { plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('../dist/vendors-manifest.json'), }), ] }

这样在watch文件时,打包就会跳过verdors中存在的那些包了。
有一点要注意的,如果最终需要上传这些静态资源,记得连带着verdors.dll.js一并上传

在本地开发时,vendors文件并不会自动注入到html模版中去,所以我们有用到了另一个插件,add-asset-html-webpack-plugin。
同时在使用中可能还会遇到webpack无限次数的重新打包,这个需要配置ignore来解决-.-:

// dev.js const HtmlWebpackPlugin = require('html-webpack-plugin') const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin') { plugins: [ // 将`ejs`模版文件放到目标文件夹,并注入入口`js`文件 new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../index.ejs'), filename: path.resolve(__dirname, '../../views/index.ejs'), }), // 将`vendors`文件注入到`ejs`模版中 new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, '../../client-dist/vendors.dll.js'), includeSourcemap: false, }), // 忽略`ejs`和`js`的文件变化,避免`webpack`无限重新打包的问题 new webpack.WatchIgnorePlugin([ /\.ejs$/, /\.js$/, ]), ] } TypeScript相关的配置

TS的配置分了两块,一个是webpack的配置,另一个是tsconfig的配置。

首先是webpack,针对ts、tsx文件我们使用了两个loader:

{ rules: [ { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'], exclude: /node_modules/, } ], resolve: { // 一定不要忘记配置ts tsx后缀 extensions: ['.tsx', '.ts', '.js'], } }

ts-loader用于将TS的一些特性转换为JS兼容的语法,然后执行babel进行处理react/jsx相关的代码,最终生成可执行的JS代码。

然后是tsconfig的配置,ts-loader的执行是依托于这里的配置的,大致的配置如下:

{ "compilerOptions": { "module": "esnext", "target": "es6", "allowSyntheticDefaultImports": true, // import的相对起始路径 "baseUrl": ".", "sourceMap": true, // 构建输出目录,但因为使用了`webpack`,所以这个配置并没有什么卵用 "outDir": "../client-dist", // 开启`JSX`模式, // `preserve`的配置让`tsc`不会去处理它,而是使用后续的`babel-loader`进行处理 "jsx": "preserve", "strict": true, "moduleResolution": "node", // 开启装饰器的使用 "experimentalDecorators": true, "emitDecoratorMetadata": true, // `vs code`所需要的,在开发时找到对应的路径,真实的引用是在`webpack`中配置的`alias` "paths": { "@Common": [ "../src/common" ], "@Common/*": [ "../src/common/*" ] } }, "exclude": [ "node_modules" ] } ESLint的配置

最近这段时间,我们团队基于airbnb的ESLint规则进行了一些自定义,创建了自家的eslint-config-blued
同时还存在了react和typescript的两个衍生版本。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgjjss.html