Explorar el Código

feat/babel-root-plugin (#15)

fix: added webpack dev config

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/babel-root-plugin

feat: implement header

feat: implement reusable button component

chore: add webpack config to git ignore

chore: comment webpack proxy config

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/babel-root-plugin

feat: add color palette

feat: integrate babel-root-plugin

feat: integrate babel-root-plugin

Co-authored-by: Tyler <everdev0923@gmail.com>
Reviewed-on: https://git.bubblev.org/bubblev/bubble-web/pulls/15
pull/17/head
Tyler Chen hace 4 años
committed by jonathan
padre
commit
726df730e5
Se han modificado 12 ficheros con 525 adiciones y 85 borrados
  1. +115
    -0
      package-lock.json
  2. +5
    -2
      package.json
  3. +45
    -0
      src/_components/layout/Header.vue
  4. +1
    -0
      src/_components/layout/index.js
  5. +94
    -0
      src/_components/shared/Button.vue
  6. +1
    -0
      src/_components/shared/index.js
  7. +3
    -0
      src/_scss/_base.scss
  8. +77
    -0
      src/_scss/_variables.scss
  9. +166
    -80
      src/auth/LoginPage.vue
  10. BIN
     
  11. +10
    -0
      webpack.config.dev.js
  12. +8
    -3
      webpack.config.js

+ 115
- 0
package-lock.json Ver fichero

@@ -1782,6 +1782,17 @@
}
}
},
"clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
"dev": true,
"requires": {
"is-plain-object": "^2.0.4",
"kind-of": "^6.0.2",
"shallow-clone": "^3.0.0"
}
},
"collection-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -3029,6 +3040,85 @@
"integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
"dev": true
},
"file-loader": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz",
"integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^2.6.5"
},
"dependencies": {
"ajv": {
"version": "6.12.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ajv-keywords": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz",
"integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"json5": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
}
}
}
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
@@ -6304,6 +6394,15 @@
"safe-buffer": "^5.0.1"
}
},
"shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dev": true,
"requires": {
"kind-of": "^6.0.2"
}
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -8110,6 +8209,16 @@
"uuid": "^3.3.2"
}
},
"webpack-merge": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.0.9.tgz",
"integrity": "sha512-P4teh6O26xIDPugOGX61wPxaeP918QOMjmzhu54zTVcLtOS28ffPWtnv+ilt3wscwBUCL2WNMnh97XkrKqt9Fw==",
"dev": true,
"requires": {
"clone-deep": "^4.0.1",
"wildcard": "^2.0.0"
}
},
"webpack-sources": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
@@ -8157,6 +8266,12 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wildcard": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
"integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
"dev": true
},
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",


+ 5
- 2
package.json Ver fichero

@@ -7,7 +7,8 @@
},
"license": "LicenseRef-LICENSE.md",
"scripts": {
"start": "webpack-dev-server --open"
"start": "webpack-dev-server --open",
"dev": "webpack-dev-server --open --config webpack.config.dev.js"
},
"dependencies": {
"babel-plugin-root-import": "^6.5.0",
@@ -30,6 +31,7 @@
"babel-preset-stage-3": "^6.24.1",
"babel-preset-vue": "^2.0.2",
"copy-webpack-plugin": "^5.1.1",
"file-loader": "^6.0.0",
"css-loader": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"path": "^0.12.7",
@@ -37,6 +39,7 @@
"vue-template-compiler": "^2.6.10",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.8",
"webpack-dev-server": "^3.8.0"
"webpack-dev-server": "^3.8.0",
"webpack-merge": "^5.0.9"
}
}

+ 45
- 0
src/_components/layout/Header.vue Ver fichero

@@ -0,0 +1,45 @@
<template>
<div
class="d-flex justify-content-center align-items-center container header"
>
<img src="/small-BubbleLogo-Horizontal-BlackText.png" height="40" />
<div class="flex-grow-1"></div>
<div class="navbar d-flex justify-content-center align-items-center ">
<router-link to="/help" class="d-flex align-items-center">
<Button link>HELP</Button>
</router-link>
<router-link to="/sign-up" class="d-flex align-items-center">
<Button link>SIGN UP</Button>
</router-link>
<router-link to="/help" class="d-flex align-items-center">
<Button color="default">SIGN IN</Button>
</router-link>
</div>
</div>
</template>

<style lang="scss" scoped>
.header {
background-color: white;

height: 85px;

.navbar {
height: 100%;
}
.navbar a {
height: 100%;
text-decoration: none;
}
}
</style>

<script>
import { Button } from '~/_components/shared';

