/* * @Author: Rindy * @Date: 2021-04-29 14:23:36 * @LastEditors: Rindy * @LastEditTime: 2021-05-24 17:28:29 * @Description: 注释 */ import deps from '@kankan/sdk-deps' import { minify } from 'terser' import path from 'path' import util from 'util' import fs from 'fs-extra' import isObject from 'is-plain-object' import globby from 'globby' import { bold, green, yellow } from 'colorette' function stringify(value) { return util.inspect(value, { breakLength: Infinity }) } async function isFile(filePath) { const fileStats = await fs.stat(filePath) return fileStats.isFile() } function renameTarget(target, rename, src) { const parsedPath = path.parse(target) return typeof rename === 'string' ? rename : rename(parsedPath.name, parsedPath.ext.replace('.', ''), src) } async function generateCopyTarget(src, dest, { flatten, rename, transform }) { if (transform && !(await isFile(src))) { throw new Error(`"transform" option works only on files: '${src}' must be a file`) } const { base, dir } = path.parse(src) const destinationFolder = flatten || (!flatten && !dir) ? dest : dir.replace(dir.split('/')[0], dest) return { src, dest: path.join(destinationFolder, rename ? renameTarget(base, rename, src) : base), ...(transform && { contents: await transform(await fs.readFile(src), base) }), renamed: rename, transformed: transform, } } export default function (options = {}) { const { mangle, copyOnce = false, flatten = true, hook = 'buildEnd', copy = {}, verbose = false, ...restPluginOptions } = options let copied = false return { name: 'rollup-plugin-deps', // 这个名字将会出现在在警告和报错中 resolveId(importee) { if (importee.indexOf('sdk-deps.js') != -1) { return importee } return null // 其他的id不受影响 }, load(id) { if (id.indexOf('sdk-deps.js') != -1) { return '' } return null // 其他的id还是通过正常的方式解析 }, async buildEnd() { if (copyOnce && copied) { return } const targets = copy.targets || [] const copyTargets = [] if (Array.isArray(targets) && targets.length) { for (const target of targets) { if (!isObject(target)) { throw new Error(`${stringify(target)} target must be an object`) } const { dest, rename, name, transform, ...restTargetOptions } = target const src = deps[name] if (!src || !dest) { throw new Error(`${stringify(target)} target must have "src" and "dest" properties`) } if (rename && typeof rename !== 'string' && typeof rename !== 'function') { throw new Error(`${stringify(target)} target's "rename" property must be a string or a function`) } const matchedPaths = await globby(src, { expandDirectories: false, onlyFiles: false, ...restPluginOptions, ...restTargetOptions, }) if (matchedPaths.length) { for (const matchedPath of matchedPaths) { const generatedCopyTargets = Array.isArray(dest) ? await Promise.all(dest.map(destination => generateCopyTarget(matchedPath, destination, { flatten, rename, transform }))) : [await generateCopyTarget(matchedPath, dest, { flatten, rename, transform })] copyTargets.push(...generatedCopyTargets) } } } } if (copyTargets.length) { console.log(green('正在复制')) if (verbose) { console.log(green('copied:')) } for (const copyTarget of copyTargets) { const { contents, dest, src, transformed } = copyTarget if (transformed) { await fs.outputFile(dest, contents, restPluginOptions) } else { await fs.copy(src, dest, restPluginOptions) } if (verbose) { let message = green(` ${bold(src)} → ${bold(dest)}`) const flags = Object.entries(copyTarget) .filter(([key, value]) => ['renamed', 'transformed'].includes(key) && value) .map(([key]) => key.charAt(0).toUpperCase()) if (flags.length) { message = `${message} ${yellow(`[${flags.join(', ')}]`)}` } console.log(message) } } console.log(green('完成复制')) } else if (verbose) { console.log(yellow('no items to copy')) } copied = true }, transform(source, id) {}, buildStart() {}, async generateBundle(options, bundle, isWrite) { console.log(green('正在压缩依赖')) const source = [] for (let i = 0; i < deps.js.length; i++) { let file = deps.js[i] if (fs.existsSync(file)) { let code = fs.readFileSync(file).toString() if (!/\.(min|prod)\.js$/.test(file)) { if (mangle) { code = (await minify(code, { mangle: true })).code } } source.push(code) } } this.emitFile({ type: 'asset', fileName: options.file.replace(/\\/g, '/').split('/').pop(), source: source.join(';\r\n') }) console.log(green('完成压缩依赖')) }, } }