- 首先, 下载相关依赖插件
yarn add compressing
- 修改package.json
package.json
将下面的内容放到scripts里面;
"rn_modules": "node webpackHooks/deleteNodeModules.js",
"bundle-ios": "node node_modules/react-native/local-cli/cli.js bundle --entry-file index.js --platform ios --dev false --bundle-output ./dist/ios/index.ios.bundle --assets-dest ./dist/ios",
"bundle-android": "node node_modules/react-native/local-cli/cli.js bundle --entry-file index.js --platform android --dev false --bundle-output ./dist/android/index.android.bundle --assets-dest ./dist/android",
"zip": "node webpackHooks/commder.js",
"bundle-all": "npm run update-version && npm run bundle-ios && npm run bundle-android && npm run updateMd5 && npm run zip",
"update-version": "node webpackHooks/index.js",
"bundle-tow": "npm run bundle-ios && npm run bundle-android",
"InspectZip": "node webpackHooks/InspectZip.js",
"inspectFileSize": "node webpackHooks/inspectFileSize.js",
"inspect-all": "npm run inspectFileSize && npm run InspectZip",
"rn-dist": "node webpackHooks/rnDist.js",
"createDirIfNotExists": "node webpackHooks/createDirIfNotExists.js",
"updateMd5": "node webpackHooks/updateMd5.js",
"init-bundle": "npm run createDirIfNotExists && npm run rn-dist && npm run bundle",
"bundle": "npm run bundle-all && npm run inspect-all",
"bundle-ios-zip": "react-native bundle --entry-file index.js --bundle-output ./dist/ios/ios/index.ios.bundle --platform ios --assets-dest ./dist/ios/ios --dev false&&node commder ios",
"bundle-android-zip": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output ./dist/android/android/index.android.bundle --assets-dest ./dist/android/android --verbose&&node commder android",
解释说明:
bundle-ios
: 打包ios的bundle包
bundle-android
: 打包安卓的bundle包
zip
: 将dist/ios 或dist/android 打包成zip , zip目录结构如下
ios: 版本号/ios/相关bundle和资源文件 0.1.1/ios//index.ios.bundle(和assets等文件)
安卓: android_版本号/andorid/相关bundle和资源文件 android_0.1.1/android//index.android.bundle(和assets等文件)
update-version
: 更新package.json文件内的version的值,从dist/iso/version.json获取,并自动向上升级一个小版本, 必须要存在才能更新,如不存在,请不要执行该命令
bundle-tow
: 同时执行 bundle-ios 和Budnle-android 命令
bundle-all
: 先执行更新版本号,然后打包,然后生成md5,最后生成zip
InspectZip
: 判断压缩包大小,是否超过最大限值;
inspectFileSize
: 检测每个文件的大小,并再控制台打印;
"inspect-all": InspectZip 和 inspectFileSize 的集合;
"rn-dist": 删除dist目录
“createDirIfNotExists”: 创建dist目录和dist/ios dist/android目录
“updateMd5”: 更新version.json里面的md5
“init-bundle”: 第一次拉代码后执行的打包命令,这时候你可能没有dist文件,这会帮你自动创建。注意: 第一次创建打包可能会卡死在打包ios时, 这时候如果卡死了,请停止重新执行npm run bundle即可
bundle
: 打包并且检测包大小, ** 平时打包就是使用这个命令即可 **
- 新建下面的目录webpackHooks和目录下面的文件, 代码都在下面; 将webpackHooks放到项目根目录;
webpackHooks/commder.js
压缩程zip包
const PackageJSON = require('../package.json');
const compressing = require('compressing');
compressing.zip.compressDir('./dist/ios', './dist/'+PackageJSON.version+'.zip').then(res => {
console.log("asdadres",res);
}).catch(err => {
console.log("asdaderr",err);
})
compressing.zip.compressDir('./dist/android', './dist/android_'+PackageJSON.version+'.zip').then(res => {
console.log("asdadres",res);
}).catch(err => {
console.log("asdaderr",err);
})
webpackHooks/createDirIfNotExists.js
检查文件dist目录是否存在,不存在就创建
const fs = require('fs');
const path = require('path');
const sep = '/'
function createDirIfNotExists(dirPath) {
console.log('检查文件是否存在,开始检查:', dirPath)
dirPath.split(sep).reduce((prevPath, folder) => {
const currentPath = path.join(prevPath, folder, sep);
if (!fs.existsSync(currentPath)){
fs.mkdirSync(currentPath);
}
return currentPath;
}, '');
console.log('检查文件是否存在,结束检查:', dirPath)
}
const iosVersionPath = './dist/ios';
const androidVersionPath = './dist/android';
// 使用方法
createDirIfNotExists(iosVersionPath);
createDirIfNotExists(androidVersionPath);
webpackHooks/deleteNodeModules.js
递归删除node_modules目录和包
const fs = require('fs');
const path = require('path');
// 递归删除目录
function deleteDirectoryRecursive(directoryPath) {
console.log(`fs.existsSync(directoryPath)`, fs.existsSync(directoryPath))
if (fs.existsSync(directoryPath)) {
fs.readdirSync(directoryPath).forEach(function(file, index) {
var curPath = path.join(directoryPath, file);
if (fs.lstatSync(curPath).isDirectory()) {
// 递归删除子目录
deleteDirectoryRecursive(curPath);
} else {
// 删除文件
fs.unlinkSync(curPath);
}
});
// 删除目录
fs.rmdirSync(directoryPath);
}
}
// 调用函数删除指定的文件夹
const folderPath = './node_modules'; // 替换为您要删除的文件夹路径
deleteDirectoryRecursive(folderPath);
webpackHooks/deleteRmFile.js
删除指定路径内的文件
const fs = require('fs');
const path = require('path');
function deleteFilesInDirectory(dirPath) {
console.log('开始删除文件路径内文件:', dirPath)
if (fs.existsSync(dirPath)) {
fs.readdirSync(dirPath).forEach((file) => {
const filePath = path.join(dirPath, file);
if (fs.lstatSync(filePath).isDirectory()) {
// 递归删除子文件夹
deleteFilesInDirectory(filePath);
fs.rmdirSync(filePath); // 删除空文件夹
} else {
// 删除文件
fs.unlinkSync(filePath);
}
});
} else {
console.log(`Directory ${dirPath} does not exist.`);
}
console.log('结束删除文件路径内文件:', dirPath)
}
module.exports = deleteFilesInDirectory;
webpackHooks/index.js
打包入口
var updateVersionFn = require('./updateVersionFn.js')
// var updateAllMd5 = require('./updateMd5.js')
console.log('------------执行更新version.json更新版本号程序------------')
updateVersionFn()
// updateAllMd5()
webpackHooks/inspectFileSize.js
读取文件并打印文件大小
//引入内置模块
const path = require('path')
const fs = require('fs')
const iosOriginPath = 'dist/ios'
const andoridOriginPath = 'dist/android'
const fileList = []
var inspectFileSize = function(srcPath, cb) {
const iosFile = fs.statSync(srcPath);
// console.log(`iosFile`, iosFile)
// console.log(`文件名称:`, srcPath, `大小: `, Math.ceil(iosFile.size/1024), 'kb')
fileList.push({
filePath: srcPath,
fullSize:iosFile.size,
fileSize: Math.ceil(iosFile.size/1024),
fileSizeStr: Math.ceil(iosFile.size/1024) + 'kb'
})
cb()
}
var copyFolder = function(srcDir, cb) {
fs.readdir(srcDir, function(err, files) {
// console.log(`err`, err)
// console.log(`files`, files)
var count = 0
var checkEnd = function() {
++count == files.length && cb && cb()
}
if (err) {
checkEnd()
return
}
files.forEach(function(file) {
var srcPath = path.join(srcDir, file)
fs.stat(srcPath, function(err, stats) {
if (stats.isDirectory()) {
copyFolder(srcPath, checkEnd)
} else {
inspectFileSize(srcPath, checkEnd)
}
})
})
//为空时直接回调
files.length === 0 && cb && cb()
})
}
function inspectFileSizeInit() {
copyFolder(iosOriginPath, function(err) {
if (err) {
return
}
// fileList.sort((a, b) => b.fullSize - a.fullSize).forEach(v => {
// console.log(`文件名称:`, v.filePath, `大小: `, v.fileSize, 'kb')
// })
copyFolder(andoridOriginPath, function(err) {
if (err) {
return
}
fileList.sort((a, b) => a.fullSize - b.fullSize).forEach(v => {
console.log(`文件名称:`, v.filePath, `大小: `, v.fileSize, 'kb')
})
})
})
}
inspectFileSizeInit()
webpackHooks/InspectZip.js
检查dist内每个文件的大小,和总的压缩大小
const packageJsonVersionPath = './package.json'
const fs = require('fs');
const maxSize = 3*1024*1024 // 最大限制 3m
function getPackageVersionFn() {
const isExit = fs.existsSync(packageJsonVersionPath);
console.log('是否存在package.json', isExit ? '存在' : '不存在');
// 当存在文件时;
if (isExit) {
const dataJsonStringify = fs.readFileSync(packageJsonVersionPath, 'utf8');
const dataJsonParse = JSON.parse(dataJsonStringify);
return dataJsonParse.version
}
}
function InspectSizeLog(iosPath){
const iosFile = fs.statSync(iosPath);
// console.log(`dataJsonStringify`, iosFile)
// console.log('%c在这个符号后的信息是绿色','color: #529b2e')
console.log(`检查到${iosPath}文件,大小为:`, iosFile.size/1024 > maxSize ? iosFile.size/1024 : `${iosFile.size/1024}` , `KB`)
if (maxSize < iosFile.size) {
console.log(`-----------------------------------start 重要的事情说四次-------------------------------------------------------------`)
console.info(`警告: ${iosPath}文件最大为`, maxSize/1024, 'kb', `当前大小为`, iosFile.size/1024, `kb,请优化代码到合理大小;`)
console.info(`警告: ${iosPath}文件最大为`, maxSize/1024, 'kb', `当前大小为`, iosFile.size/1024, `kb,请优化代码到合理大小;`)
console.info(`警告: ${iosPath}文件最大为`, maxSize/1024, 'kb', `当前大小为`, iosFile.size/1024, `kb,请优化代码到合理大小;`)
console.info(`警告: ${iosPath}文件最大为`, maxSize/1024, 'kb', `当前大小为`, iosFile.size/1024, `kb,请优化代码到合理大小;`)
console.log(`-----------------------------------end-------------------------------------------------------------`)
}
}
function InspectSizeFn() {
const pageVersion = getPackageVersionFn()
const iosPath = `dist/${pageVersion}.zip`
const androidPath = `dist/android_${pageVersion}.zip`
const isIosExit = fs.existsSync(iosPath);
const isAndoridExit = fs.existsSync(androidPath);
console.log(`是否存在ios的zip文件: ${iosPath}是否存在:`, isIosExit ? '存在' : '不存在');
console.log(`是否存在andorid的zip文件: ${androidPath}是否存在:`, isAndoridExit ? '存在' : '不存在');
// 默认升级小版本
// 当存在文件时;
if (isIosExit) {
console.log(`正在读取${iosPath}文件,请稍后...`);
InspectSizeLog(iosPath)
}
if (isAndoridExit) {
console.log(`正在读取${iosPath}文件,请稍后...`);
InspectSizeLog(androidPath)
}
}
InspectSizeFn()
webpackHooks/rnDist.js
删除dist目录文件
var deleteFilesInDirectory = require('./deleteRmFile.js')
const iosVersionPath = './dist/ios';
const androidVersionPath = './dist/android';
deleteFilesInDirectory(iosVersionPath)
deleteFilesInDirectory(androidVersionPath)
webpackHooks/updateMd5.js
更新md5
const fs = require('fs');
const crypto = require('crypto');
const iosBundlePath = './dist/ios/index.ios.bundle';
const androidBundlePath = './dist/android/index.android.bundle';
const iosVersionPath = './dist/ios/version.json';
const androidVersionPath = './dist/android/version.json';
function updateMd5(path){
const isExit = fs.existsSync(path);
if (isExit) {
const bundleStr = fs.readFileSync(path, 'utf8');
// 创建hash对象并指定算法为md5
const hash = crypto.createHash('md5');
// 更新hash对象的内容
hash.update(bundleStr);
const md5Value = hash.digest('hex');
console.log(`MD5 value of xxx is ${md5Value}`);
return md5Value
}
return ''
}
function updateVersionFn(verPath, bundlePath, keyName) {
const isExit = fs.existsSync(verPath);
console.log('是否存在version.json', isExit ? '存在' : '不存在');
// 默认升级小版本
// 当存在文件时;
if (isExit) {
console.log(keyName+'正在更新version.json文件md5,请稍后...');
const dataJsonStringify = fs.readFileSync(verPath, 'utf8');
const dataJsonParse = JSON.parse(dataJsonStringify);
const Md5 = updateMd5(bundlePath)
dataJsonParse[keyName] = Md5
fs.writeFileSync(verPath, JSON.stringify(dataJsonParse));
}
}
function updateAllMd5(){
console.log(`开始更新md5`)
const verPathList = [iosVersionPath, androidVersionPath]
const bundlePathList = [iosBundlePath, androidBundlePath]
const keyNameList = ['iosMd5', 'androidMd5']
keyNameList.forEach((v, i) => {
updateVersionFn(verPathList[i], bundlePathList[i], keyNameList[i])
})
console.log(`结束更新md5`)
}
updateAllMd5();
module.exports = updateAllMd5;
webpackHooks/updateVersionFn.js
更新版本号
const AppJSON = require('../app.json');
const {name} = AppJSON;
const AppName = name;
const fs = require('fs');
const versionPath = './dist/ios/version.json';
const androidVersionPath = './dist/android/version.json';
const packageJsonVersionPath = './package.json';
const upgradeBigVersion = false; // 是否升级大版本
const upgradeMiddleVersion = false; // 是否升级中版本, 大版本更新优先, 当大版本更新时,重置中/小版本=0, 当中版本更新时,重置小版本=0
function getUpdateVersion(version){
let bigVersion = parseInt(version.split('.')[0]);
let middleVersion = parseInt(version.split('.')[1]);
let smallVersion = parseInt(version.split('.')[2]);
if (upgradeBigVersion) {
bigVersion += 1;
middleVersion = 0;
smallVersion = 0;
} else if (upgradeMiddleVersion) {
middleVersion += 1;
smallVersion = 0;
} else {
smallVersion += 1;
}
return `${bigVersion}.${middleVersion}.${smallVersion}`;
}
function updateVersionFn() {
const isExit = fs.existsSync(versionPath);
const pageVersion = getPackageVersionFn()
console.log('是否存在version.json', isExit ? '存在' : '不存在');
// 默认升级小版本
// 当存在文件时;
if (isExit) {
console.log('正在更新version.json文件版本号,请稍后...');
const dataJsonStringify = fs.readFileSync(versionPath, 'utf8');
const dataJsonParse = JSON.parse(dataJsonStringify);
let endVersion = pageVersion || dataJsonParse.version
if (endVersion) {
dataJsonParse.version = getUpdateVersion(endVersion)
dataJsonParse.name = AppName
console.log('当前版本号:', dataJsonParse.version);
} else {
dataJsonParse.version = `0.0.1`;
dataJsonParse.name = AppName
console.log('当前版本号:', dataJsonParse.version);
}
updatePackageVersionFn(dataJsonParse.version)
fs.writeFileSync(versionPath, JSON.stringify(dataJsonParse));
fs.writeFileSync(androidVersionPath, JSON.stringify(dataJsonParse));
} else {
console.log('新建version.json文件中,请稍后...');
const obj = {
name: AppName,
version: pageVersion ? getUpdateVersion(pageVersion) : '0.0.1',
};
fs.writeFileSync(versionPath, JSON.stringify(obj));
fs.writeFileSync(androidVersionPath, JSON.stringify(obj));
console.log('当前版本号:', obj.version);
updatePackageVersionFn(obj.version)
}
}
function getPackageVersionFn() {
const isExit = fs.existsSync(packageJsonVersionPath);
console.log('是否存在package.json', isExit ? '存在' : '不存在');
// 当存在文件时;
if (isExit) {
const dataJsonStringify = fs.readFileSync(packageJsonVersionPath, 'utf8');
const dataJsonParse = JSON.parse(dataJsonStringify);
return dataJsonParse.version
}
}
function updatePackageVersionFn(version) {
const isExit = fs.existsSync(packageJsonVersionPath);
console.log('是否存在package.json', isExit ? '存在' : '不存在');
// 当存在文件时;
if (isExit) {
console.log('正在更新package.json文件版本号,请稍后...');
const dataJsonStringify = fs.readFileSync(packageJsonVersionPath, 'utf8');
const dataJsonParse = JSON.parse(dataJsonStringify);
dataJsonParse.version = version
fs.writeFileSync(packageJsonVersionPath, JSON.stringify(dataJsonParse, null, 2));
}
}
module.exports = updateVersionFn;