var fs = require('fs'); var path = require('path'); var util = require('gulp-util'); var through2 = require('through2'); var dependencies = require('./dependencies.json'); var banner = require('./banner'); var pkg = require('../package.json'); var version = process.env.VERSION || pkg.version; var IMPORT_SNIPPET = `import {{displayName}} from './{{fileName}}/index'`; var VAR_SNIPPET = `const {{displayName}} = (selector = '{{selector}}', ctx) => getCtx(selector, ctx)`; var REFRESHER_VAR_SNIPPET = `const $startWuxRefresher = (selector = '#wux-refresher', ctx) => getCtx(selector, ctx).triggerRefresh() const $stopWuxRefresher = (selector = '#wux-refresher', ctx) => getCtx(selector, ctx).finishPullToRefresh() const $stopWuxLoader = (selector = '#wux-refresher', ctx, isEnd) => getCtx(selector, ctx).finishLoadmore(isEnd)`; var REFRESHER_EXPORT_SNIPPET = ['$startWuxRefresher', '$stopWuxRefresher', '$stopWuxLoader'].join(',\n\t'); function getName(v) { if (v === 'version') return 'version'; var others = { actionsheet: 'action-sheet', keyboard: 'key-board', countdown: 'count-down', countup: 'count-up', }; var toUpper = function (val) { return `${val.charAt(0).toUpperCase()}${val.slice(1)}` }; v = others[v] || v; v = v.split('-').map(function(val) { return toUpper(val) }).join(''); return `$wux${v}`; } function getFiles(files) { return files.map(function(v) { return { displayName: getName(v), fileName: v, selector: `#wux-${v}`, } }); } function esm(snippet, options) { return snippet.replace(/{{banner}}/g, options.banner) .replace(/{{componentImports}}/g, options.componentImports) .replace(/{{componentAliases}}/g, options.componentAliases) .replace(/{{componentExports}}/g, options.componentExports) } function getFileString(snippet, opts) { var importFiles = opts.importFiles || []; var exportFiles = opts.exportFiles || []; var files = importFiles.concat(exportFiles); var extra = getFiles(importFiles); var data = getFiles(exportFiles); var componentImports = extra.map(function(v) { return inspectFile(IMPORT_SNIPPET, v) }).join('\n'); var componentAliases = `const version = '{{version}}'`.replace(/{{version}}/, version) + '\n'; componentAliases = componentAliases + data.map(function(v) { if (v.fileName === 'refresher') { return REFRESHER_VAR_SNIPPET } return inspectFile(VAR_SNIPPET, v) }).join('\n'); var componentExports = ['version'].concat(files).map(function(v) { if (v === 'refresher') { return REFRESHER_EXPORT_SNIPPET } return getName(v) }).join(',\n\t'); var options = { banner: banner.trim(), componentImports: componentImports, componentAliases: componentAliases, componentExports: componentExports, }; var result = esm(snippet, options); return result; } function getOptions(files) { var exclude = ['countdown', 'countup']; var include = ['actionsheet', 'app', 'backdrop', 'toast', 'loading', 'dialog', 'form', 'toptips', 'gallery', 'index', 'notification', 'keyboard', 'select', 'calendar', 'refresher']; var importFiles = exclude.filter(function(v) { return files.includes(v) }); var exportFiles = files.filter(function(v) { return include.includes(v) }); return { importFiles: importFiles, exportFiles: exportFiles, } } function generateScript(files) { return through2.obj(function(file, encoding, cb) { // 如果文件为空,不做任何操作,转入下一个操作,即下一个pipe if (file.isNull()) { this.push(file) return cb() } // 插件不支持对stream直接操作,抛出异常 if (file.isStream()) { this.emit('error', new util.PluginError('generateScript', 'Streaming not supported')) return cb() } // 内容转换,处理好后,再转成 Buffer 形式 var snippet = file.contents.toString() var content = getFileString(snippet, getOptions(files || [])) file.contents = typeof Buffer.from === 'function' ? Buffer.from(content) : new Buffer(content) // 下面这两句基本是标配,可参考 through2 的 API this.push(file) cb() }) } function generateStyle(themes, options) { return through2.obj(function(file, encoding, cb) { // 如果文件为空,不做任何操作,转入下一个操作,即下一个pipe if (file.isNull()) { this.push(file) return cb() } // 插件不支持对stream直接操作,抛出异常 if (file.isStream()) { this.emit('error', new util.PluginError('generateStyle', 'Streaming not supported')) return cb() } // Include folder if (options && options.include && !file.relative.match(options.include)) { return cb() } // 内容转换,处理好后,再转成 Buffer 形式 var snippet = file.contents.toString() var content = inspectLess(snippet, themes || []) file.contents = typeof Buffer.from === 'function' ? Buffer.from(content) : new Buffer(content) // 下面这两句基本是标配,可参考 through2 的 API this.push(file) cb() }) } function generateColor(themes, options) { return through2.obj(function(file, encoding, cb) { // 如果文件为空,不做任何操作,转入下一个操作,即下一个pipe if (file.isNull()) { this.push(file) return cb() } // 插件不支持对stream直接操作,抛出异常 if (file.isStream()) { this.emit('error', new util.PluginError('generateStyle', 'Streaming not supported')) return cb() } // 内容转换,处理好后,再转成 Buffer 形式 var snippet = file.contents.toString() var content = inspectColor(snippet, themes || []) file.contents = typeof Buffer.from === 'function' ? Buffer.from(content) : new Buffer(content) // 下面这两句基本是标配,可参考 through2 的 API this.push(file) cb() }) } function getModifyVars(themes) { return Object.keys(themes).reduce(function(acc, name) { acc[name.indexOf('@') === 0 ? name.slice(1) : name] = themes[name] return acc }, {}) } function inspectColor(snippet, themes) { return Object.keys(themes).reduce(function(acc, name) { return acc.replace(new RegExp(`('${name}':).+(,)`), `$1 '${themes[name]}'$2`) }, snippet) } function inspectLess(snippet, themes) { return Object.keys(themes).reduce(function(acc, name) { return acc.replace(new RegExp(`(\@${name}:).+(;)`), `$1 ${themes[name]}$2`) }, snippet) } function unique(arr) { return arr.filter(function(v, i) { return arr.indexOf(v) === i }) } function getFilesByName(name) { if (dependencies[name] === undefined) return []; return dependencies[name].dependencies.reduce(function(acc, depName) { return acc.concat(getFilesByName(depName)) }, dependencies[name].files) } function getFilesByNames(names) { return unique(names.reduce(function(acc, name) { return acc.concat(getFilesByName(name)) }, [])) } /** * Create Folder */ function mkdirs(dirname, callback) { fs.exists(dirname, function (exists) { if (exists) { callback(); } else { mkdirs(path.dirname(dirname), function () { fs.mkdir(dirname, callback); }); } }); } /** * Write File */ function writeFile(fileName, fileString) { fs.writeFile(fileName, fileString, function(err) { if (err) { console.error('error writeFile:', err); return; } console.log('success writeFile: generate index.js'); }); } /** * Inspect File */ function inspectFile(snippet, options) { return snippet.replace(/{{displayName}}/g, options.displayName) .replace(/{{fileName}}/g, options.fileName) .replace(/{{selector}}/g, options.selector) } module.exports.generateScript = generateScript; module.exports.generateStyle = generateStyle; module.exports.generateColor = generateColor; module.exports.getModifyVars = getModifyVars; module.exports.getFilesByNames = getFilesByNames; module.exports.mkdirs = mkdirs;