From 50327ae3394737fa326b869c683bc658184f25b9 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Mon, 22 Jun 2020 15:27:14 +0700 Subject: [PATCH] primate: Add support for UI customisation (#372) - New config.json global config file - Customisation: API endpoint, app name, doc link, logo, error and banner images, theme - Basic external plugin support to allow users to write UI plugins in any framework, build and import/plug a html file as integration Signed-off-by: Rohit Yadav Co-authored-by: Rohit Yadav --- ui/docs/customize.md | 77 +++++++++++++ ui/package-lock.json | 103 ++++++++++++++---- ui/package.json | 1 + ui/{src => public}/assets/403.png | Bin ui/{src => public}/assets/404.png | Bin ui/{src => public}/assets/500.png | Bin ui/{src => public}/assets/banner.svg | 0 ui/{src => public}/assets/error.png | Bin ui/{src => public}/assets/logo.svg | 0 ui/{src => public}/assets/success.png | Bin ui/public/config.json | 47 ++++++++ ui/public/example.html | 12 ++ ui/src/App.vue | 8 +- ui/src/components/header/Logo.vue | 10 +- ui/src/components/header/UserMenu.vue | 8 +- ui/src/components/widgets/Breadcrumb.vue | 6 +- ui/src/config/router.js | 18 ++- ui/src/config/settings.js | 4 - ui/src/core/use.js | 1 + ui/src/layouts/UserLayout.vue | 12 +- ui/src/main.js | 20 ++-- ui/src/permission.js | 4 +- ui/src/style/vars.less | 46 ++++++++ ui/src/utils/domUtil.js | 4 - ui/src/utils/request.js | 2 - ui/src/views/AutogenView.vue | 4 +- ui/src/views/auth/Login.vue | 3 +- ui/src/views/compute/DeployVM.vue | 37 +------ ui/src/views/exception/ExceptionPage.vue | 29 +++-- .../views/image/RegisterOrUploadTemplate.vue | 26 ++--- ui/src/views/plugins/IFramePlugin.vue | 30 +++++ ui/theme.config.js | 50 +++++++++ ui/vue.config.js | 11 +- 33 files changed, 442 insertions(+), 131 deletions(-) create mode 100644 ui/docs/customize.md rename ui/{src => public}/assets/403.png (100%) rename ui/{src => public}/assets/404.png (100%) rename ui/{src => public}/assets/500.png (100%) rename ui/{src => public}/assets/banner.svg (100%) rename ui/{src => public}/assets/error.png (100%) rename ui/{src => public}/assets/logo.svg (100%) rename ui/{src => public}/assets/success.png (100%) create mode 100644 ui/public/config.json create mode 100644 ui/public/example.html create mode 100644 ui/src/style/vars.less create mode 100644 ui/src/views/plugins/IFramePlugin.vue create mode 100644 ui/theme.config.js diff --git a/ui/docs/customize.md b/ui/docs/customize.md new file mode 100644 index 00000000000..09a86a132df --- /dev/null +++ b/ui/docs/customize.md @@ -0,0 +1,77 @@ +# UI customization +Use a `public/config.json` (or `dist/config.json` after build) file for customizing theme, logos,... + +## Images +Change the image of the logo, login banner, error page, etc. +```json +{ + "logo": "assets/logo.svg", + "banner": "assets/banner.svg", + "error": { + "404": "assets/404.png", + "403": "assets/403.png", + "500": "assets/500.png" + } +} +``` + +- `logo` changes the logo top-left side image. +- `banner` changes the login banner image. +- `error.404` change the image of error Page not found. +- `error.403` change the image of error Forbidden. +- `error.500` change the image of error Internal Server Error. + +## Theme +Customize themes like colors, border color, etc. +```json +{ + "theme": { + "@primary-color": "#1890ff", + "@success-color": "#52c41a", + "@processing-color": "#1890ff", + "@warning-color": "#faad14", + "@error-color": "#f5222d", + "@font-size-base": "14px", + "@heading-color": "rgba(0, 0, 0, 0.85)", + "@text-color": "rgba(0, 0, 0, 0.65)", + "@text-color-secondary": "rgba(0, 0, 0, 0.45)", + "@disabled-color": "rgba(0, 0, 0, 0.25)", + "@border-color-base": "#d9d9d9", + "@logo-width": "256px", + "@logo-height": "64px", + "@banner-width": "700px", + "@banner-height": "110px", + "@error-width": "256px", + "@error-height": "256px" + } +} +``` + +- `@primary-color` change the major background color of the page (background button, icon hover, etc). +- `@success-color` change success state color. +- `@processing-color` change processing state color. Exp: progress status. +- `@warning-color` change warning state color. +- `@error-color` change error state color. +- `@heading-color` change table header color. +- `@text-color` change in major text color. +- `@text-color-secondary` change of secondary text color (breadcrumb icon). +- `@disabled-color` change disable state color (disabled button, switch, etc). +- `@border-color-base` change in major border color. +- `@logo-width` change the width of the logo top-left side. +- `@logo-height` change the height of the logo top-left side. +- `@banner-width` changes the width of the login banner. +- `@banner-height` changes the height of the login banner. +- `@error-width` changes the width of the error image. +- `@error-height` changes the height of the error image. + +Assorted primary theme colours: + +- Blue: #1890FF +- Red: #F5222D +- Yellow: #FAAD14 +- Cyan: #13C2C2 +- Green: #52C41A +- Purple: #722ED1 + +Also, to add other properties, we can add new properties into `theme.config.js` based on the Ant Design Vue Less variable. +Refer: https://www.antdv.com/docs/vue/customize-theme/#Ant-Design-Vue-Less-variables diff --git a/ui/package-lock.json b/ui/package-lock.json index 7f356ff1896..98558677d58 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -6767,7 +6767,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -6814,6 +6813,44 @@ "warning": "^4.0.0" } }, + "antd-theme-generator": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/antd-theme-generator/-/antd-theme-generator-1.2.4.tgz", + "integrity": "sha512-27HCj4NTpbQZGNkz1Ip7RF1p85iSN4izf5rY6rQvytM2shvve9qVLnIwHGdNWvsMPrgOPH5wlu8bauKnh7+6dg==", + "requires": { + "glob": "^7.1.3", + "hash.js": "^1.1.5", + "less": "^3.9.0", + "less-plugin-npm-import": "^2.1.0", + "postcss": "^6.0.21", + "strip-css-comments": "^4.1.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "antd-theme-webpack-plugin": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/antd-theme-webpack-plugin/-/antd-theme-webpack-plugin-1.3.6.tgz", + "integrity": "sha512-3cxWiblpZYbkZoghQODjcejQhx0hTu8aSOilWH2nZFtdOoa0ZFXT6u60uzghZiwqFuYqgv0ylMfYGElOmTUdiw==", + "requires": { + "antd-theme-generator": "^1.2.4" + } + }, "any-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", @@ -9547,7 +9584,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -10256,7 +10292,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -10264,8 +10299,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.3", @@ -12400,7 +12434,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -14680,8 +14713,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbol-support-x": { "version": "1.4.2", @@ -14765,7 +14797,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -15253,7 +15284,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "dev": true, "optional": true }, "import-cwd": { @@ -15894,6 +15924,11 @@ "has": "^1.0.3" } }, + "is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==" + }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -17403,7 +17438,6 @@ "version": "3.11.1", "resolved": "https://registry.npmjs.org/less/-/less-3.11.1.tgz", "integrity": "sha512-tlWX341RECuTOvoDIvtFqXsKj072hm3+9ymRBe76/mD6O5ZZecnlAOVDlWAleF2+aohFrxNidXhv2773f6kY7g==", - "dev": true, "requires": { "clone": "^2.1.2", "errno": "^0.1.1", @@ -17420,14 +17454,12 @@ "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "optional": true } } @@ -17457,6 +17489,30 @@ } } }, + "less-plugin-npm-import": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/less-plugin-npm-import/-/less-plugin-npm-import-2.1.0.tgz", + "integrity": "sha1-gj5phskzGKmBccqFiEi2vq1Vvz4=", + "requires": { + "promise": "~7.0.1", + "resolve": "~1.1.6" + }, + "dependencies": { + "promise": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.0.4.tgz", + "integrity": "sha1-Nj6EpMNsg1a4kP7WLJHOhdAu1Tk=", + "requires": { + "asap": "~2.0.3" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -18397,8 +18453,7 @@ "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { "version": "1.40.0", @@ -18480,8 +18535,7 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", @@ -21428,7 +21482,6 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, "optional": true, "requires": { "asap": "~2.0.3" @@ -21477,8 +21530,7 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "ps-list": { "version": "4.1.0", @@ -23989,6 +24041,14 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-css-comments": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/strip-css-comments/-/strip-css-comments-4.1.0.tgz", + "integrity": "sha512-azjRwrqk7nK21LU7QuL7DpDyPjvRROQvqPrNyyz6emdzbOh6fsNTvkSvUiThBLzC6+MN90rFu296VbPb/KV+3A==", + "requires": { + "is-regexp": "^2.1.0" + } + }, "strip-dirs": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", @@ -24097,7 +24157,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } diff --git a/ui/package.json b/ui/package.json index 745e5682b7c..5d55c58b900 100644 --- a/ui/package.json +++ b/ui/package.json @@ -39,6 +39,7 @@ "@fortawesome/free-solid-svg-icons": "^5.13.0", "@fortawesome/vue-fontawesome": "^0.1.9", "ant-design-vue": "~1.6.2", + "antd-theme-webpack-plugin": "^1.3.4", "axios": "^0.19.2", "core-js": "^3.6.5", "enquire.js": "^2.1.6", diff --git a/ui/src/assets/403.png b/ui/public/assets/403.png similarity index 100% rename from ui/src/assets/403.png rename to ui/public/assets/403.png diff --git a/ui/src/assets/404.png b/ui/public/assets/404.png similarity index 100% rename from ui/src/assets/404.png rename to ui/public/assets/404.png diff --git a/ui/src/assets/500.png b/ui/public/assets/500.png similarity index 100% rename from ui/src/assets/500.png rename to ui/public/assets/500.png diff --git a/ui/src/assets/banner.svg b/ui/public/assets/banner.svg similarity index 100% rename from ui/src/assets/banner.svg rename to ui/public/assets/banner.svg diff --git a/ui/src/assets/error.png b/ui/public/assets/error.png similarity index 100% rename from ui/src/assets/error.png rename to ui/public/assets/error.png diff --git a/ui/src/assets/logo.svg b/ui/public/assets/logo.svg similarity index 100% rename from ui/src/assets/logo.svg rename to ui/public/assets/logo.svg diff --git a/ui/src/assets/success.png b/ui/public/assets/success.png similarity index 100% rename from ui/src/assets/success.png rename to ui/public/assets/success.png diff --git a/ui/public/config.json b/ui/public/config.json new file mode 100644 index 00000000000..f36e77c582c --- /dev/null +++ b/ui/public/config.json @@ -0,0 +1,47 @@ +{ + "apiBase": "/client/api", + "docBase": "http://docs.cloudstack.apache.org/en/latest", + "appTitle": "CloudStack", + "logo": "assets/logo.svg", + "banner": "assets/banner.svg", + "error": { + "404": "assets/404.png", + "403": "assets/403.png", + "500": "assets/500.png" + }, + "theme": { + "@primary-color": "#1890ff", + "@processing-color": "#1890ff", + "@success-color": "#52c41a", + "@warning-color": "#faad14", + "@error-color": "#f5222d", + "@font-size-base": "14px", + "@heading-color": "rgba(0, 0, 0, 0.85)", + "@text-color": "rgba(0, 0, 0, 0.65)", + "@text-color-secondary": "rgba(0, 0, 0, 0.45)", + "@disabled-color": "rgba(0, 0, 0, 0.25)", + "@border-color-base": "#d9d9d9", + "@border-radius-base": "4px", + "@box-shadow-base": "0 2px 8px rgba(0, 0, 0, 0.15)", + "@logo-width": "256px", + "@logo-height": "64px", + "@login-banner-width": "700px", + "@login-banner-height": "110px", + "@error-width": "256px", + "@error-height": "256px" + }, + "keyboardOptions": { + "us": "label.standard.us.keyboard", + "uk": "label.uk.keyboard", + "fr": "label.french.azerty.keyboard", + "jp": "label.japanese.keyboard", + "sc": "label.simplified.chinese.keyboard" + }, + "plugins": [ + { + "name": "ExamplePlugin", + "icon": "appstore", + "path": "example.html" + } + ] +} diff --git a/ui/public/example.html b/ui/public/example.html new file mode 100644 index 00000000000..594baf1c108 --- /dev/null +++ b/ui/public/example.html @@ -0,0 +1,12 @@ + + + + + + + Example Plugin + + + This is an example iframe plugin, please configure the config.json to remove this in production environment. + + diff --git a/ui/src/App.vue b/ui/src/App.vue index f21947b868e..fa75a8e635c 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -31,11 +31,13 @@ export default { mixins: [AppDeviceEnquire], data () { return { - locale: enUS + locale: enUS, + configs: {} } }, - mounted () { - + created () { + window.less.modifyVars(this.$config.theme) + console.log('config and theme applied') } } diff --git a/ui/src/components/header/Logo.vue b/ui/src/components/header/Logo.vue index 37e1e9cd07a..ba879e40d7d 100644 --- a/ui/src/components/header/Logo.vue +++ b/ui/src/components/header/Logo.vue @@ -17,7 +17,14 @@ @@ -59,7 +66,6 @@ export default { } .logo-image { - width: 256px; display: inline-block; vertical-align: middle; } diff --git a/ui/src/components/header/UserMenu.vue b/ui/src/components/header/UserMenu.vue index b697f2917ea..b30110afc16 100644 --- a/ui/src/components/header/UserMenu.vue +++ b/ui/src/components/header/UserMenu.vue @@ -33,7 +33,7 @@ - + {{ $t('label.help') }} @@ -51,7 +51,6 @@ diff --git a/ui/theme.config.js b/ui/theme.config.js new file mode 100644 index 00000000000..246267491ab --- /dev/null +++ b/ui/theme.config.js @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +const path = require('path') +const AntDesignThemePlugin = require('antd-theme-webpack-plugin') + +function resolve (dir) { + return path.join(__dirname, dir) +} + +const options = { + stylesDir: resolve('./src/style'), + antDir: resolve('./node_modules/ant-design-vue'), + varFile: resolve('./src/style/vars.less'), + themeVariables: [ + '@primary-color', + '@success-color', + '@warning-color', + '@processing-color', + '@error-color', + '@heading-color', + '@text-color', + '@text-color-secondary', + '@disabled-color', + '@border-color-base', + '@border-radius-base', + '@box-shadow-base' + ], + indexFileName: 'index.html', + publicPath: '.', + generateOnce: false +} + +const createThemeColorReplacerPlugin = () => new AntDesignThemePlugin(options) + +module.exports = createThemeColorReplacerPlugin diff --git a/ui/vue.config.js b/ui/vue.config.js index 4421a0217ee..e92841a54bc 100644 --- a/ui/vue.config.js +++ b/ui/vue.config.js @@ -20,13 +20,14 @@ const webpack = require('webpack') const fs = require('fs') const packageJson = fs.readFileSync('./package.json') const version = JSON.parse(packageJson).version || 'master' +const createThemeColorReplacerPlugin = require('./theme.config') function resolve (dir) { return path.join(__dirname, dir) } // vue.config.js -module.exports = { +const vueConfig = { publicPath: './', /* Vue-cli3: @@ -56,6 +57,7 @@ module.exports = { chainWebpack: (config) => { config.resolve.alias + .set('@public', resolve('public')) .set('@$', resolve('src')) .set('@api', resolve('src/api')) .set('@assets', resolve('src/assets')) @@ -103,11 +105,8 @@ module.exports = { loaderOptions: { less: { modifyVars: { - // Refer: // https://ant.design/docs/spec/colors // https://vue.ant.design/docs/vue/customize-theme/ - 'primary-color': '#1890ff', - 'link-color': '#1890ff' }, javascriptEnabled: true } @@ -149,3 +148,7 @@ module.exports = { } } } + +vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin()) + +module.exports = vueConfig