这里写目录标题
背景介绍
目前项目的开发语言是TypeScript,前后端的代码在一个project中,后端部分类引用了前端的一些类。项目结构如下
src
|-server
|-frontend
前端代码构建是通过webpack构建,即完成编译和bundle两个过程。
后端代码构建只有编译这个步骤。
现在项目编译有一个不足之处:因为后端依赖前端,所以后端编译之后,依赖前端的部分也会添加到dist中。编译后的结构如下。
//之前
dist
|-server
|-static
|-frontend
//移除之后的目标
dist
|-server
|-static
因此需要想方法移除后端对前端的直接依赖,最后的目标是后端编译后前端的代码不进入到dist。
移除思路
- 目前后端依赖前端的部分,通过webpack打包成一个单独的js文件
- 新建一个.d.ts文件,文件中声明后端依赖前端的接口、类以及函数等(有声明文件可以保证编译不报错)
- 代码运行的过程中依赖第1步打包的js文件,保证运行期没问题
上述思路和三方库的构建发布类似,但是架构师的意思是不希望实现过程完全和构建三方库一样。
实现过程
后端依赖前端的部分单独打包成一个js文件
通过webpack打包,webpack会帮我们处理类依赖。
实现方案:
-
新建一个ts文件,文件中re-export后端依赖的接口
export { FrontEndClass } from 'frontend/class'; -
新建的ts文件作为entry point,webpack打包
-
webpack构建,获取到打包后的js文件
编写.d.ts文件
官方说明 https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html
因为接触TypeScript项目没多久,还没有系统了解相关概念,因此有如下疑惑:
.d.ts文件是什么?- 为什么要编写
.d.ts文件?
TypeScript是JavaScript的超集,它主要的一个功能就是类型检查,.d.ts文件便是用于类型检查。
因为目前社区中很多三方库都是JavaScript写的,TypeScirpt项目中如果依赖三方库,那么如果没有类型声明文件,会导致编译失败。
TypeScript项目的流程:TypeScript --compile–> JavaScript --> Run。
TypeScript项目编译的时候会做类型检查,如果没有声明文件会编译失败。(声明文件的另一个用处是开发的时候提示)。
因此我们现在清楚要写一个的声明文件需要满足的需求:后端依赖之后可以成功编译
基于这个需求,我们有如下备选方案:
- 是否有软件可以基于上述re-export的ts文件生成声明文件,并且完美解决文件依赖。
- 是否有软件可以基于打包后的js,生成对应的声明文件
- 自己写一个声明文件(不足之处:前端相应类改动后需要维护)
方案一:基于re-export文件生成.d.ts
网上查阅了解到的一些工具:
- dts-bundle-generator
- rollup-plugin-ts
- tsc-prog
- API-Extractor
上述工具都没有满足最终需求。
dts-bundle-generator
Small tool to generate a dts bundle from your ts code.
https://www.npmjs.com/package/dts-bundle-generator
这个工具可以实现指定entry point把多个.d.ts文件打包生成一个.d.ts,并且会把打包过程中生成的依赖类的.d.ts文件删除。
–project参数用于指定编译时的tsconfig文件。
dts-bundle-generator -o output.d.ts entrypoint.ts --project tsconfig.json
该工具的不足之处:如果依赖文件中有两个接口同名,那么最后生成的文件会冲突
dts-bundle
官方文档
Export TypeScript .d.ts files as an external module definition
https://github.com/TypeStrong/dts-bundle
不支持打包.d.ts
rollup-plugin-ts
tsc-prog
API-Extractor
一个rollup .d.ts以及生成Api Doc的工具
https://api-extractor.com/pages/setup/invoking/
简单的export,并没有实现dts bundle
方案二:基于bundle.js生成.d.ts
查阅TypeScript官方手册,有js生成对应.d.ts文件的说明,tsconfig.json中编译选项增加declaration: true就可以,但是该说明偏向于是js项目转ts项目时整个生成对应的.d.ts。
新建js文件,执行命令npx tsc,然后在dist目录生成了对应的.d.ts文件,但是对于打包后的js文件,效果不好。
dts-gen
微软的声明文件生成工具
目测适用于为三方库生成
为打包后的js生成声明文件不理想
dtsmake
工具安装后执行时一直提示缺少某个包,可能是因为js文件是打包后的文件。
方案三:自己写
基于方案一中dts-bundle-generator工具生成的文件,只把前端需要的接口和函数保留,其他的都删除。
最后测试也是可行的,但是维护成本比较高。
最终方案
- 新建tsconfig.json,配置生成
.d.ts文件,配置生成目录outDir,其他配置和server端配置保持一致 - 以re-export文件为entry point,webpack打包的时候指定tsconfig.json
最后的效果就是所有re-export文件依赖的声明文件都打包到了outDir。这样做的好处是后期维护方便,packae.json中新增一个srcipt,每次构建前端项目的时候把这个脚本也执行一下,最后结构如下
ourDir
|-frontend
|-entryDep
|-entry.d.ts
后端如何import声明文件
模块导入分为相对路径导入或者非相对路径导入。
拷贝最终方案中生成的outDir至src下,tsconfig.json编译选项的模块解析paths新增src/outDir/frontend/*
修改后端依赖前端部分的import
//修改前
import { serverDep } from './frontend/server/dep/class';
//修改后
import { serverDep } from 'entry'
配置之后,实际编译时,解析entry的实际路径为src/outDir/frontend/entry.d.ts,因此编译正常。
打包的js文件放在哪里
webpack中配置打包后的js输出路径为和entry.d.ts同级目录,即webpack构建后的outDir文件结构如下:
ourDir
|-frontend
|-entryDep
|-entry.d.ts
|-entry.js
上述所有文件拷贝至src路径下,后端项目编译之后,js文件会拷贝至dist目录,dist文件结构如下:
dist
|-server
|-outDir
|-frontend
|-entry.js
遇到的问题
webpack build报错
# 报错:
TS2749: 'Direction' refers to a value, but is being used as a type here
# 报错原因
webpack配置文件是拷贝的项目中已有文件进行改造的,因为认为resolve部分没用就删除了。
resolve是用来处理代码中的import。
代码中的import没有指明文件后缀,因此需要resolve解决如下问题:
* 配置动态路径解析。通过相对路径确定import文件的位置
* 配置文件后缀组。按顺序逐个拼接文件名和后缀匹配指定路径下的文件
# 解决
resolve增加配置选项如下:
* extensions: 定义后缀数组,和文件名组合查找
* plugin: 使用插件,比如tsconfig-paths-webpack-plugin插件可以用于动态路径解析
运行提示从entry.js中找不到构造函数
# 报错
Failed on json tracking fixer: TypeError: frontend_1.Model is not a constructor
# 报错原因
webpack默认打包的文件应该是用于浏览器中,如果要用于其他环境,比如nodejs中,需要配置导出为模块以及配置导出类型
# 解决
解决参考webpack官方文档https://webpack.docschina.org/guides/author-libraries/#authoring-a-library
这篇文章是解决问题的关键
webpack.config.js的output属性主要是增加了如下两个配置:
library: 'entry',
libraryTarget: "umd"
这两个配置实现最终导出为library,其可以与 CommonJS、AMD 以及 script 标签使用。
本文探讨了如何在TypeScript项目中移除后端对前端的直接依赖,通过webpack打包分离依赖并创建.d.ts声明文件,以确保后端编译时前端代码不会包含在内。涉及的解决方案包括基于re-export的打包和.d.ts生成,以及webpack配置调整。
417

被折叠的 条评论
为什么被折叠?



