提交 bd7b53f1 编写于 作者: V vben

fix(build): fix environment variable configuration file failure

上级 e6db0d39
VITE_PORT = 3100
# Whether to open mock
VITE_USE_MOCK = true
......
......@@ -8,7 +8,7 @@ VITE_PUBLIC_PATH = ./
VITE_DROP_CONSOLE = true
# Whether to output gz file for packaging
VITE_BUILD_GZIP = false
VITE_BUILD_GZIP = true
# Basic interface address SPA
VITE_GLOB_API_URL=/api
......
......@@ -5,13 +5,10 @@
- 新增 `v-ripple`水波纹指令
- 新增左侧菜单混合模式
### ✨ Refactor
- 移除折叠显示菜单名配置
### 🐛 Bug Fixes
- 修复混合模式下滚动条丢失问题
- 修复环境变量配置失效以及 history 模式下 logo 地址问题
## 2.0.0-rc.14 (2020-12-15)
......
......@@ -4,7 +4,6 @@
import { GLOB_CONFIG_FILE_NAME } from '../constant';
import fs, { writeFileSync } from 'fs-extra';
import viteConfig from '../../vite.config';
import { errorConsole, successConsole, getCwdPath, getEnvConfig } from '../utils';
import { getShortName } from '../getShortName';
......@@ -17,7 +16,7 @@ function createConfig(
) {
try {
const windowConf = `window.${configName}`;
const outDir = viteConfig.outDir || 'dist';
const outDir = 'dist';
// Ensure that the variable will not be modified
const configStr = `${windowConf}=${JSON.stringify(config)};
......
// #!/usr/bin/env node
import { sh } from 'tasksfile';
import { argv } from 'yargs';
import { runBuildConfig } from './buildConf';
// import { runUpdateHtml } from './updateHtml';
import { errorConsole, successConsole } from '../utils';
import { startGzipStyle } from '../vite/plugin/gzip/compress';
export const runBuild = async (preview = false) => {
export const runBuild = async () => {
try {
const argvList = argv._;
if (preview) {
let cmd = `cross-env NODE_ENV=production vite build`;
await sh(cmd, {
async: true,
nopipe: true,
});
}
// Generate configuration file
if (!argvList.includes('no-conf')) {
await runBuildConfig();
}
// await runUpdateHtml();
if (!preview) {
await startGzipStyle();
}
await startGzipStyle();
successConsole('Vite Build successfully!');
} catch (error) {
errorConsole('Vite Build Error\n' + error);
......
// Do you need to update the dependencies to prevent package.json from updating the dependencies, and no install after others get the code
import path from 'path';
import fs from 'fs-extra';
import { isEqual } from 'lodash';
import { sh } from 'tasksfile';
import { successConsole, errorConsole } from '../utils';
const resolve = (dir: string) => {
return path.resolve(process.cwd(), dir);
};
const reg = /[\u4E00-\u9FA5\uF900-\uFA2D]/;
let NEED_INSTALL = false;
export async function runPreserve() {
// rc.6 fixed
const cwdPath = process.cwd();
if (reg.test(cwdPath)) {
errorConsole(
'Do not include Chinese, Japanese or Korean in the full path of the project directory, please modify the directory name and run again!'
);
errorConsole('项目目录全路径请勿包含中文、日文、韩文,请修改目录名后再次重新运行!');
process.exit(1);
}
await fs.mkdirp(resolve('build/.cache'));
function checkPkgUpdate() {
const pkg = require('../../package.json');
const { dependencies, devDependencies } = pkg;
const depsFile = resolve('build/.cache/deps.json');
if (!fs.pathExistsSync(depsFile)) {
NEED_INSTALL = true;
return;
}
const depsJson = require('../.cache/deps.json');
if (!isEqual(depsJson, { dependencies, devDependencies })) {
NEED_INSTALL = true;
}
}
checkPkgUpdate();
if (NEED_INSTALL) {
// no error
successConsole(
'A dependency change is detected, and the dependency is being installed to ensure that the dependency is consistent! (Tip: The project will be executed for the first time)!'
);
try {
await sh('npm run bootstrap ', {
async: true,
nopipe: true,
});
successConsole('Dependency installation is successful, start running the project!');
const pkg = require('../../package.json');
const { dependencies, devDependencies } = pkg;
const depsFile = resolve('build/.cache/deps.json');
const deps = { dependencies, devDependencies };
if (!fs.pathExistsSync(depsFile)) {
fs.writeFileSync(depsFile, JSON.stringify(deps));
} else {
const depsFile = resolve('build/.cache/deps.json');
const depsJson = require('../.cache/deps.json');
if (!isEqual(depsJson, deps)) {
fs.writeFileSync(depsFile, JSON.stringify(deps));
}
}
} catch (error) {}
}
}
runPreserve();
......@@ -4,12 +4,7 @@ import Koa from 'koa';
import staticServer from 'koa-static';
import portfinder from 'portfinder';
import { resolve } from 'path';
import viteConfig from '../../vite.config';
import { getIPAddress } from '../utils';
// import { runBuild } from './postBuild';
// const BUILD = 1;
// const NO_BUILD = 2;
// start server
const startApp = () => {
......@@ -17,7 +12,7 @@ const startApp = () => {
portfinder.basePort = port;
const app = new Koa();
app.use(staticServer(resolve(process.cwd(), viteConfig.outDir || 'dist')));
app.use(staticServer(resolve(process.cwd(), 'dist')));
portfinder.getPort(async (err, port) => {
if (err) {
......@@ -35,25 +30,4 @@ const startApp = () => {
});
};
// export const runPreview = async () => {
// // const prompt = inquirer.prompt({
// // type: 'list',
// // message: 'Please select a preview method',
// // name: 'type',
// // choices: [
// // {
// // name: 'Preview after packaging',
// // value: BUILD,
// // },
// // {
// // name: `No packaging, preview directly (need to have dist file after packaging)`,
// // value: NO_BUILD,
// // },
// // ],
// // });
// const { type } = await prompt;
// if (type === BUILD) {
// await runBuild(true);
// }
// };
startApp();
......@@ -63,12 +63,12 @@ export function getIPAddress() {
return '';
}
export function isDevFn(): boolean {
return process.env.NODE_ENV === 'development';
export function isDevFn(mode: 'development' | 'production'): boolean {
return mode === 'development';
}
export function isProdFn(): boolean {
return process.env.NODE_ENV === 'production';
export function isProdFn(mode: 'development' | 'production'): boolean {
return mode === 'production';
}
/**
......@@ -106,18 +106,11 @@ export interface ViteEnv {
}
// Read all environment variable configuration files to process.env
export function loadEnv(): ViteEnv {
const env = process.env.NODE_ENV;
export function wrapperEnv(envConf: any): ViteEnv {
const ret: any = {};
const envList = [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env', ,];
envList.forEach((e) => {
dotenv.config({
path: e,
});
});
for (const envName of Object.keys(process.env)) {
let realName = (process.env as any)[envName].replace(/\\n/g, '\n');
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);
......
import { gzip } from 'zlib';
import { readFileSync, writeFileSync } from 'fs';
import { GzipPluginOptions } from './types';
import viteConfig from '../../../../vite.config';
import { readAllFile, getCwdPath, isBuildGzip, isSiteMode } from '../../../utils';
export function startGzip(
......@@ -22,8 +21,8 @@ export function startGzip(
// 手动压缩css
export async function startGzipStyle() {
if (isBuildGzip() || isSiteMode()) {
const outDir = viteConfig.outDir || 'dist';
const assets = viteConfig.assetsDir || '_assets';
const outDir = 'dist';
const assets = '_assets';
const allCssFile = readAllFile(getCwdPath(outDir, assets), /\.(css)$/);
for (const path of allCssFile) {
const source = readFileSync(path);
......
......@@ -7,16 +7,21 @@ import { hmScript } from '../hm';
import pkg from '../../../package.json';
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
export function setupHtmlPlugin(plugins: Plugin[], env: ViteEnv) {
export function setupHtmlPlugin(
plugins: Plugin[],
env: ViteEnv,
mode: 'development' | 'production'
) {
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env;
const htmlPlugin = ViteHtmlPlugin({
// html title
title: VITE_GLOB_APP_TITLE,
minify: isProdFn(),
minify: isProdFn(mode),
options: {
publicPath: VITE_PUBLIC_PATH,
// Package and insert additional configuration files
injectConfig: isProdFn()
injectConfig: isProdFn(mode)
? `<script src='${VITE_PUBLIC_PATH || './'}${GLOB_CONFIG_FILE_NAME}?v=${
pkg.version
}-${new Date().getTime()}'></script>`
......
......@@ -8,21 +8,21 @@ import gzipPlugin from './gzip/index';
// @ts-ignore
import pkg from '../../../package.json';
import { isProdFn, isSiteMode, ViteEnv, isReportMode, isBuildGzip } from '../../utils';
import { isSiteMode, ViteEnv, isReportMode, isBuildGzip } from '../../utils';
import { setupHtmlPlugin } from './html';
import { setupPwaPlugin } from './pwa';
import { setupMockPlugin } from './mock';
// gen vite plugins
export function createVitePlugins(viteEnv: ViteEnv) {
export function createVitePlugins(viteEnv: ViteEnv, mode: 'development' | 'production') {
const vitePlugins: VitePlugin[] = [];
// vite-plugin-html
setupHtmlPlugin(vitePlugins, viteEnv);
setupHtmlPlugin(vitePlugins, viteEnv, mode);
// vite-plugin-pwa
setupPwaPlugin(vitePlugins, viteEnv);
setupPwaPlugin(vitePlugins, viteEnv, mode);
// vite-plugin-mock
setupMockPlugin(vitePlugins, viteEnv);
setupMockPlugin(vitePlugins, viteEnv, mode);
// vite-plugin-purge-icons
vitePlugins.push(PurgeIcons());
......@@ -34,12 +34,11 @@ export function createVitePlugins(viteEnv: ViteEnv) {
export function createRollupPlugin() {
const rollupPlugins: rollupPlugin[] = [];
if (!isProdFn() && isReportMode()) {
if (isReportMode()) {
// rollup-plugin-visualizer
rollupPlugins.push(visualizer({ filename: './build/.cache/stats.html', open: true }) as Plugin);
}
if (!isProdFn() && (isBuildGzip() || isSiteMode())) {
if (isBuildGzip() || isSiteMode()) {
// rollup-plugin-gizp
rollupPlugins.push(gzipPlugin());
}
......
......@@ -2,14 +2,22 @@ import { createMockServer } from 'vite-plugin-mock';
import type { Plugin } from 'vite';
import { isDevFn, ViteEnv } from '../../utils';
export function setupMockPlugin(plugins: Plugin[], env: ViteEnv) {
export function setupMockPlugin(
plugins: Plugin[],
env: ViteEnv,
mode: 'development' | 'production'
) {
const { VITE_USE_MOCK } = env;
const mockPlugin = createMockServer({
ignore: /^\_/,
mockPath: 'mock',
showTime: true,
});
if (isDevFn() && VITE_USE_MOCK) {
const useMock = isDevFn(mode) && VITE_USE_MOCK;
if (useMock) {
const mockPlugin = createMockServer({
ignore: /^\_/,
mockPath: 'mock',
showTime: true,
localEnabled: useMock,
});
plugins.push(mockPlugin);
}
return plugins;
......
import { VitePWA } from 'vite-plugin-pwa';
import type { Plugin } from 'vite';
import { isProdFn, ViteEnv } from '../../utils';
import { ViteEnv } from '../../utils';
export function setupPwaPlugin(plugins: Plugin[], env: ViteEnv) {
export function setupPwaPlugin(
plugins: Plugin[],
env: ViteEnv,
// @ts-ignore
mode: 'development' | 'production'
) {
const { VITE_USE_PWA } = env;
const pwaPlugin = VitePWA({
......@@ -23,8 +28,7 @@ export function setupPwaPlugin(plugins: Plugin[], env: ViteEnv) {
],
},
});
if (isProdFn() && VITE_USE_PWA) {
if (VITE_USE_PWA) {
plugins.push(pwaPlugin);
}
return plugins;
......
......@@ -2,21 +2,31 @@ type ProxyItem = [string, string];
type ProxyList = ProxyItem[];
const reg = /^https:\/\//;
type ProxyTargetList = Record<
string,
{
target: string;
changeOrigin: boolean;
rewrite: (path: string) => any;
secure?: boolean;
}
>;
const httpsRE = /^https:\/\//;
/**
* Generate proxy
* @param list
*/
export function createProxy(list: ProxyList = []) {
const ret: any = {};
const ret: ProxyTargetList = {};
for (const [prefix, target] of list) {
const isHttps = reg.test(target);
const isHttps = httpsRE.test(target);
ret[prefix] = {
target: target,
changeOrigin: true,
rewrite: (path: string) => path.replace(new RegExp(`^${prefix}`), ''),
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
// https is require secure=false
...(isHttps ? { secure: false } : {}),
};
......
......@@ -137,7 +137,11 @@
</style>
<div class="app-loading">
<div class="app-loading-wrap">
<img src="./resource/img/logo.png" class="app-loading-logo" alt="Logo" />
<img
src="<%= viteHtmlPluginOptions.publicPath %>resource/img/logo.png"
class="app-loading-logo"
alt="Logo"
/>
<div class="app-loading-dots">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
......
......@@ -3,8 +3,8 @@
"version": "2.0.0-rc.14",
"scripts": {
"bootstrap": "yarn install",
"serve": "esno ./build/script/preserve.ts && cross-env NODE_ENV=development vite",
"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
"serve": "cross-env vite --mode=development",
"build": "cross-env vite build --mode=production && esno ./build/script/postBuild.ts",
"build:site": "cross-env SITE=true npm run build ",
"build:no-cache": "yarn clean:cache && npm run build",
"typecheck": "typecheck .",
......
......@@ -38,7 +38,7 @@ setupErrorHandle(app);
// Mount when the route is ready
router.isReady().then(() => {
app.mount('#app');
app.mount('#app', true);
});
// The development environment takes effect
......
......@@ -9,11 +9,9 @@ import { basicRoutes } from './routes/';
import { scrollBehavior } from './scrollBehavior';
import { REDIRECT_NAME } from './constant';
export const hashRouter = createWebHashHistory();
// app router
const router = createRouter({
history: hashRouter,
history: createWebHashHistory(),
routes: basicRoutes as RouteRecordRaw[],
strict: true,
scrollBehavior: scrollBehavior,
......
import type { UserConfig, Resolver } from 'vite';
import { resolve } from 'path';
import { loadEnv } from 'vite';
import { modifyVars } from './build/config/lessModifyVars';
import { createProxy } from './build/vite/proxy';
import { configManualChunk } from './build/vite/optimizer';
......@@ -8,16 +10,12 @@ import { configManualChunk } from './build/vite/optimizer';
import globbyTransform from './build/vite/plugin/transform/globby';
import dynamicImportTransform from './build/vite/plugin/transform/dynamic-import';
import { loadEnv } from './build/utils';
import { wrapperEnv } from './build/utils';
import { createRollupPlugin, createVitePlugins } from './build/vite/plugin';
const pkg = require('./package.json');
const viteEnv = loadEnv();
const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY, VITE_DROP_CONSOLE, VITE_DYNAMIC_IMPORT } = viteEnv;
function pathResolve(dir: string) {
return resolve(__dirname, '.', dir);
}
......@@ -30,84 +28,93 @@ const root: string = process.cwd();
const resolvers: Resolver[] = [];
const viteConfig: UserConfig = {
root,
alias,
/**
* port
* @default '3000'
*/
port: VITE_PORT,
/**
* Base public path when served in production.
* @default '/'
*/
base: VITE_PUBLIC_PATH,
/**
* Transpile target for esbuild.
* @default 'es2020'
*/
esbuildTarget: 'es2019',
// terser options
terserOptions: {
compress: {
keep_infinity: true,
drop_console: VITE_DROP_CONSOLE,
export default (mode: 'development' | 'production'): UserConfig => {
const env = loadEnv(mode, root);
const viteEnv = wrapperEnv(env);
const {
VITE_PORT,
VITE_PUBLIC_PATH,
VITE_PROXY,
VITE_DROP_CONSOLE,
VITE_DYNAMIC_IMPORT,
} = viteEnv;
return {
root,
alias,
/**
* port
* @default '3000'
*/
port: VITE_PORT,
/**
* Base public path when served in production.
* @default '/'
*/
base: VITE_PUBLIC_PATH,
/**
* Transpile target for esbuild.
* @default 'es2020'
*/
esbuildTarget: 'es2019',
// terser options
terserOptions: {
compress: {
keep_infinity: true,
drop_console: VITE_DROP_CONSOLE,
},
},
define: {
__VERSION__: pkg.version,
// setting vue-i18-next
// Suppress warning
__VUE_I18N_LEGACY_API__: false,
__VUE_I18N_FULL_INSTALL__: false,
__INTLIFY_PROD_DEVTOOLS__: false,
},
cssPreprocessOptions: {
less: {
modifyVars: modifyVars,
javascriptEnabled: true,
},
},
},
define: {
__VERSION__: pkg.version,
// setting vue-i18-next
// Suppress warning
__VUE_I18N_LEGACY_API__: false,
__VUE_I18N_FULL_INSTALL__: false,
__INTLIFY_PROD_DEVTOOLS__: false,
},
cssPreprocessOptions: {
less: {
modifyVars: modifyVars,
javascriptEnabled: true,
// The package will be recompiled using rollup, and the new package compiled into the esm module specification will be put into node_modules/.vite_opt_cache
optimizeDeps: {
include: [
'qs',
'echarts/map/js/china',
'ant-design-vue/es/locale/zh_CN',
'ant-design-vue/es/locale/en_US',
'@ant-design/icons-vue',
],
},
},
// The package will be recompiled using rollup, and the new package compiled into the esm module specification will be put into node_modules/.vite_opt_cache
optimizeDeps: {
include: [
'qs',
'echarts/map/js/china',
'ant-design-vue/es/locale/zh_CN',
'ant-design-vue/es/locale/en_US',
'@ant-design/icons-vue',
transforms: [
globbyTransform({
resolvers: resolvers,
root: root,
alias: alias,
includes: [resolve('src/router'), resolve('src/locales')],
}),
dynamicImportTransform(VITE_DYNAMIC_IMPORT),
],
},
transforms: [
globbyTransform({
resolvers: resolvers,
root: root,
alias: alias,
includes: [resolve('src/router'), resolve('src/locales')],
}),
dynamicImportTransform(VITE_DYNAMIC_IMPORT),
],
proxy: createProxy(VITE_PROXY),
plugins: createVitePlugins(viteEnv),
rollupInputOptions: {
plugins: createRollupPlugin(),
},
rollupOutputOptions: {
compact: true,
manualChunks: configManualChunk,
},
};
export default viteConfig;
proxy: createProxy(VITE_PROXY),
plugins: createVitePlugins(viteEnv, mode),
rollupInputOptions: {
plugins: createRollupPlugin(),
},
rollupOutputOptions: {
compact: true,
manualChunks: configManualChunk,
},
};
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册