Frontend Development 15 min read

How to Build a React‑Kbone Mini‑Program: From Setup to Optimization

This article walks through using Kbone to create a React‑based mini‑program that shares code with an existing H5 page, covering framework choice, webpack and Babel configuration, code reuse strategies, bundle size optimization, and practical lessons learned.

Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
How to Build a React‑Kbone Mini‑Program: From Setup to Optimization

Background

Kbone is WeChat's solution for web and mini‑program code‑sharing, supporting Vue and React. The Tencent Classroom "new‑user course gift" page needs to run on H5, mini‑program, and app, and using a web‑view in the mini‑program would lose native capabilities such as phone number binding.

Framework Selection

Most React‑to‑mini‑program solutions (e.g., Taro, Nanachi) rely on static compilation, which sacrifices dynamic JavaScript features and lags behind React updates. Kbone, by providing

miniprogram-render

and

miniprogram-element

, fully supports React and JSX without such limitations.

React‑Kbone Mini‑Program Process

The official

kbone-template-react

example builds the mini‑program with Webpack. It uses Babel to transform React code and

mp-webpack-plugin

to generate mini‑program files (e.g.,

app.*

,

pages/*

,

project.config.json

) after the web build.

Core modules

miniprogram-render

and

miniprogram-element

are installed via npm.

The

common

directory contains transformed business code and third‑party libraries.

Integrating into Existing Project

The gift page consists of two existing projects: m-core (H5, Webpack 4 + Babel 7 + React ^16.8 + TypeScript) and weapp‑ke (native mini‑program). To keep H5 functional, the new page code is placed in

m-core

and a custom

webpack.mp.config.js

is added. The mini‑program build generates a split package to avoid inflating the main bundle, and unnecessary files are removed by adjusting

mp-webpack-plugin

.

Build Configuration

<code>{
  test: /\.(ts|js)x?$/,
  use: [
    'thread-loader',
    {
      loader: 'babel-loader?cacheDirectory',
      options: isMp ? {
        configFile: false,
        presets: ['@babel/preset-typescript', '@babel/preset-react'],
        plugins: ['@babel/plugin-proposal-class-properties']
      } : {
        configFile: path.resolve(rootDir, 'babel.config.js')
      }
    },
    {
      loader: 'webpack-strip-block',
      options: {
        start: isMp ? 'strip-block--h5-only:begin' : 'strip-block--mp-only:begin',
        end: isMp ? 'strip-block--h5-only:end' : 'strip-block--mp-only:end'
      }
    }
  ],
  include: [path.resolve(rootDir, 'src'), path.resolve(rootDir, 'node_modules/@tencent')],
  sideEffects: !isMp
}
</code>

For mini‑program builds,

@babel/preset-env

and plugins like

@babel/plugin-transform-runtime

are omitted because the mini‑program devtools already handle ES6→ES5 conversion.

Code Writing

To reuse existing mini‑program utilities,

webpack.externals

excludes them from the output, allowing the mini‑program at runtime to load the original modules. An alias is created for the utils directory:

<code>resolve.alias.weappKeUtils = path.resolve(weappKeDir, 'utils');</code>

Example of importing a mini‑program router:

<code>import * as keRouter from 'weappKeUtils/router';
export function refresh() {
  if (process.env.isMiniprogram) {
    keRouter.refresh();
  } else {
    window.location.reload();
  }
}
</code>

Special handling is required for

open-type

button callbacks that are not part of React's event system. A custom

WxButton

component binds these callbacks to the DOM so Kbone can forward them.

<code>processWxEvents = (fn) => {
  if (process.env.isMiniprogram) {
    Object.keys(this.props).forEach(k => {
      if (k.indexOf('wxOn') === 0) {
        const eventName = `on${k.slice(4)}`;
        fn(eventName, this.props[k]);
      }
    });
  }
};
</code>

Mini‑Program Page Optimization

The original mini‑program bundle was ~1350 KB. After Kbone integration the split package grew to ~800 KB, with an additional ~200 KB over the main bundle.

React runtime : ~120 KB (compressed).

Kbone adapter (

miniprogram-element

+

miniprogram-render

): ~180 KB.

Business wxss : ~350 KB before compression.

Business js : ~340 KB before compression.

Optimization focused on the business code:

Removed large base64 background images and duplicated iconfont from CSS, moving the background to CDN and sharing the iconfont via global styles, reducing wxss to ~90 KB.

Enabled Tree Shaking by using ES2015 module syntax, setting

sideEffects

in

package.json

, and avoiding

modules: 'commonjs'

in Babel.

Externalized shared npm packages and mini‑program utils via

externals

to avoid duplication.

After these steps the final bundle size is ~420 KB (≈300 KB third‑party libraries, 120 KB activity page split package), which does not affect the main bundle size.

Conclusion

Kbone enables low‑cost integration of existing H5 projects into mini‑programs with minimal code changes—only environment‑specific logic guarded by

process.env.isMiniprogram

is needed. Development experience is smooth and performance comparable to native development for simple pages. Remaining challenges include improving the

webpack-strip-block

loader to avoid import order issues.

Kbone logo
Kbone logo
H5 page screenshot
H5 page screenshot
Mini‑program page screenshot
Mini‑program page screenshot
QR code for testing
QR code for testing
FrontendMiniProgramReactWebpackkboneCodeReuseTreeShaking
Tencent IMWeb Frontend Team
Written by

Tencent IMWeb Frontend Team

IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.