UNPKG

@varlinor/builder-vue3

Version:

This package provides a set of Rollup and Vite configurations and utility functions tailored for Vue.js development environments, focusing on simplifying the build process for front-end development. It includes modules for configuring Rollup and Vite for

218 lines (215 loc) 7.17 kB
import fs from 'fs-extra'; import path from 'path'; import { normalizePath, scanFilesByConditions, loadJsonFile, getAllDependencies } from '@varlinor/node-tools'; import { build } from 'unbuild'; import { defineConfig, build as build$1 } from 'vite'; import vue from '@vitejs/plugin-vue'; import replacePlugin from '@rollup/plugin-replace'; import postcssPresetEnv from 'postcss-preset-env'; import cssInject from 'vite-plugin-css-injected-by-js'; import { merge, uniq } from 'lodash-es'; function getSfcBuildConfig(opts) { const { input, name, externals, output, plugins, replace, hooks } = opts; if (!input || !name) return null; const pluginArr = [...plugins, vue()]; if (!!replace) { pluginArr.push( replacePlugin({ preventAssingment: true, // 避免破坏赋值操作。 values: replace // 待替换的隐射 }) ); } return defineConfig({ configFile: false, plugins: [...pluginArr, cssInject()], css: { preprocessorOptions: { css: { charset: false } }, postcss: { plugins: [postcssPresetEnv()] } }, build: { minify: false, cssMinify: true, emptyOutDir: false, lib: { name, formats: ["es"], entry: input, filename: `${name}.js` }, rollupOptions: { external: Array.isArray(externals) && externals.length ? [...externals] : [], output } } }); } function getScriptBuildConfig(opts) { if (!opts.entries || !opts.externals) { throw new Error("entries or externals is empty, please check!"); } const { entries, externals, clean, rollup, alias, replace, hooks } = opts; const buildOpt = merge( { failOnWarn: false, clean: true, declaration: false, rollup: { emitCJS: false, output: { format: "es", // 设置输出格式为 ES 模块 entryFileNames: "[name].js" // 设置输出文件名为 .js 后缀 } } }, { entries, externals, clean, rollup, alias: alias || {}, replace: replace || {}, hooks // unbuild 提供的hooks } ); return buildOpt; } async function buildScripts(packageRoot, packOption) { const rootDir = normalizePath(path.resolve(process.cwd(), packageRoot || ".")); const externals = checkAndLoadExternals(rootDir, packOption.externals); const jsBuildOpt = getScriptBuildConfig({ entries: packOption.entries, // 所有的sfc的包含install的文件位置 clean: packOption.clean, externals, replace: packOption.replace || {}, alias: packOption.alias || {}, hooks: packOption.hooks || {} }); console.log("Ready to build script files ..."); await build(null, false, jsBuildOpt); copyStaticResources(rootDir, packOption.staticResources); console.log("Build script files successfully!"); } function copyStaticResources(packageRoot, staticResources) { if (!!staticResources && staticResources.length) { staticResources.forEach(({ src, dest }) => { const targetSrc = path.join(packageRoot, src); const targetDest = path.join(packageRoot, "dist", dest); if (fs.existsSync(targetSrc)) { console.log("copy [%s] to [dist/%s]!", targetSrc, targetDest); fs.copySync(targetSrc, targetDest); } }); } } async function buildPackage(packageRoot, packOption) { const rootDir = normalizePath(path.resolve(process.cwd(), packageRoot || ".")); const ComponentsInfo = checkAndLoadComDefs(rootDir); const allExternals = checkAndLoadExternals(rootDir, packOption.externals); const extraPlugins = packOption.plugins || []; const DistDir = `${rootDir}/dist`; const buildPromise = []; ComponentsInfo.forEach((com) => { const { packageName, basedir, filename, outputPath, outputFileName } = com; const outDir = outputPath.substring("/src".length, outputPath.length); const entryFileName = filename === "index.vue" ? filename : outputFileName === "index" ? "index" : `index-${outputFileName}`; const entry = path.join("./", outputPath, entryFileName); const outputBase = `${DistDir}/${outDir}`; const comOutPath = `${outDir}/${outputFileName}`; const buildOpt = getSfcBuildConfig({ input: entry, output: { dir: outputBase, entryFileNames: `${outputFileName}.js` }, name: comOutPath, externals: allExternals, plugins: extraPlugins, replace: packOption.replace }); if (buildOpt) { buildPromise.push(build$1(buildOpt)); } }); console.log("Ready to build Vue SFC ..."); await Promise.all(buildPromise); console.log("Build Vue SFC files successfully!"); if (packOption.entries) { const entries = []; entries.push(...packOption.entries); await buildScripts(packageRoot, { entries, externals: allExternals, clean: false, replace: packOption.replace, hooks: packOption.hooks }); } copyStaticResources(packageRoot, packOption.staticResources); } function getI18nFiles(packageRoot) { function filterFunc(f, filePath, parentPath) { return parentPath.indexOf("node_modules") < 0 && parentPath.endsWith("i18n"); } return getScriptFiles(packageRoot, filterFunc); } function getScriptFiles(packageRoot, entryFilter) { function modifier(file, filePath, parentPath) { let name = path.basename(filePath, ".ts"); let parentP = normalizePath(parentPath); if (!parentP.endsWith("/")) { parentP += "/"; } const srcIndex = parentP.indexOf("src/"); let pPath = parentP; if (srcIndex !== -1) { pPath = parentP.slice(srcIndex + "src/".length); } if (pPath.indexOf("./") === 0) { pPath = pPath.substring(2); } name = pPath ? `${pPath}${name}` : name; return { name, input: normalizePath(filePath) }; } function filterFunc(f, filePath, parentPath) { if (entryFilter != null && typeof entryFilter == "function") { return filePath.endsWith(".ts") && entryFilter(f, filePath, parentPath); } else { return filePath.endsWith(".ts"); } } return scanFilesByConditions(packageRoot, modifier, filterFunc); } function checkAndLoadComDefs(rootDir) { const comDefPath = path.join(rootDir, "./components.json"); if (!fs.existsSync(comDefPath)) { throw new Error(`Cannot find components.json in dir [${rootDir}]`); } return loadJsonFile(comDefPath); } function checkAndLoadExternals(rootDir, extraExternals) { const pkgPath = path.join(rootDir, "./package.json"); if (!fs.existsSync(pkgPath)) { throw new Error(`Cannot find package.json in dir [${rootDir}]`); } const { dependencies, devDependencies } = loadJsonFile(pkgPath); const externals = getAllDependencies(dependencies); const devExternals = getAllDependencies(devDependencies); let allExternals = [...externals, ...devExternals]; if (extraExternals) { allExternals = uniq([...allExternals, ...extraExternals]); } return allExternals; } export { buildPackage, buildScripts, getI18nFiles, getScriptBuildConfig, getScriptFiles, getSfcBuildConfig };