export default {
components: {
Button,
},
};
</script>

+ 1
- 0
src/_components/layout/index.js Ver fichero

@@ -0,0 +1 @@
export { default as Header } from './Header';

+ 94
- 0
src/_components/shared/Button.vue Ver fichero

@@ -0,0 +1,94 @@
<template>
<button
v-bind="$attrs"
@click="click($event)"
:class="{
round: round,
block: block,
[`color-${color}`]: color,
link: link,
}"
class="app-btn"
>
<span class="btn--text">
<slot></slot>
</span>
</button>
</template>

<style lang="scss" scoped>
@import '../../_scss/_variables';

.app-btn {
font-size: 14px;
box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0);
transition: all 300ms ease 0ms;

max-height: 100%;
height: 60px;
cursor: pointer;
border: none;

// &:hover {
// box-shadow: 0px 5px 5px 0px rgba(0, 0, 0, 0.2);
// }

&.round {
border-radius: 50px;
}

&.block {
display: block;
}

.btn--text {
padding: 5px 20px;
}

&.link {
background-color: transparent;
color: #737373;

.btn--text {
padding: 0 5px;
}
}

// TODP: color schemas
&.color-default {
background: linear-gradient(300deg, #b838c9 -5%, #ee2f8e 95%);
color: white;
}
}
</style>

<script>
export default {
props: {
round: {
type: Boolean,
default: true,
},
block: {
type: Boolean,
default: false,
},
link: {
type: Boolean,
default: false,
},
color: {
type: String,
default: '',
},
},
data() {
return {};
},
methods: {
click(event) {
this.$emit('click', event);
},
},
};
</script>

+ 1
- 0
src/_components/shared/index.js Ver fichero

@@ -0,0 +1 @@
export { default as Button } from './Button';

+ 3
- 0
src/_scss/_base.scss Ver fichero

@@ -0,0 +1,3 @@
html, body {
font-family: 'Luto';
}

+ 77
- 0
src/_scss/_variables.scss Ver fichero

@@ -0,0 +1,77 @@
// color codes

$deep-purple: #3607a6;
$deep-purple-1: #4709d7;
$deep-purple-2: #5814f5;
$deep-purple-3: #6628f6;
$deep-purple-4: #733bf7;
$deep-purple-5: #814ff8;
$deep-purple-6: #8f62f8;
$deep-purple-7: #3a07b0;
$deep-purple-8: #ba9efa;
$deep-purple-9: #d5c5fc;
$deep-purple-10: #e3d8fd;

$vivid-navy: #221fe0;
$vivid-navy-1: #3c3ae4;
$vivid-navy-2: #4e4be7;
$vivid-navy-3: #605de9;
$vivid-navy-4: #716feb;
$vivid-navy-5: #8381ee;
$vivid-navy-6: #9593f0;
$vivid-navy-7: #a7a5f3;
$vivid-navy-8: #bab7f6;
$vivid-navy-9: #cbc9f8;
$vivid-navy-10: #dcdafb;

$strong-purple: #7a11b1;
$strong-purple-1: #8c14cc;
$strong-purple-2: #9916df;
$strong-purple-3: #aa33eb;
$strong-purple-4: #b245ed;
$strong-purple-5: #c16af0;
$strong-purple-6: #c97df2;
$strong-purple-7: #d9a2f6;
$strong-purple-8: #e0b5f8;
$strong-purple-9: #e8c7fa;
$strong-purple-10: #f0d9fc;

$vivid-pink: #f92c8b;
$vivid-pink-1: #f94d9d;
$vivid-pink-2: #f962a8;
$vivid-pink-3: #fa75b3;
$vivid-pink-4: #fb89be;
$vivid-pink-5: #fb9dc9;
$vivid-pink-6: #fcb1d4;
$vivid-pink-7: #fdc4df;
$vivid-pink-8: #fed8e9;
$vivid-pink-9: #feebf4;
$vivid-pink-10: #fdf5f9;

$light-blue: #54c7ea;
$light-blue-1: #6ecfed;
$light-blue-2: #80d5ef;
$light-blue-3: #92dbf2;
$light-blue-4: #a4e1f4;
$light-blue-5: #b6e7f6;
$light-blue-6: #c9edf8;
$light-blue-7: #d7eef8;
$light-blue-8: #dbf3fa;
$light-blue-9: #e4f3f9;
$light-blue-10: #edf9fd;

