diff --git a/.env.development b/.env.development index 36595b60d0c43c7f2205d6cbf68de35dc9f38ef2..a15f7ffe6f5cd7319aec5173601f0e822c5cb56e 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,5 @@ +VITE_PORT = 3100 + # Whether to open mock VITE_USE_MOCK = true diff --git a/.env.production b/.env.production index 2f6243c72cb8e4c90d3f8f8186f2d0c3c05551d5..ec9a400d50f5c41e9b9a932a7a3c399260ea4a33 100644 --- a/.env.production +++ b/.env.production @@ -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 diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index cbadb9f9f3dc9fc248e24f3f566bb973c9c251da..9bd6605b85b79ee848ba11dc11d9e9c74e6a96ec 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -5,13 +5,10 @@ - 新增 `v-ripple`水波纹指令 - 新增左侧菜单混合模式 -### ✨ Refactor - -- 移除折叠显示菜单名配置 - ### 🐛 Bug Fixes - 修复混合模式下滚动条丢失问题 +- 修复环境变量配置失效以及 history 模式下 logo 地址问题 ## 2.0.0-rc.14 (2020-12-15) diff --git a/build/script/buildConf.ts b/build/script/buildConf.ts index 15e54d750cfdf770ab5614f4860fcd1ee4faa7d0..25220b2ce480cc04456200b99c5647db6d20ea87 100644 --- a/build/script/buildConf.ts +++ b/build/script/buildConf.ts @@ -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)}; diff --git a/build/script/postBuild.ts b/build/script/postBuild.ts index 75683f25392da703e3e78584d153c2343c9d20d6..3a9574f09988e06c39a2e659c01dfc1ab70ee29d 100644 --- a/build/script/postBuild.ts +++ b/build/script/postBuild.ts @@ -1,32 +1,20 @@ // #!/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); diff --git a/build/script/preserve.ts b/build/script/preserve.ts deleted file mode 100644 index 443ad881e53f24d39da20340200aa7e5ffb22005..0000000000000000000000000000000000000000 --- a/build/script/preserve.ts +++ /dev/null @@ -1,74 +0,0 @@ -// 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(); diff --git a/build/script/preview.ts b/build/script/preview.ts index 6f8c08adc3cac544fe3da74ffd9fc383fc60b273..ba0bcbd40ecb35e5b6632bf706d1dea10be566a4 100644 --- a/build/script/preview.ts +++ b/build/script/preview.ts @@ -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(); diff --git a/build/utils.ts b/build/utils.ts index 662cd123fc3c9e94e93cbd69e781268c106fea86..93d0019bf925b8087302798543e3230715591c69 100644 --- a/build/utils.ts +++ b/build/utils.ts @@ -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); diff --git a/build/vite/plugin/gzip/compress.ts b/build/vite/plugin/gzip/compress.ts index 80fae75041de357724632867e10f0017f978beb9..119bbe80481654becfff570e7ae4fd878a5cc180 100644 --- a/build/vite/plugin/gzip/compress.ts +++ b/build/vite/plugin/gzip/compress.ts @@ -1,7 +1,6 @@ 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); diff --git a/build/vite/plugin/html.ts b/build/vite/plugin/html.ts index 1b107f439d4f4cc5c52154c8aaab10a7f10d2e3f..dd1af20e40b4e034dae9c11d14a54c7f233f8f13 100644 --- a/build/vite/plugin/html.ts +++ b/build/vite/plugin/html.ts @@ -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) ? `` diff --git a/build/vite/plugin/index.ts b/build/vite/plugin/index.ts index 922432fd638e1a08f6a6c8a18deaef8105bf418c..5db946ac9d7d4c9c063dc4833f0302d442d795e5 100644 --- a/build/vite/plugin/index.ts +++ b/build/vite/plugin/index.ts @@ -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()); } diff --git a/build/vite/plugin/mock.ts b/build/vite/plugin/mock.ts index ee720a468aa4b483a48fac9b4cadcbd20c52760a..90537f130dfe3221d3ef5e71953e60d4a02db51d 100644 --- a/build/vite/plugin/mock.ts +++ b/build/vite/plugin/mock.ts @@ -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; diff --git a/build/vite/plugin/pwa.ts b/build/vite/plugin/pwa.ts index 0748696397c58dfe0d49f21f2c4157b78c85a771..d8e02ed06a1b8b1f1f4f7da1c373c2fa38711e02 100644 --- a/build/vite/plugin/pwa.ts +++ b/build/vite/plugin/pwa.ts @@ -1,8 +1,13 @@ 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; diff --git a/build/vite/proxy.ts b/build/vite/proxy.ts index b64bcb5f2ec9a5bee6e42ecef474f50debddb14c..f01a074684b3c8d627687f57135c575dba4bcee4 100644 --- a/build/vite/proxy.ts +++ b/build/vite/proxy.ts @@ -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 } : {}), }; diff --git a/index.html b/index.html index 515d2521002bf987a28aa0a175795477d455da26..3064328c1923a69b4d164b64cc238adc4009b92c 100644 --- a/index.html +++ b/index.html @@ -137,7 +137,11 @@
- +
diff --git a/package.json b/package.json index 88953b8cc8d324f93b8cda2937da5ffd26178fdc..71d84fadeafc9483d91b5515203465b003d45081 100644 --- a/package.json +++ b/package.json @@ -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 .", diff --git a/src/main.ts b/src/main.ts index 136d2523643068024c95c6b066f579a73e1fc95e..8eb959df1e0b8db7f5b5e492c0b1e8ea72e116b8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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 diff --git a/src/router/index.ts b/src/router/index.ts index 5cf1cda463f609d0a0aa059f454861193b5d0242..8525c3be6253821d3f2cb5870c8bdeda4abffea4 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -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, diff --git a/vite.config.ts b/vite.config.ts index 29e4ae8c14d887840c8d360c1b05a501b613407f..662f42fbad1fed16a2bb85342c11db97c58b4b7d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,8 @@ 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, + }, + }; +};