完成了 BOM 管理和生产管理,完成部分发料单、采购计划和调拨单。
This commit is contained in:
61
node/compress.ts
Normal file
61
node/compress.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { Plugin } from "vite";
|
||||
import compressPlugin from "vite-plugin-compression";
|
||||
|
||||
/**
|
||||
* 打包压缩格式的类型声明
|
||||
*/
|
||||
export type ViteCompression = "none" | "gzip" | "brotli" | "both" | "gzip-clear" | "brotli-clear" | "both-clear";
|
||||
|
||||
export const configCompressPlugin = (compress: ViteCompression): Plugin | Plugin[] => {
|
||||
if (!compress || compress === "none") return [];
|
||||
|
||||
const gz = {
|
||||
// 生成的压缩包后缀
|
||||
ext: ".gz",
|
||||
// 体积大于 threshold 才会被压缩
|
||||
threshold: 0,
|
||||
// 默认压缩 .js|mjs|json|css|html 后缀文件,设置成 true,压缩全部文件
|
||||
filter: () => true,
|
||||
// 压缩后是否删除原始文件
|
||||
deleteOriginFile: false,
|
||||
};
|
||||
const br = {
|
||||
ext: ".br",
|
||||
algorithm: "brotliCompress",
|
||||
threshold: 0,
|
||||
filter: () => true,
|
||||
deleteOriginFile: false,
|
||||
};
|
||||
|
||||
const codeList = [
|
||||
{ k: "gzip", v: gz },
|
||||
{ k: "brotli", v: br },
|
||||
{ k: "both", v: [gz, br] },
|
||||
];
|
||||
|
||||
const plugins: Plugin[] = [];
|
||||
|
||||
codeList.forEach((item: any) => {
|
||||
if (compress.includes(item.k)) {
|
||||
if (compress.includes("clear")) {
|
||||
if (Array.isArray(item.v)) {
|
||||
item.v.forEach((vItem: any) => {
|
||||
plugins.push(compressPlugin(Object.assign(vItem, { deleteOriginFile: true })));
|
||||
});
|
||||
} else {
|
||||
plugins.push(compressPlugin(Object.assign(item.v, { deleteOriginFile: true })));
|
||||
}
|
||||
} else {
|
||||
if (Array.isArray(item.v)) {
|
||||
item.v.forEach((vItem: any) => {
|
||||
plugins.push(compressPlugin(vItem));
|
||||
});
|
||||
} else {
|
||||
plugins.push(compressPlugin(item.v));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return plugins;
|
||||
};
|
||||
72
node/getEnv.ts
Normal file
72
node/getEnv.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
export type Recordable<T = any> = Record<string, T>;
|
||||
|
||||
export function isDevFn(mode: string): boolean {
|
||||
return mode === "development";
|
||||
}
|
||||
|
||||
export function isProdFn(mode: string): boolean {
|
||||
return mode === "production";
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否开启生成 package 报告
|
||||
*/
|
||||
export function isReportMode(): boolean {
|
||||
return process.env.VITE_REPORT === "true";
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新解析 .env 的内容,重新封装类型,比如 .env 定义了 true,false,默认为字符串类型,需要转换为 boolean 类型
|
||||
*/
|
||||
export function wrapperEnv(envConf: Recordable): ImportMetaEnv {
|
||||
const ret: any = {};
|
||||
|
||||
for (const envName of Object.keys(envConf)) {
|
||||
let realName = envConf[envName].replace(/\\n/g, "\n");
|
||||
// 将 true 和 false 字符串转换为布尔值
|
||||
realName = realName === "true" ? true : realName === "false" ? false : realName;
|
||||
|
||||
// 指定变量名进行类型转换
|
||||
if (envName === "VITE_PORT") realName = Number(realName);
|
||||
ret[envName] = realName;
|
||||
process.env[envName] = realName;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从环境变量文件里获取变量值
|
||||
*
|
||||
* @param match 前缀
|
||||
* @param confFiles 文件列表
|
||||
*/
|
||||
export function getEnvConfig(match = "VITE_", confFiles = [".env", ".env.production", ".env.sit", ".env.uat"]) {
|
||||
let envConfig = {};
|
||||
confFiles.forEach(item => {
|
||||
try {
|
||||
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
|
||||
envConfig = { ...envConfig, ...env };
|
||||
} catch (error) {
|
||||
console.error(`Error in parsing ${item}`, error);
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(envConfig).forEach(key => {
|
||||
const reg = new RegExp(`^(${match})`);
|
||||
if (!reg.test(key)) {
|
||||
Reflect.deleteProperty(envConfig, key);
|
||||
}
|
||||
});
|
||||
return envConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目根路径
|
||||
*/
|
||||
export function getRootPath(...dir: string[]) {
|
||||
return path.resolve(process.cwd(), ...dir);
|
||||
}
|
||||
23
node/optimize.ts
Normal file
23
node/optimize.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 此文件作用于 `vite.config.ts` 的 `optimizeDeps.include` 依赖预构建配置项
|
||||
* 依赖预构建,`vite` 启动时会将下面 include 里的模块,编译成 esm 格式并缓存到 node_modules/.vite 文件夹,页面加载到对应模块时如果浏览器有缓存就读取浏览器缓存,如果没有会读取本地缓存并按需加载
|
||||
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
|
||||
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
|
||||
*/
|
||||
const include = [
|
||||
"qs",
|
||||
"mitt",
|
||||
"axios",
|
||||
"pinia",
|
||||
"vue-i18n",
|
||||
"sortablejs",
|
||||
"@vueuse/core",
|
||||
"pinia-plugin-persistedstate",
|
||||
];
|
||||
|
||||
/**
|
||||
* 在预构建中强制排除的依赖项
|
||||
*/
|
||||
const exclude = ["@iconify-icons/ant-design"];
|
||||
|
||||
export { include, exclude };
|
||||
76
node/plugins.ts
Normal file
76
node/plugins.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import { resolve } from "path";
|
||||
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
|
||||
import { createStyleImportPlugin, ElementPlusResolve } from "vite-plugin-style-import";
|
||||
import eslintPlugin from "vite-plugin-eslint";
|
||||
import progress from "vite-plugin-progress";
|
||||
import ServerUrlCopy from "vite-plugin-url-copy";
|
||||
import vueDevTools from "vite-plugin-vue-devtools";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||
import { configCompressPlugin } from "./compress";
|
||||
|
||||
export function getPluginsList(command: string, viteEnv: ImportMetaEnv) {
|
||||
const lifecycle = process.env.npm_lifecycle_event;
|
||||
return [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
viteEnv.VITE_DEVTOOLS && vueDevTools(),
|
||||
eslintPlugin({ cache: false }), // EsLint 报错信息显示在浏览器界面上
|
||||
ServerUrlCopy({
|
||||
qrcode: {
|
||||
disabled: true, // 是否生成二维码
|
||||
},
|
||||
}),
|
||||
|
||||
progress(),
|
||||
!viteEnv.VITE_LOAD_ALL_EP_STYLE
|
||||
? createStyleImportPlugin({
|
||||
resolves: [ElementPlusResolve()],
|
||||
libs: [
|
||||
{
|
||||
libraryName: "element-plus",
|
||||
esModule: true,
|
||||
resolveStyle: name => {
|
||||
if (!name.startsWith("el-")) return "";
|
||||
return `element-plus/theme-chalk/src/${name.replace(/^el-/, "")}.scss`;
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
: undefined,
|
||||
|
||||
AutoImport({
|
||||
imports: ["vue", "vue-router", "pinia"], // 自动引入 vue 的 ref、toRefs、onMounted 等,无需在页面中再次引入
|
||||
dts: "src/types/auto-import.d.ts", // 生成在 src 路径下名为 auto-import.d.ts 的声明文件
|
||||
eslintrc: {
|
||||
enabled: false, // 改为 true 用于生成 eslint 配置。生成后改回 false,避免重复生成消耗
|
||||
},
|
||||
resolvers: !viteEnv.VITE_LOAD_ALL_EP_COMPONENTS ? [ElementPlusResolver()] : [],
|
||||
}),
|
||||
|
||||
!viteEnv.VITE_LOAD_ALL_EP_COMPONENTS
|
||||
? Components({
|
||||
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
|
||||
dirs: "src/components", // 自定引入需要扫描的组件路径
|
||||
dts: "src/types/auto-components.d.ts", // 生成在 src 路径下名为 auto-components.d.ts 的声明文件
|
||||
directoryAsNamespace: true,
|
||||
})
|
||||
: undefined,
|
||||
|
||||
// 使用 svg 图标
|
||||
createSvgIconsPlugin({
|
||||
iconDirs: [resolve(process.cwd(), "src/common/assets/icons")],
|
||||
symbolId: "icon-[dir]-[name]",
|
||||
}),
|
||||
|
||||
viteEnv.VITE_BUILD_GZIP && configCompressPlugin(viteEnv.VITE_COMPRESSION),
|
||||
|
||||
// 打包分析
|
||||
(lifecycle === "report" || viteEnv.VITE_REPORT) &&
|
||||
visualizer({ open: true, brotliSize: true, filename: "report.html" }),
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user