UNPKG

wx2swan

Version:

微信小程序 转换 百度小程序

263 lines (244 loc) 6.64 kB
/** * @file wxml convert swan * @author yican */ const fs = require('fs-extra'); const recursiveCopy = require('recursive-copy'); const mkdirp = require('mkdirp'); const path = require('path'); const vfile = require('vfile'); const swanFileSuffix = 'swan'; const cssFileSuffix = 'css'; const jsFileSuffix = 'js'; const configFileSuffix = 'json'; /** * 拷贝项目 * * @param {string} fromPath 目标目录路径 * @param {string} toPath 生成目录路径 * @return {Promise} */ exports.copyProject = function (fromPath, toPath) { // 支持转换入口为单一文件 if (isDirectory(fromPath)) { return copyDirectory(fromPath, toPath); } else { return copyFile(fromPath, toPath); } }; /** * 拷贝目录 * * @param {string} fromPath 目标目录路径 * @param {string} toPath 生成目录路径 * @return {Promise} */ function copyDirectory(fromPath, toPath) { const lists = fs.readdirSync(fromPath).filter(function (item) { return !/(node_modules|DS_store)/i.test(item); }); const options = { overwrite: true, expand: true, dot: true, rename(filePath) { return renameFileExt(filePath); } }; const arr = []; for (let i = 0; i < lists.length; i++) { arr.push( recursiveCopy( path.join(fromPath, lists[i]), path.join(toPath, lists[i].replace(/wxml$/, swanFileSuffix).replace(/wxss$/, cssFileSuffix)), options ) ); } return Promise.all(arr); } /** * 拷贝单文件 * * @param {string} fromPath 目标文件路径 * @param {string} toPath 生成文件路径 * @return {Promise} */ function copyFile(fromPath, toPath) { // 拷贝文件时toPath支持文件与目录两种形式 let fromfileName = path.basename(fromPath); if (isDirectory(toPath)) { // toPath为目录时补上文件名为fromPath中处理扩展名后的文件名 fromfileName = renameFileExt(fromfileName); toPath = path.join(toPath, fromfileName); } return fs.copy(fromPath, toPath); } /** * 重命名文件扩展名 * * @param {string} filePath 文件路径 * @return {string} 处理后路径 */ function renameFileExt(filePath) { if (/wxml/.test(filePath)) { return filePath.replace(/wxml$/, swanFileSuffix); } else if (/wxss/.test(filePath)) { return filePath.replace(/wxss$/, cssFileSuffix); } else { return filePath; } } /** * 判断路径是否为目录 * * @param {string} entryPath 路径 * @return {boolean} */ function isDirectory(entryPath) { return !path.extname(entryPath); } exports.isDirectory = isDirectory; // get content exports.getContent = function (filepath) { return new Promise(function (resolve) { fs.readFile(filepath, function (err, con) { resolve(con.toString()); }); }); }; // get content sync exports.getContentSync = function (filepath) { return fs.readFileSync(filepath).toString(); }; // write content exports.saveFile = function (path, con) { return new Promise((resolve, reject) => { fs.writeFile(path, con, error => { if (error) { reject(error); } else { resolve(true); } }); }); }; // write content exports.saveLog = function (ContentPath, con) { return new Promise((resolve, reject) => { mkdirp(path.dirname(ContentPath), err => { if (err) { reject(err); } else { fs.writeFileSync(ContentPath, con); } }); }); }; // object to json string exports.object2String = function (obj) { const cache = []; return JSON.stringify(obj, function (key, value) { if (typeof value === 'object' && value !== null) { if (cache.indexOf(value) !== -1) { // Circular reference found, discard key return; } // Store value in our collection cache.push(value); } return value; }, 2); }; /** * 创建虚拟文件,并添加关联文件 * * @param {string} filePath 文件路径 * @param {string} contents 文件内容 * @return {VFile} */ exports.toVFile = function (filePath, contents) { const file = vfile({path: filePath, contents: contents}); const related = { style: cssFileSuffix, view: swanFileSuffix, js: jsFileSuffix, config: configFileSuffix }; const {cwd, dirname, stem, extname} = file; file.data.relatedFiles = Object .keys(related) .reduce( (prev, type) => { const ext = `.${related[type]}`; if (ext !== extname) { const filePath = path.resolve(cwd, dirname, stem + ext); fs.existsSync(filePath) && (prev[type] = filePath); } return prev; }, {} ); return file; }; /** * 判断是否对象 * * @param {Object} val 参数 * @return {boolean} 是否对象 */ module.exports.isObject = function isObject(val) { return val != null && typeof val === 'object' && Array.isArray(val) === false; }; /** * 无请求头的css静态资源url添加https请求头 * * @param {string} content 文件内容 * @return {string} 处理后文件内容 */ exports.transformCssStaticUrl = function transformCssStaticUrl(content) { content = content.replace(/url\((.*)\)/g, function ($1, $2) { if (!$2) { return $1; } const res = $2.replace(/^(['"\s^]?)(\/\/.*)/, function ($1, $2, $3) { const resUrl = `${$2}https:${$3}`; return resUrl; }); return `url(${res})`; }); return content; }; /** * 创建.wx2swaninfo文件 * * @param {string} toPath 生成文件路径 * @return {Promise} */ exports.createWx2swaninfo = function (toPath) { let dirPath = toPath; if (!isDirectory(toPath)) { dirPath = path.dirname(toPath); } const pkg = require('../../package.json'); const filePath = dirPath + '/.wx2swaninfo'; const con = `{ "toolName": "wx2swan", "toolCliVersion": "${pkg.version}", "createTime": ${new Date().getTime()} }`; return new Promise((resolve, reject) => { fs.writeFile(filePath, con, error => { if (error) { reject(error); } else { resolve(true); } }); }); };