小程序引入外部组件后报loader和ts语法问题的处理

一 问题回顾

公司的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中查看对应的组件:
小程序引入外部组件后报loader和ts语法问题的处理_第1张图片
可以看到项目中既没有打包后的dist文件,也没有node_modules,这就会有问题。

项目在打包过程中会使用babel将ES 2015+版本的代码转换为向后兼容的js语法,而node_modules会添加项目需要的依赖,如果缺少这两个文件的话,那就意味着我们需要手动添加在node_modules中的@fta/components-lib-adv组件的编译,同时查看@fta/components-lib-adv中依赖的组件是否本项目中都有。

二 解决过程

1.bable问题的解决过程

方法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'

请添加图片描述

2.引入组件后需要添加依赖的解决方案

解决了上面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:小程序引入外部组件后报loader和ts语法问题的处理_第2张图片
发现项目的peerDependencies中有@fta/components这个依赖,但是查看我们自己的项目中并没有这个依赖,而引入的@fta/components-lib-adv连node_modules都没有,也就是说,我们需要额外的引入@fta/components,这个问题也就是上面提到的引入的组件中没有node_modules可能会导致的问题。
方法:npm install @fta/components后重新启动项目,发现可以正常使用组件了。

3.ts语法以及npm和yarn安装依赖的问题

当时以为问题解决了,准备打小程序的体验版的包测试,结果编译过程中报了错:

[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可以并行安装,因此比npm速度更快;
  • yarn可以做到安装版本统一,而npm需要通过shrinkwrap命令生成npm-shrinkwrap.json文件后,packages版本信息才能被记录和更新;
  • yarn可以做到依赖包被不同的库关联引用后,只从一个注册来源去装,防止出现混乱;
  • yarn的离线模式可以直接从缓存中获取之前已经安装过的包,不用再从网络下载;

以后安装包和启动项目,还是选择yarn。

你可能感兴趣的:(小程序,小程序,前端,javascript)