最后就是准备采用的方案了,这个方案就是纯粹和@dcloudio/uni-ui的使用方案是相同的了,因为既然uniapp是写死的,那么我们就适应一下这个方式吧,就不再去做loader或者plugin去特殊处理插件了,将其作为一个规范就好,踩坑踩太多了,顶不住了,实际上我觉得使用loader去解决这个问题也还可以,但是毕竟实际上改动太大并且需要通用地适配,还是采用一个相对通用的方式吧,直接看他的npm包可以看到其组件的结构为/lib/component/component,那我们就可以写个脚本去处理并且可以构建完成后自动发布。现在就是在dist/package下生成了index.js作为引入的main,还有index.d.ts作为声明文件,还有README.md、package.json、.npmrc文件,以及符合上述目录结构的组件,主要都是一些文件操作,以及在package.json写好构建和发布的命令。可以对比https://npm.runkit.com/shst-campus和https://github.com/WindrunnerMax/Campus的文件差异,或者直接在https://github.com/WindrunnerMax/Campus运行一下npm run build:package即可在dist/package看到要发布的npm包。
// utils.js const { promisify } = require("util"); const fs = require("fs"); const path = require("path"); const exec = require("child_process").exec; module.exports.copyFolder = async (from, to) => { if (fs.existsSync(from)) { if (!fs.existsSync(to)) fs.mkdirSync(to, { recursive: true }); const files = fs.readdirSync(from, { withFileTypes: true }); for (let i = 0; i < files.length; i++) { const item = files[i]; const fromItem = path.join(from, item.name); const toItem = path.join(to, item.name); if (item.isFile()) { const readStream = fs.createReadStream(fromItem); const writeStream = fs.createWriteStream(toItem); readStream.pipe(writeStream); } else { fs.accessSync(path.join(toItem, ".."), fs.constants.W_OK); module.exports.copyFolder(fromItem, toItem); } } } }; module.exports.execCMD = (cmdStr, cmdPath) => { const workerProcess = exec(cmdStr, { cwd: cmdPath }); // 打印正常的后台可执行程序输出 workerProcess.stdout.on("data", data => { process.stdout.write(data); }); // 打印错误的后台可执行程序输出 workerProcess.stderr.on("data", data => { process.stdout.write(data); }); // 退出之后的输出 // workerProcess.on("close", code => {}); }; module.exports.fileExist = async location => { try { await promisify(fs.access)(location, fs.constants.F_OK); return true; } catch { return false; } }; module.exports.writeFile = (location, content, flag = "w+") => { return promisify(fs.writeFile)(location, content, { flag }); }; module.exports.readDir = dir => { return promisify(fs.readdir)(dir); }; module.exports.fsStat = fullPath => { return promisify(fs.stat)(fullPath); }; module.exports.copyFile = (from, to) => { // const readStream = fs.createReadStream(from); // const writeStream = fs.createWriteStream(to); // readStream.pipe(writeStream); return promisify(fs.copyFile)(from, to); }; // index.js const path = require("path"); const { copyFolder, readDir, fsStat, writeFile, copyFile, fileExist } = require("./utils"); const root = process.cwd(); const source = root + "/src/components"; const target = root + "/dist/package"; const toClassName = str => { const tmpStr = str.replace(/-(\w)/g, (_, $1) => $1.toUpperCase()).slice(1); return str[0].toUpperCase() + tmpStr; }; const start = async dir => { const components = []; console.log("building"); console.log("copy components"); const items = await readDir(dir); for (const item of items) { const fullPath = path.join(dir, item); const stats = await fsStat(fullPath); if (stats.isDirectory()) { if (/^c-/.test(item)) { components.push({ fileName: item, componentName: toClassName(item) }); } copyFolder(fullPath, path.join(target, "/lib/", item)); } } console.log("processing index.js"); let indexContent = ""; components.forEach(item => { indexContent += `import ${item.componentName} from "./lib/${item.fileName}/${item.fileName}.vue";\n`; }); const exportItems = components.map(v => v.componentName).join(", "); indexContent += `export { ${exportItems} };\n`; indexContent += `export default { ${exportItems} };\n`; await writeFile(path.join(target, "/index.js"), indexContent); console.log("processing index.d.ts"); let dtsContent = `import { Component } from "vue";\n\n`; components.forEach(item => { dtsContent += `declare const ${item.componentName}: Component;\n`; }); await writeFile(path.join(target, "/index.d.ts"), dtsContent); console.log("processing .npmrc"); const exist = await fileExist(path.join(target, "/.npmrc")); if (!exist) { const info = "registry=https://registry.npmjs.org/"; await writeFile(path.join(target, "/.npmrc"), info); } console.log("processing README.md"); await copyFile(path.join(root, "/README.md"), target + "/README.md"); console.log("processing package.json"); const originPackageJSON = require(path.join(root, "/package.json")); const targetJson = { ...originPackageJSON, repository: { type: "git", url: "https://github.com/WindrunnerMax/Campus", }, scripts: {}, author: "Czy", license: "MIT", dependencies: { "vue": "^2.6.11", "vue-class-component": "^6.3.2", "vue-property-decorator": "^8.0.0", }, devDependencies: {}, }; await writeFile(path.join(target, "/package.json"), JSON.stringify(targetJson, null, "\t")); }; start(source);uniapp小程序迁移到TS (7)
内容版权声明:除非注明,否则皆为本站原创文章。