React依赖TypeScript工具包时Webpack Loader加载类失败问题
问题描述
我有两个TypeScript包:一个React应用,一个基础设施工具包。当前React应用通过npm link依赖这个工具包。在工具包中新增Job类后,运行React应用时出现以下错误:
Module parse failed: Unexpected token (4:8) File was processed with these loaders: * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js * ./node_modules/source-map-loader/dist/cjs.js You may need an additional loader to handle the result of these loaders. | | export class Job { > active: boolean; | address: string; | coordinates: any;
我查过的解决方案都需要修改Webpack配置,但我的两个包都没直接用Webpack(React底层默认用Webpack)。其他同类问题大多是因为用了??运算符,但我没用到这个运算符。
引发错误的Job类代码:
export class Job { active: boolean; address: string; coordinates: any; title: string; description: string; startDate: Date; endDate: Date; userId: number; id: number; constructor(data: any) { this.active = data.active; this.address = data.address; this.coordinates = data.coordinates; this.title = data.title; this.description = data.description; this.startDate = data.start_date; this.endDate = data.end_date; this.userId = data.user_id; this.id = data.id; } getLatitude = () => { return this.coordinates.x; }; getLongitude = () => { return this.coordinates.y; }; toGeoJSON = () => { return { type: "Feature", geometry: { type: "Point", coordinates: [this.getLongitude(), this.getLatitude()], }, properties: { id: this.id, title: this.title, description: this.description, address: this.address, }, }; }; }
解决方案
方法1:让工具包输出编译后的JavaScript
问题核心是React默认Webpack只处理自身node_modules里的已编译代码,npm link过来的工具包是TypeScript源码,未经过转译,Webpack识别不了TS的类属性类型声明。
- 工具包的
tsconfig.json确保配置正确:{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "declaration": true, "outDir": "./dist", "strict": true }, "include": ["src/**/*"], "exclude": ["node_modules"] } - 在工具包
package.json指定编译后的入口文件:{ "main": "./dist/index.js", "types": "./dist/index.d.ts" } - 执行工具包的编译命令(可在
package.json加"build": "tsc",然后跑npm run build)。 - 重新在React应用中link工具包,或重启React开发服务器。
方法2:让React的Webpack处理link过来的TS源码
如果不想每次改工具包都重新编译,可修改React的Webpack配置。如果是Create React App创建的项目,用craco修改:
- 安装依赖:
npm install --save-dev craco @craco/craco - 项目根目录创建
craco.config.js,添加配置:const path = require('path'); module.exports = { webpack: { configure: (webpackConfig) => { // 替换成你的工具包本地路径 const toolkitPath = path.resolve(__dirname, '../your-toolkit-folder'); webpackConfig.module.rules.push({ test: /\.(ts|tsx)$/, include: toolkitPath, use: ['babel-loader', 'ts-loader'], }); return webpackConfig; }, }, }; - 修改
package.json的启动命令:{ "scripts": { "start": "craco start", "build": "craco build", "test": "craco test" } } - 重启React开发服务器。
方法3:用npm pack替代npm link
如果link方式太麻烦,可在工具包生成本地包后安装:
- 工具包目录执行:
npm pack - 会生成类似
your-toolkit-1.0.0.tgz的文件,在React应用中安装:npm install ../path-to-toolkit/your-toolkit-1.0.0.tgz
这种方式安装的是编译后的代码,不会有转译问题,适合测试最终打包效果。
内容的提问来源于stack exchange,提问作者Jake Cirino
相关产品推荐
相关产品推荐

