Merge pull request #412 from Safelite/refactor/digital-components
Additional linting and updates. Mostly digital-components.
This commit is contained in:
commit
2ae350d927
23 changed files with 800 additions and 386 deletions
|
|
@ -4,11 +4,12 @@ module.exports = {
|
|||
jest: true
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 14
|
||||
ecmaVersion: 'latest'
|
||||
},
|
||||
extends: [
|
||||
'eslint-config-airbnb-base',
|
||||
'plugin:vue/vue3-recommended'
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:jsdoc/recommended'
|
||||
],
|
||||
rules: {
|
||||
'linebreak-style': 'off',
|
||||
|
|
@ -38,7 +39,7 @@ module.exports = {
|
|||
svg: 'always',
|
||||
math: 'always'
|
||||
}],
|
||||
'import/extensions': ['error', 'always', { vue: 'never', js: 'ignorePackages' }]
|
||||
'import/extensions': ['error', 'always', { js: 'ignorePackages' }]
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
module.exports = {
|
||||
verbose: true,
|
||||
coverageReporters: ["html", "text", "cobertura"],
|
||||
reporters: ["default", "jest-junit"],
|
||||
testResultsProcessor: "jest-junit",
|
||||
preset: "@vue/cli-plugin-unit-jest",
|
||||
transform: { "^.+\\.vue$": "@vue/vue3-jest" },
|
||||
moduleFileExtensions: ["js", "vue"],
|
||||
moduleNameMapper: {
|
||||
axios: 'axios/dist/browser/axios.cjs'
|
||||
},
|
||||
collectCoverageFrom: [
|
||||
"src/**/*.{js,vue}",
|
||||
"!src/main.js",
|
||||
"!src/constants/*.js",
|
||||
"!src/router/**/*.js",
|
||||
"!src/helpers/unit-test-helper.js"
|
||||
verbose: true,
|
||||
coverageReporters: ['html', 'text', 'cobertura'],
|
||||
reporters: ['default', 'jest-junit'],
|
||||
testResultsProcessor: 'jest-junit',
|
||||
preset: '@vue/cli-plugin-unit-jest',
|
||||
transform: { '^.+\\.vue$': '@vue/vue3-jest' },
|
||||
moduleFileExtensions: ['js', 'vue'],
|
||||
moduleNameMapper: {
|
||||
axios: 'axios/dist/browser/axios.cjs'
|
||||
},
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.{js,vue}',
|
||||
'!src/main.js',
|
||||
'!src/constants/*.js',
|
||||
'!src/router/**/*.js',
|
||||
'!src/helpers/unit-test-helper.js'
|
||||
// END
|
||||
], // ! means exclude from coverage.
|
||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||
coverageThreshold: {
|
||||
// global: {
|
||||
// statements: 80,
|
||||
// },
|
||||
},
|
||||
], // ! means exclude from coverage.
|
||||
testMatch: ['**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'],
|
||||
coverageThreshold: {
|
||||
// global: {
|
||||
// statements: 80,
|
||||
// },
|
||||
}
|
||||
};
|
||||
|
|
|
|||
888
package-lock.json
generated
888
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -32,6 +32,8 @@
|
|||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/user-event": "14.4.3",
|
||||
"@testing-library/vue": "6.6.1",
|
||||
"@vitejs/plugin-vue": "4.2.3",
|
||||
"@vitest/coverage-v8": "^0.34.1",
|
||||
"@vue/cli-plugin-babel": "^5.0.8",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-unit-jest": "~5.0.0",
|
||||
|
|
@ -44,12 +46,15 @@
|
|||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-import-resolver-alias": "1.1.2",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jsdoc": "^46.4.3",
|
||||
"eslint-plugin-vue": "^9.15.1",
|
||||
"jest": "^27.0.5",
|
||||
"jest-junit": "^13.0.0",
|
||||
"jsdoc": "^4.0.2",
|
||||
"jsdom": "^22.1.0",
|
||||
"sass": "^1.32.7",
|
||||
"sass-loader": "^12.0.0",
|
||||
"vite": "^4.4.6",
|
||||
"vitest": "^0.33.0",
|
||||
"volar-service-vetur": "latest"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* @module applicationConfig
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
*/
|
||||
const applicationConfig = {
|
||||
CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod"
|
||||
CONSUMER_CF_DISTRO: process.env.VUE_APP_CONSUMER_CF_DISTRO,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import applicationConfig from '@/constants/application-config.js';
|
||||
|
||||
/**
|
||||
* @module cookieNames
|
||||
* @requires applicationConfig
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
*/
|
||||
const cookieNames = {
|
||||
ISS_SESSION_INFO: `ISSSessionInfo-${applicationConfig.CURRENT_ENVIRONMENT}`,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* @module errorMessages
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
*/
|
||||
const errorMessages = Object.freeze({
|
||||
DAMAGE_LOCATION_REQUIRED: 'Please select damage location',
|
||||
DAMAGE_SIDE_REQUIRED: 'Please select vehicle side',
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
/**
|
||||
* @file global-rules.js
|
||||
* @module globalRules
|
||||
* @summary Contains all the globally defined rules.
|
||||
* @author MB
|
||||
* @copyright Safelite
|
||||
*/
|
||||
|
||||
/**
|
||||
* @summary Contains all the globally defined rules.
|
||||
*/
|
||||
const globalRules = Object.freeze({
|
||||
POLICYHOLDER_FIRST_NAME_REQUIRED: 'policyholder-first-name-required',
|
||||
POLICYHOLDER_LAST_NAME_REQUIRED: 'policyholder-last-name-required',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* @module states
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
*/
|
||||
const states = Object.freeze({
|
||||
AL: 'Alabama',
|
||||
AK: 'Alaska',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
/* eslint-disable max-len */
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question';
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
|
||||
/** @ignore */
|
||||
function setupMocks(mountOptionsMockData = {}) {
|
||||
const defaultMountOptions = { route: { query: { issPage: 'page-name' } } };
|
||||
const baseMountOptions
|
||||
= getMountOptions(Object.assign(defaultMountOptions, mountOptionsMockData));
|
||||
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
|
||||
|
||||
return allMountOptions;
|
||||
}
|
||||
|
||||
describe('buttonQuestion.vue', () => {
|
||||
it('Fieldset classes should contain row if button type is listCard', () => {
|
||||
// Act
|
||||
|
|
@ -1009,12 +1020,3 @@ describe('buttonQuestion.vue', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks(mountOptionsMockData = {}) {
|
||||
const defaultMountOptions = { route: { query: { issPage: 'page-name' } } };
|
||||
const baseMountOptions
|
||||
= getMountOptions(Object.assign(defaultMountOptions, mountOptionsMockData));
|
||||
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
|
||||
|
||||
return allMountOptions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import listButton from '@/ux-components/list-button/list-button';
|
||||
import listButtonHorizontal from '@/ux-components/list-button-horizontal/list-button-horizontal';
|
||||
import listCard from '@/ux-components/list-card/list-card';
|
||||
import radio from '@/ux-components/radio/radio';
|
||||
import listButton from '@/ux-components/list-button/list-button.vue';
|
||||
import listButtonHorizontal from '@/ux-components/list-button-horizontal/list-button-horizontal.vue';
|
||||
import listCard from '@/ux-components/list-card/list-card.vue';
|
||||
import radio from '@/ux-components/radio/radio.vue';
|
||||
import { ErrorMessage } from 'vee-validate';
|
||||
import providerPrefRadio from '@/layouts/provider-preference/provider-pref-radio/provider-pref-radio';
|
||||
import providerPrefRadio from '@/layouts/provider-preference/provider-pref-radio/provider-pref-radio.vue';
|
||||
|
||||
export default {
|
||||
name: 'button-question',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import dropdownQuestion from './dropdown-question';
|
||||
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question.vue';
|
||||
|
||||
// Mock CMS content
|
||||
const questionText = 'Question Text';
|
||||
|
|
|
|||
|
|
@ -111,12 +111,12 @@ export default {
|
|||
const words = this.questionText.toString().split(/[ ]+/);
|
||||
words.forEach((word) => {
|
||||
const position = 1;
|
||||
word = [
|
||||
const newWord = [
|
||||
word.toString().slice(0, position),
|
||||
noBreakChar,
|
||||
word.toString().slice(position)
|
||||
].join('');
|
||||
questionText += `${word} `;
|
||||
questionText += `${newWord} `;
|
||||
});
|
||||
|
||||
questionText = questionText.trimEnd();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
|
|||
import crypto from 'crypto';
|
||||
import { useForm } from 'vee-validate';
|
||||
import { Modal } from 'bootstrap';
|
||||
import modal from './modal';
|
||||
import modal from '@/digital-components/modal/modal.vue';
|
||||
|
||||
jest.mock('vee-validate', () => ({
|
||||
useForm: jest.fn()
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
loaderColor="white"
|
||||
:buttonText="footerButtonText"
|
||||
:class="(isButtonDisabled || isFooterButtonDisabled) && 'form-test-invalid'"
|
||||
@click-event="validateAndEmit" />
|
||||
@clickEvent="validateAndEmit" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import modalButtonMain from '@/ux-components/modal-button-main/modal-button-main';
|
||||
import modalButtonMain from '@/ux-components/modal-button-main/modal-button-main.vue';
|
||||
import { Modal } from 'bootstrap';
|
||||
import { useForm } from 'vee-validate';
|
||||
|
||||
|
|
@ -69,6 +69,7 @@ export default {
|
|||
|
||||
const { meta, validate, resetForm } = useForm();
|
||||
|
||||
// TODO: Correct Duplicate key 'modalId' issue.
|
||||
return {
|
||||
modalId,
|
||||
meta,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,42 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import questionChain from '@/digital-components/question-chain/question-chain';
|
||||
import questionChain from '@/digital-components/question-chain/question-chain.vue';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
/** @ignore */
|
||||
function setupMocks({
|
||||
questionDataProp = [
|
||||
{
|
||||
questionSequence: 1,
|
||||
questionText: 'Does only your center sliding piece need to be replaced?',
|
||||
answers: [
|
||||
{
|
||||
answerResult: 'DB09410',
|
||||
answerText: 'Yes',
|
||||
nextQuestionSequence: null
|
||||
},
|
||||
{
|
||||
answerResult: 'DB10840',
|
||||
answerText: 'No',
|
||||
nextQuestionSequence: null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}) {
|
||||
Element.prototype.scrollIntoView = jest.fn();
|
||||
|
||||
const mountOptions = getMountOptions({});
|
||||
mountOptions.propsData = {
|
||||
questionData: questionDataProp
|
||||
};
|
||||
mountOptions.attachTo = document.body;
|
||||
|
||||
const wrapper = shallowMount(questionChain, mountOptions);
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('Question Chain component', () => {
|
||||
describe('on create...', () => {
|
||||
test('Should populate questions data array', async () => {
|
||||
|
|
@ -205,7 +239,7 @@ describe('Question Chain component', () => {
|
|||
wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.questions[1].answerSelected).toBeUndefined;
|
||||
expect(wrapper.vm.questions[1].answerSelected).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should return false if returnedAnswer is a nextQuestion (not a final answer)', async () => {
|
||||
|
|
@ -279,36 +313,3 @@ describe('Question Chain component', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({
|
||||
questionDataProp = [
|
||||
{
|
||||
questionSequence: 1,
|
||||
questionText: 'Does only your center sliding piece need to be replaced?',
|
||||
answers: [
|
||||
{
|
||||
answerResult: 'DB09410',
|
||||
answerText: 'Yes',
|
||||
nextQuestionSequence: null
|
||||
},
|
||||
{
|
||||
answerResult: 'DB10840',
|
||||
answerText: 'No',
|
||||
nextQuestionSequence: null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}) {
|
||||
Element.prototype.scrollIntoView = jest.fn();
|
||||
|
||||
const mountOptions = getMountOptions({});
|
||||
mountOptions.propsData = {
|
||||
questionData: questionDataProp
|
||||
};
|
||||
mountOptions.attachTo = document.body;
|
||||
|
||||
const wrapper = shallowMount(questionChain, mountOptions);
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question';
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||
import { useValidateForm } from 'vee-validate';
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import TextBlock from './text-block';
|
||||
import TextBlock from '@/digital-components/text-block/text-block.vue';
|
||||
|
||||
const mockCmsContent = {
|
||||
Text: 'Sample text here.'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Components
|
||||
import textareaQuestion from '@/digital-components/textarea-question/textarea-question';
|
||||
import textareaQuestion from '@/digital-components/textarea-question/textarea-question.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
|
|
|||
|
|
@ -105,14 +105,16 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
/**
|
||||
* @summary Returns the number of characters in the textarea field.
|
||||
*/
|
||||
* @summary Returns the number of characters in the textarea field.
|
||||
* @returns {number}
|
||||
*/
|
||||
characterCount() {
|
||||
return this?.modelValue?.length ?? 0;
|
||||
},
|
||||
/**
|
||||
* @summary Returns the CMS text associated with the question.
|
||||
*/
|
||||
* @summary Returns the CMS text associated with the question.
|
||||
* @returns {string} QuestionText from cms data.
|
||||
*/
|
||||
questionText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
|
||||
},
|
||||
|
|
@ -127,8 +129,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
/**
|
||||
* @summary Removes whitespace from the end of pasted content.
|
||||
*/
|
||||
* @summary Removes whitespace from the end of pasted content.
|
||||
* @param {event} evt - Browser event
|
||||
*/
|
||||
trimOnPaste(evt) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import textboxQuestion from './textbox-question';
|
||||
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
||||
|
||||
// Mock CMS content
|
||||
const questionText = 'Question Text';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<template>
|
||||
<div class="textbox-question" :class="(errors && errors.length) || hasError ? 'has-error' : ''">
|
||||
<div
|
||||
class="textbox-question"
|
||||
:class="(errors && errors.length) || hasError ? 'has-error' : ''">
|
||||
<label
|
||||
v-if="displayQuestionText"
|
||||
:for="inputId"
|
||||
|
|
@ -43,7 +45,10 @@
|
|||
@focus="$emit('focus', $event.target.value)"
|
||||
@paste="trimOnPaste"
|
||||
@drop="trimOnPaste" />
|
||||
<button v-if="includeSearchIcon" type="submit" aria-label="Search button" />
|
||||
<button
|
||||
v-if="includeSearchIcon"
|
||||
type="submit"
|
||||
aria-label="Search button" />
|
||||
<button
|
||||
v-if="includeSelectIcon"
|
||||
type="submit"
|
||||
|
|
@ -51,8 +56,12 @@
|
|||
:data-bs-target="'#' + cmsWidgetName"
|
||||
aria-label="Select button" />
|
||||
</div>
|
||||
<div v-show="errorMessage" class="row my-1 form-test-error">
|
||||
<span class="d-inline-flex mt-0" role="alert">{{ errorMessage }}</span>
|
||||
<div
|
||||
v-show="errorMessage"
|
||||
class="row my-1 form-test-error">
|
||||
<span
|
||||
class="d-inline-flex mt-0"
|
||||
role="alert">{{ errorMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -107,12 +116,12 @@ export default {
|
|||
let initialValue;
|
||||
|
||||
switch (typeof modelValue) {
|
||||
case 'number':
|
||||
initialValue = modelValue;
|
||||
break;
|
||||
default:
|
||||
initialValue = modelValue && modelValue.length > 0 ? modelValue : '';
|
||||
break;
|
||||
case 'number':
|
||||
initialValue = modelValue;
|
||||
break;
|
||||
default:
|
||||
initialValue = modelValue && modelValue.length > 0 ? modelValue : '';
|
||||
break;
|
||||
}
|
||||
|
||||
const fieldOptions = {
|
||||
|
|
@ -122,11 +131,9 @@ export default {
|
|||
};
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { errorMessage, handleBlur, handleChange, meta, validate, errors } = useField(
|
||||
props.inputId,
|
||||
const { errorMessage, handleBlur, handleChange, meta, validate, errors } = useField(props.inputId,
|
||||
props.validationRules,
|
||||
fieldOptions
|
||||
);
|
||||
fieldOptions);
|
||||
|
||||
return {
|
||||
errorMessage,
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
process.env.VUE_APP_CONSUMER_CF_DISTRO ="https://digitalapi.dev.safelite.io";
|
||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = "Localhost";
|
||||
process.env.VUE_APP_GOOGLE_PLACES_API_KEY =
|
||||
"AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0";
|
||||
process.env.VUE_APP_CONSUMER_CF_DISTRO = 'https://digitalapi.dev.safelite.io';
|
||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = 'Localhost';
|
||||
process.env.VUE_APP_GOOGLE_PLACES_API_KEY
|
||||
= 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0';
|
||||
|
||||
// GA & GTM
|
||||
// NOTE: Using the old ISS site GTM Cotnainer ID for now, will create a new one soon.
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');";
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = "https://www.googletagmanager.com/ns.html?id=GTM-KKNWZ3>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x";
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY
|
||||
= "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');";
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC
|
||||
= 'https://www.googletagmanager.com/ns.html?id=GTM-KKNWZ3>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x';
|
||||
|
||||
module.exports = {
|
||||
publicPath: "/",
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
// Load Order Matters!!!
|
||||
// Note: only include functions, variables and mixins here
|
||||
additionalData: `
|
||||
publicPath: '/',
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
// Load Order Matters!!!
|
||||
// Note: only include functions, variables and mixins here
|
||||
additionalData: `
|
||||
@import "./node_modules/bootstrap/scss/functions";
|
||||
@import "@/styles/ux-variables.scss";
|
||||
@import "./node_modules/bootstrap/scss/variables";
|
||||
@import "./node_modules/bootstrap/scss/mixins";
|
||||
@import "@/styles/mixins/customMixins";
|
||||
`
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
devtool: 'source-map'
|
||||
}
|
||||
devtool: 'source-map'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue