想要实现一个属于自己的组件库,搜索微信官方文档发现 已经提供了比较方便的命令工具:
1、官方提供的组件只有一个src下的的index.wxml,组件库自然是需要多入口的
2、没有支持ts
因此想实现一个ts小程序组件库,需要解决上面的两个问题。
一、分析
用miniproram命令构建一个基础的项目后,现阶段的想法是 将组件放到src目录下
index.js文件会做为打包后的dist目录下的入口文件,是个空文件也行,到时候打包之后就会被新内容覆盖
研究了一下微信官方打包的方式,发现使用了webpack和gulp混用的方式去打包
二、实现多入口
明确目标:修改component-check 任务。 打开 tools下面的check-components.js 文件: 将原本最后执行的compoenntsListMap.push操作放入for循环中执行,这样每次遍历一个文件夹后就会将文件引入其中
/**
* 检测是否包含其他自定义组件
*/
//对齐小程序通用引用组件方式,这里只使用usingComponents这一种
const checkProp = 'usingComponents';
const hasCheckMap = {}
async function checkIncludedComponents(jsonPath, componentListMap) {
const json = _.readJson(jsonPath)
if (!json) throw new Error(`json is not valid: "${jsonPath}"`)
const {dirPath, fileName, fileBase} = getJsonPathInfo(jsonPath)
if (hasCheckMap[fileBase]) return
hasCheckMap[fileBase] = true
const checkPropValue = json[checkProp] || {}
const keys = Object.keys(checkPropValue)
for (let j = 0, jlen = keys.length; j < jlen; j++) {
const key = keys[j]
let value = typeof checkPropValue[key] === 'object' ? checkPropValue[key].default : checkPropValue[key]
if (!value) continue
value = _.transformPath(value, path.sep)
// 检查相对路径
const componentPath = `${path.join(dirPath, value)}.json`
const isExists = await _.checkFileExists(componentPath)
if (isExists) { //存在便将所有文件推入对应列表
// 进入存储
componentListMap.wxmlFileList.push(`${value}.wxml`)
componentListMap.wxssFileList.push(`${value}.wxss`)
componentListMap.jsonFileList.push(`${value}.json`)
componentListMap.jsFileMap[value] = `${path.join(dirPath, value)}.js`
//jsMap包含index入口文件,每个组件都应该被引入
componentListMap.jsFileList.push(`${value}.js`)
// await checkIncludedComponents(componentPath, componentListMap)
}
}
componentListMap.jsFileMap[fileBase] = `${path.join(dirPath, fileName)}.js`
}
这时候在执行 npm run build ,可以发现已经被打包成功并被index文件export出去了。
三、实现js升级ts
1、安装依赖
既然要升级ts,就必须要有typescript的支持,需要安装下面的包
npm install ts-loader --save-dev
npm install typescript --save-dev
2、修改文件名
将.js后缀的组件改成.ts,同时check-components.js / checkIncludedComponents这个方法下面也需要将推进去的文件名进行修改:
3、增加ts配置
tools/config.js
webpack: {
mode: 'production',
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
},
target: 'node',
externals: [nodeExternals()], // 忽略 node_modules
module: {
rules: [{
test: /\.js$/i,
use: [
'babel-loader',
'eslint-loader'
],
exclude: /node_modules/
},{ //新增ts打包逻辑 ---------------
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
// 指定特定的ts编译配置,为了区分脚本的ts配置
configFile: path.resolve(__dirname, '../tsconfig.json'),
},
},
],
exclude: /node_modules/,
} -------------新增结束
],
},
resolve: {
modules: [src, 'node_modules'],
extensions: ['.ts','.tsx', '.json'],
},
plugins: [
new webpack.DefinePlugin({}),
new webpack.optimize.LimitChunkCountPlugin({maxChunks: 1}),
],
optimization: {
minimize: false,
},
// devtool: 'nosources-source-map', // 生成 js sourcemap
performance: {
hints: 'warning',
assetFilter: assetFilename => assetFilename.endsWith('.js')
}
},
同时在根目录下创建一个tsconfig.json文件,在将ts编译成js时会根据这个文件的配置进行编译
这时候尝试npm run build,会报如下错误:
第二种错误 这是因为ts需要由类型声明文件,打开微信小程序官方文档,找到定义文件,
执行 npm install miniprogram-api-typings
ok,到这里就将小程序变成了ts和多入口。 小白第一次写文章,不足之处希望大佬指出,以后改进! 另外还有疑问,npm安装小程序官方typings并不生效,不太理解
查了一下github的issue,找到了下载typing也不生效的原因: github.com/wechat-mini…