How to Use Webpack for Mini‑Program File Dependency Analysis
This article explains how to leverage Webpack to perform comprehensive file dependency analysis for WeChat mini‑programs, covering the creation of dynamic entry files, custom loaders for wxss, wxml, wxs, and json, handling path issues, and preparing resources for efficient packaging.
1. Introduction
Last October I shared a talk on "Mini‑Program Engineering Exploration" and received many requests for implementation details. I decided to write a series on mini‑program engineering, focusing each article on a single point. This first article explains how to use Webpack to analyze file dependencies in mini‑program code.
2. Early packaging methods for mini‑programs
The built‑in developer tools convert ES6 to ES5 and minify JavaScript, but they lack Sass/PostCSS support for CSS. Developers often add Gulp to handle Sass/PostCSS and simply copy other source files. Over time, Gulp's glob rules become insufficient to identify exactly which files are needed, leading to missing or extra files, so a dependency analysis step is required. Webpack can provide this analysis (among other capabilities).
3. What resources a mini‑program depends on
Using WeChat mini‑programs as an example, a program consists of an
appdescription and multiple
pagedescriptions. The root must contain
app.js,
app.json, and
app.wxss. Each page consists of four files:
.js,
.json,
.wxss, and
.wxml. Additional assets include images, fonts, and
.wxsscripts. All pages are registered in
app.json, which can be used to discover page and component dependencies.
4. How to implement dependency analysis
Webpack starts from an entry point and builds a dependency graph. Mini‑programs lack a single JavaScript entry, so we generate a dynamic entry based on
app.jsonand then let Webpack recursively collect all dependent resources.
Note: reading this series assumes basic knowledge of Webpack.
Generating the entry
Assume the mini‑program directory structure is:
<code>|-- pages
|-- index
|-- index.js
|-- index.wxss
|-- index.wxml
|-- index.json
|-- components
|-- nav
|-- nav.js
|-- nav.wxss
|-- nav.wxml
|-- nav.json
|-- common
|-- color.wxss
|-- app.js
|-- app.json
|-- app.wxss</code>The
app.jsonfile looks like:
<code>{
"pages": [
"pages/index/index"
]
}</code>From this we can generate an entry file
entry.js:
<code>require('./app.js');
require('./app.wxss');
require('./pages/index/index.js');
require('./pages/index/index.json');
require('./pages/index/index.wxss');
require('./pages/index/index.wxml');</code>Webpack natively parses only JavaScript modules, so we need custom loaders for
.wxss,
.wxml,
.wxs, and
.jsonfiles.
Writing wxss-loader to get wxss dependencies
The loader extracts
@importstatements using a regular expression and returns a JavaScript module that requires the imported files. For example,
app.wxsscontains:
<code>@import './common/color.wxss';
.fixed{
position: fixed;
}</code>After processing, the loader returns:
<code>require('./common/color.wxss');
module.exports = '';</code>All source code is available in the wecteam/dm repository (see references).
Writing wxml-loader to get wxml and wxs dependencies
The loader parses
import,
include, and
wxstags using a regular expression to collect dependent files, then emits
requirestatements for each.
Writing wxs-loader to get wxs dependencies
This loader simply returns the content of a
.wxsfile as a JavaScript module, allowing Webpack to recurse through its dependencies.
Writing wxjson-loader to get component dependencies
Although Webpack can parse JSON, we need the
usingComponentsfield to discover component files. For example,
index.jsoncontains:
<code>{
"navigationBarTitleText": "首页",
"usingComponents" : {
"nav" : "../../nav/nav"
}
}</code>From this we can require the four files of the
navcomponent (
nav.wxml,
nav.js,
nav.json,
nav.wxss) in a generated JavaScript module.
Note: set the loader type to javascript/auto so Webpack treats the transformed JSON as a JS module.
Component dependencies may also be expressed as plugin:// URLs, which can be ignored during analysis.
Handling image and font resources
Image paths in
app.jsoncan be resolved directly, but those in
wxmlare often set dynamically via
setDataand can only be determined at runtime. It is recommended to host most images on a CDN and copy the remaining assets as‑is.
Other dependencies in app.json
Global
Componentconfiguration.
sitemap.jsonfor search.
The
./functional-pagesdirectory for plugin pages (must not be referenced elsewhere).
Cross‑OS path issues
When converting Windows paths (e.g.,
d:\path\to\file) to POSIX style, backslashes are replaced with forward slashes, and escaped characters like
\tbecome tabs, so we normalize paths with
replace(/\\/g, '/').
Incompatible path syntax compatibility
Mini‑programs treat
require('util')as a relative file, while standard Node treats it as a package. Variants such as
require('./util'),
require('/util'), and
require('/')need to be normalized. Similarly,
@import /app.wxssand
@import ./app.wxssboth refer to the root‑level file.
When to resolve path problems
Each custom loader should normalize paths for its file type.
JavaScript path issues can be handled in Webpack's
normalModuleFactory beforeResolvehook (see reference).
5. Conclusion
This article described how to perform file dependency analysis for mini‑programs using Webpack, including dynamic entry generation and custom loaders for wxss, wxml, wxs, and json. The same approach works for other mini‑program platforms (e.g., Alipay) by writing appropriate loaders. The next article will show how to collect the analysis results and package them into the required directory structure.
References
[1] wecteam/dm: https://github.com/wecteam/dm/blob/master/packages/dm-cli/src/plugins/plugin-build/webpack-loaders/wxss-loader.ts
[2] wecteam/dm: https://github.com/wecteam/dm/blob/master/packages/dm-cli/src/plugins/plugin-build/webpack-plugins/deps-plugin.ts
WecTeam
WecTeam (维C团) is the front‑end technology team of JD.com’s Jingxi business unit, focusing on front‑end engineering, web performance optimization, mini‑program and app development, serverless, multi‑platform reuse, and visual building.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.