$bright-cyan: #2ed1a1;
$bright-cyan-1: #47d7ac;
$bright-cyan-2: #58dab3;
$bright-cyan-3: #68debb;
$bright-cyan-4: #79e2c2;
$bright-cyan-5: #8ae5ca;
$bright-cyan-6: #9be9d1;
$bright-cyan-7: #abedd9;
$bright-cyan-8: #bcf1e1;
$bright-cyan-9: #cdf4e8;
$bright-cyan-10: #def8f0;


// fonts
$default-font-family: 'Lato';

+ 166
- 80
src/auth/LoginPage.vue Ver fichero

@@ -1,45 +1,123 @@
<!-- Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ -->
<template>
<div>
<h2>{{messages.form_title_login}}</h2>
<h4 v-if="resetPasswordMessageSent === true" class="alert-success">{{messages.message_resetPassword_sent}}</h4>
<h4 v-if="submitted && errors.has('approvalToken')" class="invalid-feedback d-block">{{ errors.first('approvalToken') }}</h4>
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label for="name">{{messages.field_label_email}}</label>
<input type="text" v-model="name" name="name" class="form-control" :class="{ 'is-invalid': submitted && !name }" />
<div v-show="submitted && !name" class="invalid-feedback">Name is required</div>
<div v-if="submitted && errors.has('account')" class="invalid-feedback d-block">{{ errors.first('account') }}</div>
<div v-if="submitted && errors.has('name')" class="invalid-feedback d-block">{{ errors.first('name') }}</div>
</div>
<div class="form-group">
<label htmlFor="password">{{messages.field_label_password}}</label>
<input type="password" v-model="password" name="password" class="form-control" :class="{ 'is-invalid': submitted && !password }" />
<div v-if="submitted && errors.has('password')" class="invalid-feedback d-block">{{ errors.first('password') }}</div>
</div>
<div v-if="showTotp" class="form-group">
<p>{{messages.message_login_authenticator_auth}}</p>
<label htmlFor="totpToken">{{messages.field_label_totp_code}}</label>
<input v-validate="'required'" v-model="totpToken" name="totpToken" class="form-control"/>
<div v-if="submitted && errors.has('totpToken')" class="invalid-feedback d-block">{{ errors.first('totpToken') }}</div>
</div>
<div v-if="configs && configs.locked === true && (configs.launchLock === null || configs.launchLock)" class="form-group">
<label htmlFor="unlockKey">{{messages.field_label_unlock_key}}</label>
<input type="password" v-model="unlockKey" name="unlockKey" class="form-control" :class="{ 'is-invalid': submitted && !unlockKey }" />
<div v-show="submitted && !unlockKey" class="invalid-feedback">Unlock Key is required</div>
<div v-if="submitted && errors.has('unlockKey')" class="invalid-feedback d-block">{{ errors.first('unlockKey') }}</div>
</div>
<div class="form-group">
<div><small v-html="messages.message_login_agreeToTerms"></small><hr/></div>
<button class="btn btn-primary" :disabled="status.loggingIn">{{messages.button_label_login}}</button>
<img v-show="status.loggingIn" :src="loadingImgSrc" />
<router-link v-if="configs && configs.allowRegistration" to="/register" class="btn btn-link">{{messages.button_label_register}}</router-link>
</div>
<div class="form-group">
<router-link to="/forgotPassword" class="btn btn-link">{{messages.button_label_forgotPassword}}</router-link>
</div>
</form>
</div>
<div>
<h2>{{ messages.form_title_login }}</h2>
<h4 v-if="resetPasswordMessageSent === true" class="alert-success">
{{ messages.message_resetPassword_sent }}
</h4>
<h4
v-if="submitted && errors.has('approvalToken')"
class="invalid-feedback d-block"
>
{{ errors.first('approvalToken') }}
</h4>
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label for="name">{{ messages.field_label_email }}</label>
<input
type="text"
v-model="name"
name="name"
class="form-control"
:class="{ 'is-invalid': submitted && !name }"
/>
<div v-show="submitted && !name" class="invalid-feedback">
Name is required
</div>
<div
v-if="submitted && errors.has('account')"
class="invalid-feedback d-block"
>
{{ errors.first('account') }}
</div>
<div
v-if="submitted && errors.has('name')"
class="invalid-feedback d-block"
>
{{ errors.first('name') }}
</div>
</div>
<div class="form-group">
<label htmlFor="password">{{ messages.field_label_password }}</label>
<input
type="password"
v-model="password"
name="password"
class="form-control"
:class="{ 'is-invalid': submitted && !password }"
/>
<div
v-if="submitted && errors.has('password')"
class="invalid-feedback d-block"
>
{{ errors.first('password') }}
</div>
</div>
<div v-if="showTotp" class="form-group">
<p>{{ messages.message_login_authenticator_auth }}</p>
<label htmlFor="totpToken">{{ messages.field_label_totp_code }}</label>
<input
v-validate="'required'"
v-model="totpToken"
name="totpToken"
class="form-control"
/>
<div
v-if="submitted && errors.has('totpToken')"
class="invalid-feedback d-block"
>
{{ errors.first('totpToken') }}
</div>
</div>
<div
v-if="
configs &&
configs.locked === true &&
(configs.launchLock === null || configs.launchLock)
"
class="form-group"
>
<label htmlFor="unlockKey">{{ messages.field_label_unlock_key }}</label>
<input
type="password"
v-model="unlockKey"
name="unlockKey"
class="form-control"
:class="{ 'is-invalid': submitted && !unlockKey }"
/>
<div v-show="submitted && !unlockKey" class="invalid-feedback">
Unlock Key is required
</div>
<div
v-if="submitted && errors.has('unlockKey')"
class="invalid-feedback d-block"
>
{{ errors.first('unlockKey') }}
</div>
</div>
<div class="form-group">
<div>
<small v-html="messages.message_login_agreeToTerms"></small>
<hr />
</div>
<button class="btn btn-primary" :disabled="status.loggingIn">
{{ messages.button_label_login }}
</button>
<img v-show="status.loggingIn" :src="loadingImgSrc" />
<router-link
v-if="configs && configs.allowRegistration"
to="/register"
class="btn btn-link"
>{{ messages.button_label_register }}</router-link
>
</div>
<div class="form-group">
<router-link to="/forgotPassword" class="btn btn-link">{{
messages.button_label_forgotPassword
}}</router-link>
</div>
</form>
</div>
</template>

