@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
234 lines (228 loc) • 8.08 kB
JavaScript
'use strict';
const fs = require('fs-extra');
const path = require('path');
const nodeTools = require('@varlinor/node-tools');
const unbuild = require('unbuild');
const vite = require('vite');
const vue = require('@vitejs/plugin-vue');
const replacePlugin = require('@rollup/plugin-replace');
const postcssPresetEnv = require('postcss-preset-env');
const cssInject = require('vite-plugin-css-injected-by-js');
const lodashEs = require('lodash-es');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
const vue__default = /*#__PURE__*/_interopDefaultCompat(vue);
const replacePlugin__default = /*#__PURE__*/_interopDefaultCompat(replacePlugin);
const postcssPresetEnv__default = /*#__PURE__*/_interopDefaultCompat(postcssPresetEnv);
const cssInject__default = /*#__PURE__*/_interopDefaultCompat(cssInject);
function getSfcBuildConfig(opts) {
const { input, name, externals, output, plugins, replace, hooks } = opts;
if (!input || !name) return null;
const pluginArr = [...plugins, vue__default()];
if (!!replace) {
pluginArr.push(
replacePlugin__default({
preventAssingment: true,
// 避免破坏赋值操作。
values: replace
// 待替换的隐射
})
);
}
return vite.defineConfig({
configFile: false,
plugins: [...pluginArr, cssInject__default()],
css: {
preprocessorOptions: { css: { charset: false } },
postcss: {
plugins: [postcssPresetEnv__default()]
}
},
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 = lodashEs.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 = nodeTools.normalizePath(path__default.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 unbuild.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__default.join(packageRoot, src);
const targetDest = path__default.join(packageRoot, "dist", dest);
if (fs__default.existsSync(targetSrc)) {
console.log("copy [%s] to [dist/%s]!", targetSrc, targetDest);
fs__default.copySync(targetSrc, targetDest);
}
});
}
}
async function buildPackage(packageRoot, packOption) {
const rootDir = nodeTools.normalizePath(path__default.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__default.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(vite.build(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__default.basename(filePath, ".ts");
let parentP = nodeTools.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: nodeTools.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 nodeTools.scanFilesByConditions(packageRoot, modifier, filterFunc);
}
function checkAndLoadComDefs(rootDir) {
const comDefPath = path__default.join(rootDir, "./components.json");
if (!fs__default.existsSync(comDefPath)) {
throw new Error(`Cannot find components.json in dir [${rootDir}]`);
}
return nodeTools.loadJsonFile(comDefPath);
}
function checkAndLoadExternals(rootDir, extraExternals) {
const pkgPath = path__default.join(rootDir, "./package.json");
if (!fs__default.existsSync(pkgPath)) {
throw new Error(`Cannot find package.json in dir [${rootDir}]`);
}
const { dependencies, devDependencies } = nodeTools.loadJsonFile(pkgPath);
const externals = nodeTools.getAllDependencies(dependencies);
const devExternals = nodeTools.getAllDependencies(devDependencies);
let allExternals = [...externals, ...devExternals];
if (extraExternals) {
allExternals = lodashEs.uniq([...allExternals, ...extraExternals]);
}
return allExternals;
}
exports.buildPackage = buildPackage;
exports.buildScripts = buildScripts;
exports.getI18nFiles = getI18nFiles;
exports.getScriptBuildConfig = getScriptBuildConfig;
exports.getScriptFiles = getScriptFiles;
exports.getSfcBuildConfig = getSfcBuildConfig;