微信小程序第三方自定义组件开发详细流程

1,539 阅读4分钟
  1. 微信官方文档:developers.weixin.qq.com/miniprogram…
  2. 组件demo的仓库地址:gitee.com/mayxue/mini…
  3. npm包的链接:www.npmjs.com/package/xx-… (仅测试的demo)

一、下载模板

1. 官方提供了命令行工具,用于快速初始化一个项目。执行如下命令安装命令行工具:

npm install -g @wechat-miniprogram/miniprogram-cli

2. 然后新建一个空目录作为项目根目录,在此根目录下执行:

2.1 安装模板的命令:

miniprogram init --type custom-component

2.2 安装模板需要填写的信息(包的名称、版本、打包后文件的名称、包的存放仓库、作者)

D:\mayGit\miniprogram\miniprogram-component-demo>miniprogram init --type custom-component

? please input the package name miniprogram-component-demo

? please input the package version 1.0.0

? please input the miniprogram dist folder miniprogram_dist

? please input the git repository url <https://gitee.com/mayxue/miniprogram-component-demo.git>

? please input the author may

2.3 新建一个空的文件夹(miniprogram-component-demo),用来存放模板文件

二、项目运行、配置

1. 通过微信开发者工具打开下载好的官方模板

2. 官方的项目模板目录

3. 安装依赖,执行完后会生成node_modules文件夹

npm install

4. 执行命令

npm run dev

默认会在包根目录下生成 miniprogram_dev 目录,src 中的源代码会被构建并生成到miniprogram_dev/components 目录下。(小程序开发者工具预览效果打开的也是这个目录)

5. 使用微信开发者工具打开项目(打开 miniprogram_dev文件夹,其他文件,开发者工具编译不了,会报错)

5.1 项目->导入项目->选择(上面一步生成的 miniprogram_dev 文件夹)

5.2 点击编译按钮

三、文件夹的关系

1. node_modules:执行npm install生成的依赖文件
2. src:开发自定义组件及相关文件存放的地方(源文件存放的地方),
3. test:测试文件
4. tools:工具文件夹
5. miniprogram_dev:执行npm run dev生成的文件夹(miniprogram_dev中的components文件夹中的文件全部来自于src中,其他文件全部来自于tools中的demo文件夹中的文件)
- 执行npm run dev的时候,会将src文件夹里的内容复制到miniprogram_dev底下的components文件下;
- 执行npm run dev的时候,会将tools底下的demo文件夹里的内容复制到miniprogram_dev的根目录下;

四、组件的开发

1. 开发时的注意事项

1. 因为微信开发者工具只能编译miniprogram_dev里的文件,所以微信开发者工具可打开miniprogram_dev夹查看项目的修改情况;
2. 在vscode里打开整个项目miniprogram-component-demo;修改src的内容时,执行npm run dev;miniprogram_dev里的内容是不可以实时更新的;
3. 执行npm run watch,会监听 tools 目录下的 demo 变动并进行拷贝;

2. 删除模板里的文件

2.1 miniprogram-component-demo -> src

2.2 miniprogram-component-demo -> tools -> config.js

2.2.1 出口文件,根据自己的情况配置

2.2.2 eslint的校验:写js文件时有个坑就是eslint的校验,如果你的代码不符合规范,就会各种报错,然后编译不通过,这里我是暂时先选择关闭了校验

const path = require('path')

const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')

const isDev = process.argv.indexOf('--develop') >= 0
const isWatch = process.argv.indexOf('--watch') >= 0
const demoSrc = path.resolve(__dirname, './demo')
const demoDist = path.resolve(__dirname, '../miniprogram_dev')
const src = path.resolve(__dirname, '../src')
const dev = path.join(demoDist, 'components')
const dist = path.resolve(__dirname, '../miniprogram_dist')

module.exports = {
  entry: ['index'],

  isDev,
  isWatch,
  srcPath: src, // 源目录
  distPath: isDev ? dev : dist, // 目标目录

  demoSrc, // demo 源目录
  demoDist, // demo 目标目录

  wxss: {
    less: false, // 使用 less 来编写 wxss
    sourcemap: false, // 生成 less sourcemap
  },

  js: {
    webpack: true, // 使用 webpack 来构建 js
  },

  webpack: {
    mode: 'production',
    output: {
      filename: '[name].js',
      libraryTarget: 'commonjs2',
    },
    target: 'node',
    externals: [nodeExternals()], // 忽略 node_modules
    module: {
      rules: [{
        test: /.js$/i,
        use: [{
          loader: 'thread-loader',
        }, {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
          },
        },
          // {
          //   loader: 'eslint-loader',
          // }
        ],
        exclude: /node_modules/
      }, {
        test: /.ts$/,
        exclude: /node_modules/,
        use: [{
          loader: 'thread-loader',
        }, {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
          },
        }, {
          loader: 'ts-loader',
          options: {
            appendTsSuffixTo: [/.vue$/],
            happyPackMode: true,
          },
        },
          // {
          //   loader: 'eslint-loader',
          // }
        ],
      }],
    },
    resolve: {
      modules: [src, 'node_modules'],
      extensions: ['.js', '.json'],
    },
    plugins: [
      new webpack.DefinePlugin({}),
      new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
    ],
    optimization: {
      minimize: false,
    },
    devtool: 'source-map', // 生成 js sourcemap
    performance: {
      hints: 'warning',
      assetFilter: assetFilename => assetFilename.endsWith('.js')
    }
  },

  copy: ['./assets'], // 将会复制到目标目录
}

3. 新建自定义组件

3.1 自定义组件目录:src

3.2 引入自定义组件:index.json

3.3 在页面中使用自定义组件:index.wxml

3.4 组件要传递的参数

五、组件的打包、发布

1. 打包

npm run build

2. 发布

2.1 如果还没有npm账号的,可以先到npm官网先注册一个账号

2.2 发布之前一定要检查下你当前的源是不是npm的源,很有可能之前你改过源为taobao的

2.2.1 检查当前npm的源
npm config get registry

2.2.2 切换为npm的源
npm config set registry https://registry.npmjs.org/

2.3 在本地登录npm账号,执行

npm adduser 或 npm login

2.4 发布组件到npm上

npm publish

2.5 查看发布的npm包

www.npmjs.com/package/xx-…

五、在小程序项目中使用npm组件

1. 新建小程序项目

2. 初始化项目

  • npm init -y:对项目进行初始化操作,对包进行管理
  • -y 的含义:yes的意思,在init的时候省去了敲回车的步骤,生成的默认的package.json
npm init -y

3. 安装npm插件

npm i xx-wx-ad-component

4. 构建npm

工具 -> 构建npm -> 在根目录下会自动生成miniprogram_npm文件夹

5. 在项目中使用npm组件

5.1 index.wxml

<!--index.wxml-->
<view class="container">
  <xx-wx-ad-component adType="{{adType}}"></xx-wx-ad-component>
</view>

5.2 index.json

{
  "usingComponents": {
    "xx-wx-ad-component": "xx-wx-ad-component"
  }
}

5.3 index.js

// index.js
// 获取应用实例
const app = getApp()

Page({
  data: {
    adType: 'fsAd',
  },
})

5.4 效果