公司的taro项目需要引入一个其他团队的组件,如下:
import { LibAdvSwiper } from '@fta/components-lib-adv/index'
引入后小程序在编译过程中报了语法问题:
./node_modules/@fta/components-lib-adv/src/swiper.tsx 5:21
Module parse failed: Unexpected token (5:21)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import React, { useEffect } from 'react'
| import { COMMON_PARAMS } from './const'
> export default (props: any) => {
| const {
| indicatorDots = false,
而这个@fta/components-lib-adv就是本次引入的组件。
从报错信息来看,本来以为是没有解析对应语法的loader,但是看提示错误的信息行是个简单的ES5语法,本项目中是肯定支持ES5语法的。因此可以确定是引入的组件内部出现了问题。
去node_modules中查看对应的组件:
可以看到项目中既没有打包后的dist文件,也没有node_modules,这就会有问题。
项目在打包过程中会使用babel将ES 2015+版本的代码转换为向后兼容的js语法,而node_modules会添加项目需要的依赖,如果缺少这两个文件的话,那就意味着我们需要手动添加在node_modules中的@fta/components-lib-adv组件的编译,同时查看@fta/components-lib-adv中依赖的组件是否本项目中都有。
方法1:手动添加对@fta/components-lib-adv组件的编译
修改config/index.js配置文件,让bable单独编译node_modules里的库:
mini: {
compile: {
// 额外执行预编译的依赖
include: [path.resolve(__dirname, '..', 'node_modules/@fta/components-lib-adv')],
},
}
方法2:让组件提供方对组件打包,生成dist文件,同时修改组件引入方式:
import { LibAdvSwiper } from '@fta/components-lib-adv/dist/weapp'
解决了上面babel的问题之后重新编译,发现又报错:
./node_modules/@fta/components-lib-adv/dist/weapp/index.js
Module not found: Error: Can't resolve '@fta/components' in '/Users/liyueyun/Desktop/ymm/code/miniapp-short-distance/node_modules/@fta/components-lib-adv/dist/weapp'
resolve '@fta/components' in '/Users/liyueyun/Desktop/ymm/code/miniapp-short-distance/node_modules/@fta/components-lib-adv/dist/weapp'
这次报错的组件为@fta/components
,查看本次引入的组件@fta/components-lib-adv
的package.json:
发现项目的peerDependencies中有@fta/components
这个依赖,但是查看我们自己的项目中并没有这个依赖,而引入的@fta/components-lib-adv
连node_modules都没有,也就是说,我们需要额外的引入@fta/components
,这个问题也就是上面提到的引入的组件中没有node_modules可能会导致的问题。
方法:npm install @fta/components
后重新启动项目,发现可以正常使用组件了。
当时以为问题解决了,准备打小程序的体验版的包测试,结果编译过程中报了错:
[7m./node_modules/@fta/components/common/context/index.tsx 12:0[27m
Module parse failed: The keyword 'interface' is reserved (12:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| } from 'react'
这个问题在我本地项目中并没有出现,但是在通过平台打体验包的时候出现了,而且是ts的语法问题。我本地用的是npm安装包,以及启动项目,但是平台默认的是yarn安装包以及启动,初步判断是npm和yarn在安装依赖的时候版本或其他不一致,导致一个没问题一个有问题。
模拟:
删除node_modules,重新用yarn安装依赖,启动后问题果然出现。
首先可以看出,是@fta/components
这个包下面有个文件用了ts语法,并且没有ts-loader来解析和编译,因此报错。实际上我们的项目很多地方都用了ts语法,ts-loader肯定是有配置的。
查看项目的tsconfig.json,找到了里面的配置:
"exclude": [
"node_modules",
"dist"
],
也就是说,我们的项目并不会对node_modules里的依赖进行ts的语法解析,那么就是说明@fta/components
这个包里有些文件没有打包。找到公司提供@fta/components
的团队,联系他们排查没有打包的组件并重新打包,后来问题解决。
实际上我们自己的项目或者@fta/components-lib-adv
组件提供方都可以在tsconfig.json中将exclude的node_modules删去,但是这样做会导致整个项目编译的时间大大增加,体验会非常不友好。这种解决方式不考虑。
关于npm和yarn安装包的区别:
实际上我们可以通过yarn.lock以及package-lock.json的对比,来判断到底是哪个依赖安装错误导致的问题,但是考虑到公司的依赖非常多,这两个文件几千行,对比起来很耗时,就没有进行详细对比。
简单列一下这两者的对比:
以后安装包和启动项目,还是选择yarn。