UNPKG

xyvcard-wechat-build

Version:

基于 Vite 的小程序组件构建工具

146 lines (145 loc) 5.15 kB
import { build as viteBuild } from "vite"; import * as path from "path"; import * as fs from "fs-extra"; import glob from "fast-glob"; import * as sass from "sass"; import esbuild from "rollup-plugin-esbuild"; import { getMiniprogramNpmPackages } from "./utils.js"; const IGNORE_PATTERNS = [ "node_modules", "miniprogram_npm/**", "pages/**", "app.ts", "app.scss", "app.json", "sitemap.json", ]; const IGNORE_SCSS = ["styles/**/*.scss"]; export async function build(options = {}) { const ROOT_DIR = options.root || process.cwd(); const SRC_DIR = path.resolve(ROOT_DIR, "miniprogram"); const DIST_DIR = path.resolve(ROOT_DIR, options.outDir || "dist"); const EXTERNAL = [ /^@types\//, /^miniprogram-/, /^xyvcard-/, /^jmash-/, /^pages/, ]; const EXTERNAL_PACKAGES = await getMiniprogramNpmPackages(SRC_DIR); async function buildTypeScript() { const tsFiles = await glob("**/*.ts", { cwd: SRC_DIR, ignore: IGNORE_PATTERNS, }); const input = Object.fromEntries(tsFiles.map((file) => [ path.join(path.dirname(file), path.basename(file, ".ts")), path.resolve(SRC_DIR, file), ])); await viteBuild({ root: ROOT_DIR, build: { outDir: DIST_DIR, lib: { entry: input, formats: ["es"], fileName: (format, entryName) => `${entryName}.js`, }, rollupOptions: { input, external: EXTERNAL.concat(EXTERNAL_PACKAGES), output: { format: "es", exports: "named", preserveModules: true, preserveModulesRoot: "miniprogram", }, plugins: [ esbuild({ target: "es2020", tsconfig: path.resolve(ROOT_DIR, "tsconfig.json"), sourceMap: false, minify: false, loaders: { ".ts": "ts", }, }), ], }, minify: "terser", terserOptions: { format: { comments: false, }, compress: { keep_classnames: true, drop_console: true, drop_debugger: true, }, }, sourcemap: false, emptyOutDir: false, }, resolve: { alias: { "@": path.resolve(ROOT_DIR, "miniprogram"), }, }, }); } async function buildSass() { const scssFiles = await glob("**/*.scss", { cwd: SRC_DIR, ignore: [...IGNORE_PATTERNS, ...IGNORE_SCSS], }); await Promise.all(scssFiles.map(async (file) => { const srcFile = path.join(SRC_DIR, file); const distFile = path.join(DIST_DIR, file.replace(/\.scss$/, ".wxss")); const result = sass.compile(srcFile, { style: "compressed", }); await fs.outputFile(distFile, result.css); })); } async function copyOtherFiles() { const patterns = ["**/*.wxml", "**/*.json", "**/*.wxs", ...IGNORE_SCSS]; const files = await glob(patterns, { cwd: SRC_DIR, ignore: IGNORE_PATTERNS, }); await Promise.all(files.map((file) => fs.copy(path.join(SRC_DIR, file), path.join(DIST_DIR, file)))); } async function generateTypes() { const tsFiles = await glob("**/*.ts", { cwd: SRC_DIR, ignore: IGNORE_PATTERNS, }); const absTsFiles = tsFiles.map((file) => path.join("miniprogram", file)); const typesConfigPath = path.join(ROOT_DIR, "tsconfig.types.json"); const typesConfig = { extends: "./tsconfig.json", include: absTsFiles, compilerOptions: { declaration: true, emitDeclarationOnly: true, skipLibCheck: true, outDir: DIST_DIR, }, }; await fs.default.writeFile(typesConfigPath, JSON.stringify(typesConfig, null, 2), "utf8"); const { execSync } = await import("child_process"); execSync(`tsc -p ${typesConfigPath}`, { stdio: "inherit", cwd: ROOT_DIR, }); await fs.remove(typesConfigPath); } console.time("构建完成"); // 清理输出目录 await fs.remove(DIST_DIR); // 并行执行构建任务 await Promise.all([buildTypeScript(), buildSass(), copyOtherFiles()]); // 生成类型声明文件 await generateTypes(); console.timeEnd("构建完成"); }