<script>
@@ -47,47 +125,55 @@ import { mapState, mapActions } from 'vuex';
import { loadingImgSrc } from '~/_store';

export default {
data () {
return {
name: '',
password: '',
totpToken: null,
unlockKey: (this.$route.query && this.$route.query.k) ? this.$route.query.k : null,
showTotp: false,
submitted: false,
loadingImgSrc: loadingImgSrc
}
data() {
return {
name: '',
password: '',
totpToken: null,
unlockKey:
this.$route.query && this.$route.query.k ? this.$route.query.k : null,
showTotp: false,
submitted: false,
loadingImgSrc: loadingImgSrc,
};
},
created() {
this.loadSystemConfigs();
},
computed: {
...mapState('account', [
'status',
'loginError',
'resetPasswordMessageSent',
]),
...mapState('system', ['configs', 'messages']),
},
methods: {
...mapActions('account', ['login', 'logout']),
...mapActions('system', ['loadSystemConfigs']),
handleSubmit(e) {
this.errors.clear();
this.submitted = true;
const { name, password, totpToken, unlockKey } = this;
if (name && password) {
this.login({
user: { name, password, totpToken, unlockKey },
systemConfigs: this.configs,
messages: this.messages,
errors: this.errors,
});
}
},
created () {
this.loadSystemConfigs();
},
watch: {
loginError(e) {
if (
(e && e === 'err_totpToken_required') ||
e === 'err_totpToken_invalid'
) {
this.showTotp = true;
}
},
computed: {
...mapState('account', ['status', 'loginError', 'resetPasswordMessageSent']),
...mapState('system', ['configs', 'messages'])
},
methods: {
...mapActions('account', ['login', 'logout']),
...mapActions('system', ['loadSystemConfigs']),
handleSubmit (e) {
this.errors.clear();
this.submitted = true;
const { name, password, totpToken, unlockKey } = this;
if (name && password) {
this.login({
user: {name, password, totpToken, unlockKey},
systemConfigs: this.configs,
messages: this.messages,
errors: this.errors
});
}
}
},
watch: {
loginError (e) {
if (e && e === 'err_totpToken_required' || e === 'err_totpToken_invalid') {
this.showTotp = true;
}
}
}
},
};
</script>


+ 10
- 0
webpack.config.dev.js Ver fichero

@@ -0,0 +1,10 @@
const webpackMerge = require('webpack-merge');

module.exports = webpackMerge.merge(require('./webpack.config.js'), {
mode: 'development',
devServer: {
proxy: {
'/api': 'http://beta.bubv.net:8888',
},
},
});

+ 8
- 3
webpack.config.js Ver fichero

@@ -34,6 +34,14 @@ module.exports = {
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
plugins: [
@@ -44,9 +52,6 @@ module.exports = {
],
devServer: {
historyApiFallback: true,
// proxy: {
// '/api': 'http://beta.bubv.net:8888'
// }
},
externals: {
// global app config object


Cargando…
Cancelar
Guardar