微信开发者工具创建的typescript小程序目录结构并不能良好的使用npm的“自定义组件”,想要漂亮地使用“自定义组件”,得自行改造工程结构
注:这里是指wxml中使用的“自定义组件”,不是ts或js中可调用的纯js
问题现象分析如下:
微信开发者工具,创建出的Typescript小程序工程结构如下:
|--miniprogram
| |--pages
| |--app.js
| |--app.wxss
| |--app.json
|--typings
| |--wx
| |--index.d.ts
| |--lib.wa.es6.d.ts
|--package.json
|--project.config.js
|--ts.json
这样的结构,小程序根目录在miniprogram,导致package.json不在小程序根目录内,也即node_modules目录中的第三方组件不在小程序根目录,违背了npm支持中node_modules位置的要求:npm 支持-使用npm包
此时,如果app.json或index.json中,无论如何引用不到node_modules中的第三方组件(注意是第三方开发的微信“自定义组件”,如vant-weapp,而纯js是可用的)
如:
图中的"…/node_modules"无论如何修改,控制台也会报类似的错误:
问题原因:
经过测试,存在两个约束导致了以上问题:
- app.json或index.json(以及任何页面的配置文件)的"usingComponents"不能引用node_modules目录下的组件;
- "usingComponents"只能引用小程序根目录(此例是miniprogram)及子目录下的组件。
通过以下步骤,就可以验证:
- 将node_modules下的vant-weapp目录复制到miniprogram目录下,"usingComponents"修改为其相对位置,组件即可用:
|--miniprogram
| |--pages
| |--app.js
| |--app.wxss
| |--app.json
| |--want-weapp
|--typings
| |--wx
| |--index.d.ts
| |--lib.wa.es6.d.ts
|--package.json
|--project.config.js
|--ts.json
成功使用自定义组件的效果:
2. 如果vant-weapp放在miniprogram以外的目录,仍然引用不到。
但是,有代码洁癖的同学肯定不能满足于,把所有的依赖都手工复制到miniprogram目录这么弱智的操作方法吧?
解决方案:
怎样才能做到npm安装的组件,可以直接在小程序中引用呢?
其实答案就在npm 支持这篇文章里,只不过其写的比较含糊,没有解释清楚细节,总结起来就是对模板工程做两步改造,分别解决上面提到的两个问题:
- 将小程序根目录即miniprogram移动到与package.json同级别;
- 使用“npm构建”功能(将node_modules目录的组件构建到miniprogram_npm目录下)构建后,再直接引用组件即可使用。
操作步骤如下:
第一步:移动miniprogram目录下的所有文件到根目录(与package.json同级):
|--pages
|--app.js
|--app.wxss
|--app.json
|--want-weapp
|--typings
| |--wx
| |--index.d.ts
| |--lib.wa.es6.d.ts
|--package.json
|--project.config.js
|--ts.json
第二步:修改project.config.json,去掉下面这行:
"miniprogramRoot": "miniprogram/",
或者修改为
"miniprogramRoot": "./",
第三步:修改tsconfig.json中的include/exclude以确保自己的ts代码被编译:
"include": [
"./miniprogram/**/*.ts"
],
"exclude": [
"node_modules",
"miniprogram_dist",
"miniprogram_npm",
"**/*.spec.ts",
"typings/**/*.d.ts"
]
改为
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules",
"miniprogram_dist",
"miniprogram_npm",
"**/*.spec.ts",
"typings/**/*.d.ts"
]
说明:include目录外移一层,同时exclude掉typings和miniprogram_npm目录
第四步:使用微信开发者工具的“工具-构建npm”功能构建组件到miniprogram_npm目录
第五步:在app.json(或者页面的json配置)里面引入组件
"usingComponents": {
"van-button": "vant-weapp/button/index"
}
注意:这里使用相对于miniprogramnpm的目录就可以了,并不需要相对于app.json文件
后记:
微信开发者工具创建出的typescript小程序,本意应该是将小程序根目录与typescript、node环境隔离开来,提供一个清晰的目录结构,但是对npm集成、“自定义组件”支持的不佳,说明了微信团队在“自定义组件”,npm支持,typescript支持还处在起步阶段,团队间的磨合还不到位,文档也不够透彻,当然这需要时间去改进。
我希望微信小程序团队通过以下几点,能很快地原生支持typescript+npm+第三方自定义组件:
1、调整微信开发者工具的typescript小程序模板工程结构,或者反过来让支持现在的工程结构下使用第三方的npm自定义组件;
2、完善npm支持相关的文档,如果自己完善不来,其实可以用wiki的方式,鼓励广大开发者一起来完善
npm支持做两点改造也能不动工程结构解决此问题:
1、构建npm是基于project.config.json的位置找package.json,而不是“miniprogramRoot”;
2、node_modules位置也应以project.config.json为准,而不是“miniprogramRoot”。
总之“miniprogramRoot”只是用来整理代码结构的一个配置,小程序再怎么变也离不开project.config.json,而不是miniprogrammRoot
恶心
好文章
新建的Typescript小程序,还没加什么功能,包大小就快7M
这个问题怎么解决,也要分包吗?@CT
可以换一种思路,可以把跟miniprogram同级的所有文件夹移动到miniprogram(node_modules),其他步骤如博主所述
现在支持的挺好的了,已经用了2个项目了差不多,后续都是用TS来做开发了。
https://github.com/wechat-miniprogram/api-typings