wechat-page-generator
Version:
🚀 Automatic page generator for WeChat Mini Program with ready-made templates
259 lines (219 loc) • 6.03 kB
JavaScript
const fs = require('fs');
const path = require('path');
/**
* Creates a new WeChat Mini Program page
* @param {string} pageName - Name of the page to create
* @param {object} options - Configuration options
*/
function createPage(pageName, options = {}) {
// Validate the page name
if (!pageName || typeof pageName !== 'string') {
throw new Error('Page name is required and must be a string');
}
// Clean the page name (remove special characters)
const cleanPageName = pageName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
if (!cleanPageName) {
throw new Error('Page name must contain at least one alphanumeric character');
}
const basePath = path.join(process.cwd(), 'pages', cleanPageName);
// Check if the page already exists
if (fs.existsSync(basePath)) {
throw new Error(`Page "${cleanPageName}" already exists`);
}
// Create the folder
fs.mkdirSync(basePath, { recursive: true });
// File templates
const files = {
[`${cleanPageName}.wxml`]: generateWxmlTemplate(cleanPageName, options),
[`${cleanPageName}.js`]: generateJsTemplate(cleanPageName, options),
[`${cleanPageName}.wxss`]: generateWxssTemplate(cleanPageName, options),
[`${cleanPageName}.json`]: generateJsonTemplate(cleanPageName, options)
};
// Create the files
for (const [fileName, content] of Object.entries(files)) {
const filePath = path.join(basePath, fileName);
fs.writeFileSync(filePath, content, 'utf8');
}
// Automatically add the page to app.json
const appJsonUpdated = updateAppJson(cleanPageName);
return {
success: true,
pageName: cleanPageName,
path: basePath,
files: Object.keys(files),
appJsonUpdated
};
}
/**
* Generates the WXML template
*/
function generateWxmlTemplate(pageName, options) {
const title = options.title || pageName.charAt(0).toUpperCase() + pageName.slice(1);
return `<view class="${pageName}-container">
<view class="${pageName}-header">
<text class="${pageName}-title">${title}</text>
</view>
<view class="${pageName}-content">
<!-- Content of the ${pageName} page -->
<text>Welcome to the ${title} page</text>
</view>
</view>`;
}
/**
* Generates the JavaScript template
*/
function generateJsTemplate(pageName, options) {
return `// pages/${pageName}/${pageName}.js
Page({
/**
* Initial data for the page
*/
data: {
title: '${pageName.charAt(0).toUpperCase() + pageName.slice(1)}'
},
/**
* Lifecycle - On page load
*/
onLoad(options) {
console.log('Page ${pageName} loaded with options:', options);
},
/**
* Lifecycle - When page is shown
*/
onShow() {
console.log('Page ${pageName} displayed');
},
/**
* Lifecycle - When page is hidden
*/
onHide() {
console.log('Page ${pageName} hidden');
},
/**
* Lifecycle - When page is unloaded
*/
onUnload() {
console.log('Page ${pageName} unloaded');
},
/**
* Event handler - On pull down refresh
*/
onPullDownRefresh() {
console.log('Pull down refresh on ${pageName}');
// wx.stopPullDownRefresh();
},
/**
* Event handler - On reach bottom
*/
onReachBottom() {
console.log('Reached bottom of ${pageName}');
}
});`;
}
/**
* Generates the WXSS template
*/
function generateWxssTemplate(pageName, options) {
return `/* pages/${pageName}/${pageName}.wxss */
.${pageName}-container {
min-height: 100vh;
background-color: #f5f5f5;
padding: 20rpx;
}
.${pageName}-header {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.${pageName}-title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
text-align: center;
display: block;
}
.${pageName}-content {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.${pageName}-content text {
font-size: 28rpx;
color: #666666;
line-height: 1.6;
}`;
}
/**
* Generates the JSON configuration
*/
function generateJsonTemplate(pageName, options) {
const config = {
navigationBarTitleText: options.title || pageName.charAt(0).toUpperCase() + pageName.slice(1),
navigationBarBackgroundColor: "#ffffff",
navigationBarTextStyle: "black",
backgroundColor: "#f5f5f5"
};
return JSON.stringify(config, null, 2);
}
/**
* Automatically updates app.json to include the new page
* @param {string} pageName - Name of the page to add
* @returns {object} Update result
*/
function updateAppJson(pageName) {
const appJsonPath = path.join(process.cwd(), 'app.json');
try {
// Check if app.json exists
if (!fs.existsSync(appJsonPath)) {
return {
updated: false,
reason: 'app.json not found in the root directory'
};
}
// Read app.json
const appJsonContent = fs.readFileSync(appJsonPath, 'utf8');
let appConfig;
try {
appConfig = JSON.parse(appJsonContent);
} catch (parseError) {
return {
updated: false,
reason: 'Invalid JSON in app.json'
};
}
// Ensure "pages" section exists
if (!appConfig.pages || !Array.isArray(appConfig.pages)) {
appConfig.pages = [];
}
// Construct the page path
const pagePath = `pages/${pageName}/${pageName}`;
// Check if the page already exists
if (appConfig.pages.includes(pagePath)) {
return {
updated: false,
reason: 'Page already exists in app.json'
};
}
// Add the new page
appConfig.pages.push(pagePath);
// Save app.json with formatted JSON
const updatedContent = JSON.stringify(appConfig, null, 2);
fs.writeFileSync(appJsonPath, updatedContent, 'utf8');
return {
updated: true,
path: pagePath,
totalPages: appConfig.pages.length
};
} catch (error) {
return {
updated: false,
reason: `Error while updating: ${error.message}`
};
}
}
module.exports = {
createPage
};