小程序 组件库模板 升级ts (一)

1,297 阅读3分钟

想要实现一个属于自己的组件库,搜索微信官方文档发现 已经提供了比较方便的命令工具:

选择custom-component 就可以进行安装,但是安装后发现有几个问题没有被解决:
1、官方提供的组件只有一个src下的的index.wxml,组件库自然是需要多入口的
2、没有支持ts

因此想实现一个ts小程序组件库,需要解决上面的两个问题。

一、分析

用miniproram命令构建一个基础的项目后,现阶段的想法是 将组件放到src目录下

像上图那样定义src结构,然后由index.json统一收敛需要暴露出去的组件。
index.js文件会做为打包后的dist目录下的入口文件,是个空文件也行,到时候打包之后就会被新内容覆盖

研究了一下微信官方打包的方式,发现使用了webpack和gulp混用的方式去打包

运行 npm run build 实际上是执行了gulp.task('default')这一句,然后去 build.js里面找,发现build任务实际上由三个任务组成:

1、clean-dist,做的事情就是清除生成的build后的目录 2、component-check,找到所有需要被编译的文件 3、并行编译 各类型文件

二、实现多入口

明确目标:修改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这个方法下面也需要将推进去的文件名进行修改:

研究build.js下面编译js的代码可以发现,这一块的打包使用的是webpack,因此需要去tools/config.js文件下修改webpack的配置,让他能打包ts文件

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,会报如下错误:

这是两种错误, 第一种错误 解决方法: npm install @types/node –save
第二种错误 这是因为ts需要由类型声明文件,打开微信小程序官方文档,找到定义文件,
执行 npm install miniprogram-api-typings
这时候问题来了。。。即使我安装了这个typings,还是报同样的错误,ts2304 于是,我换了一种方式,将node_modules/miniprogram-api-typings下面的typins文件夹和index.d.ts文件复制到src目录下,就发现打包成功了。。。这个地方先存疑= =

ok,到这里就将小程序变成了ts和多入口。 小白第一次写文章,不足之处希望大佬指出,以后改进! 另外还有疑问,npm安装小程序官方typings并不生效,不太理解


查了一下github的issue,找到了下载typing也不生效的原因: github.com/wechat-mini…