feat(All):Initial
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@astral3d/build-vite-plugins",
|
||||
"author": "ErSan<mlt131220@163.com>",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^11.0.3",
|
||||
"dotenv": "16.3.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"rollup-plugin-visualizer": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"unplugin-config": "^0.1.5",
|
||||
"vite": "catalog:",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-enhance-log": "^0.6.2",
|
||||
"vite-plugin-top-level-await": "^1.3.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './utils.ts';
|
||||
export * from './plugins/index.ts';
|
||||
@@ -0,0 +1,28 @@
|
||||
// @ts-ignore
|
||||
import ConfigPlugin from 'unplugin-config/vite';
|
||||
import type { PluginOption } from 'vite';
|
||||
import {getEnvConfig,strToHex} from "../utils.ts";
|
||||
|
||||
export async function createConfigPluginConfig(
|
||||
shouldGenerateConfig: boolean,
|
||||
): Promise<PluginOption> {
|
||||
const config:Record<string, any> = await getEnvConfig();
|
||||
const APP_NAME = strToHex(config?.VITE_GLOB_APP_TITLE ?? '__APP');
|
||||
// https://github.com/kirklin/unplugin-config
|
||||
return ConfigPlugin({
|
||||
appName: APP_NAME,
|
||||
baseDir:"./",
|
||||
envVariables: {
|
||||
prefix: 'VITE_GLOB_',
|
||||
files: [".env.production", ".env"],
|
||||
},
|
||||
configFile: {
|
||||
generate: shouldGenerateConfig,
|
||||
fileName: '_astral3d.config.js',
|
||||
outputDir: 'dist',
|
||||
},
|
||||
htmlInjection: {
|
||||
decodeEntities: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 用于打包和输出gzip;
|
||||
* 注意,这在Vite中不能正常工作,具体原因还在调查中
|
||||
* https://github.com/anncwb/vite-plugin-compression
|
||||
*/
|
||||
import type { PluginOption } from 'vite';
|
||||
import compressPlugin from 'vite-plugin-compression';
|
||||
|
||||
export function configCompressPlugin({compress,deleteOriginFile = false}: {
|
||||
compress: "gzip" | "brotli" | "none";
|
||||
deleteOriginFile?: boolean;
|
||||
}): PluginOption[] {
|
||||
const compressList = compress.split(',');
|
||||
|
||||
const plugins: PluginOption[] = [];
|
||||
|
||||
if (compressList.includes('gzip')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.gz',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (compressList.includes('brotli')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import type {PluginOption} from 'vite';
|
||||
import topLevelAwait from "vite-plugin-top-level-await";
|
||||
import EnhanceLog from 'vite-plugin-enhance-log';
|
||||
|
||||
import {createConfigPluginConfig} from "./appConfig.ts";
|
||||
import {configCompressPlugin} from "./compress.ts";
|
||||
import {configVisualizerConfig} from "./visualizer.ts";
|
||||
|
||||
interface Options {
|
||||
isBuild: boolean;
|
||||
root: string;
|
||||
compress: {
|
||||
compress: "gzip" | "brotli" | "none";
|
||||
deleteOriginFile: boolean;
|
||||
};
|
||||
enableAnalyze?: boolean;
|
||||
enableConfig?: boolean;
|
||||
}
|
||||
|
||||
export async function createPlugins({isBuild,compress,enableAnalyze,enableConfig}: Options) {
|
||||
const vitePlugins: (PluginOption | PluginOption[])[] = [
|
||||
topLevelAwait({
|
||||
// 每个块模块的顶级await promise的导出名称
|
||||
promiseExportName: "__tla",
|
||||
// 用于在每个块模块中生成顶级await承诺的导入名称的函数
|
||||
promiseImportName: i => `__tla_${i}`
|
||||
}),
|
||||
EnhanceLog({
|
||||
/** 高亮文件名(firefox不支持) */
|
||||
colorFileName: true,
|
||||
splitBy: '\n',
|
||||
preTip: '🚀🚀🚀🚀🚀🚀',
|
||||
enableFileName: { enableDir: false}
|
||||
}),
|
||||
];
|
||||
|
||||
if(enableConfig){
|
||||
const appConfigPlugin = await createConfigPluginConfig(isBuild);
|
||||
vitePlugins.push(appConfigPlugin);
|
||||
}
|
||||
|
||||
// 以下插件只在生产环境中工作
|
||||
if (isBuild) {
|
||||
// rollup-plugin-gzip
|
||||
vitePlugins.push(configCompressPlugin(compress));
|
||||
|
||||
// 打包视图分析 rollup-plugin-visualizer
|
||||
if (enableAnalyze) {
|
||||
vitePlugins.push(configVisualizerConfig());
|
||||
}
|
||||
}
|
||||
|
||||
return vitePlugins;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* package.json包文件容量分析
|
||||
*/
|
||||
// @ts-ignore
|
||||
import {visualizer} from 'rollup-plugin-visualizer';
|
||||
import { type PluginOption } from 'vite';
|
||||
|
||||
export function configVisualizerConfig() {
|
||||
return visualizer({
|
||||
filename: 'node_modules/.cache/visualizer/stats.html',
|
||||
open: true,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
}) as PluginOption;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { join } from 'node:path';
|
||||
import pkg from 'fs-extra';
|
||||
import {parse} from "dotenv";
|
||||
|
||||
/**
|
||||
* 读取所有环境变量配置文件以处理.env
|
||||
*/
|
||||
export function wrapperEnv(envConf) {
|
||||
const ret:any = {};
|
||||
|
||||
for (const envName of Object.keys(envConf)) {
|
||||
let realName = envConf[envName].replace(/\\n/g, '\n');
|
||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
||||
|
||||
if (envName === 'VITE_PORT') {
|
||||
realName = Number(realName);
|
||||
}
|
||||
|
||||
ret[envName] = realName;
|
||||
if (typeof realName === 'string') {
|
||||
process.env[envName] = realName;
|
||||
} else if (typeof realName === 'object') {
|
||||
process.env[envName] = JSON.stringify(realName);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境下生效的配置文件名
|
||||
*/
|
||||
function getConfFiles() {
|
||||
const script = process.env.npm_lifecycle_script;
|
||||
const reg = new RegExp('--mode ([a-z_\\d]+)');
|
||||
const result = reg.exec(script as string) as any;
|
||||
if (result) {
|
||||
const mode = result[1] as string;
|
||||
return ['.env', `.env.${mode}`];
|
||||
}
|
||||
return ['.env', '.env.production'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取以指定前缀开头的环境变量
|
||||
* @param match prefix
|
||||
* @param confFiles ext
|
||||
*/
|
||||
export async function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) {
|
||||
let envConfig = {};
|
||||
for (const confFile of confFiles) {
|
||||
try {
|
||||
const envPath = await pkg.readFile(join(process.cwd(), confFile), { encoding: 'utf8' });
|
||||
const env = parse(envPath);
|
||||
envConfig = { ...envConfig, ...env };
|
||||
} catch (e) {
|
||||
console.error(`Error in parsing ${confFile}`, e);
|
||||
}
|
||||
}
|
||||
const reg = new RegExp(`^(${match})`);
|
||||
Object.keys(envConfig).forEach((key) => {
|
||||
if (!reg.test(key)) {
|
||||
Reflect.deleteProperty(envConfig, key);
|
||||
}
|
||||
});
|
||||
return envConfig;
|
||||
}
|
||||
|
||||
export function strToHex(str: string) {
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const hex = str.charCodeAt(i).toString(16);
|
||||
result.push(('000' + hex).slice(-4));
|
||||
}
|
||||
return result.join('').toUpperCase();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": false,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "Bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
"baseUrl": ".",
|
||||
"types": [],
|
||||
"typeRoots": ["./node_modules/@types/"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": []
|
||||
}
|
||||
Reference in New Issue
Block a user