getComputedStyle(...) does NOT return pixel values in jsdom in Svelte - testing

I am using jest and testing-library/svelte to write tests in SvelteKit. I have a simple text-component and want to test, if the line-height of the text is big enough depending on the font-size (because of accessibility reasons). For this, I want to use the window.getComputedStyle(...) method. However, if I am using it in a test, the font-size is NOT returned in pixel, but the unit I used in the actual css.
Text.svelte:
<div class="text">
<slot></slot>
</div>
<style>
.text {
text-align: left;
font-size: 1.2em;
line-height: 2.4em;
}
</style>
Text.spec.ts
/**
* #jest-environment jsdom
*/
import '#testing-library/jest-dom';
import { render } from "#testing-library/svelte";
import Text from "./Text.svelte";
describe("Text component", () => {
test("text must have a minimum line-height of 1.5x the font-size", () => {
const { container } = render(Text);
const textDiv = container.querySelector(".text");
const fontSize = window.getComputedStyle(textDiv).getPropertyValue('font-size')
const lineHeight = window.getComputedStyle(textDiv).getPropertyValue('line-height')
console.log("fontSize:", fontSize) // Output --> font-size: 1.2em
console.log("lineHeight:", lineHeight) // Output --> line-height: 2.4em
});
});
jest.config.cjs
module.exports = {
transform: {
"^.+\\.svelte$": [
"svelte-jester",
{ preprocess: "./svelte.config.js" },
],
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "ts-jest",
},
moduleFileExtensions: ["js", "ts", "svelte"],
moduleNameMapper: {
"^\\$lib(.*)$": "<rootDir>/src/lib$1",
"^\\$app(.*)$": [
"<rootDir>/.svelte-kit/dev/runtime/app$1",
"<rootDir>/.svelte-kit/build/runtime/app$1",
],
},
setupFilesAfterEnv: ["<rootDir>/jest-setup.ts"],
collectCoverageFrom: ["src/**/*.{ts,tsx,svelte,js,jsx}"],
};
jest-setup.ts
import "#testing-library/jest-dom";
Just in case, here are the relevant dependencies from my package.json
{
"devDependencies": {
"#testing-library/jest-dom": "^5.16.3",
"#testing-library/svelte": "^3.1.0",
"#types/jest": "^27.4.1",
"jest": "^27.5.1",
"svelte": "^3.46.6",
"svelte-check": "^2.2.6",
"svelte-jester": "^2.3.2",
"svelte-loader": "^3.1.2",
"svelte-preprocess": "^4.10.1",
"svelte2tsx": "^0.5.6",
"ts-jest": "^27.1.4",
"tslib": "^2.3.1",
"typescript": "~4.6.2"
},
"type": "module"
}
So how can I get the font-size and line-height in pixels. Is this even possible in a jest-test? I'd appreciate every answer, ideas or suggestions!

Related

Sass global variables and mixins not working

I've set up a project using Vue 3.2.33 and Vite 2.9.5
When I try to access any global variable or mixin from within any vue component, I get an undefined error. This problem doesn't occur in scss files.
The import itself seems working correctly because any css rules in it are working.
vite.config.ts:
import { fileURLToPath, URL } from 'url';
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: '#use "#/styles/variables";',
},
},
},
});
src/styles/_variables.scss:
// breakpoints
$breakpoints: (
"sm": 576px,
"md": 768px,
"lg": 992px,
"xl": 1200px,
"xxl": 1400px,
);
#mixin test {
border: 3px solid red;
}
Example use:
<style scoped lang="scss">
#use 'sass:map';
.container {
max-width: 100%;
width: 100%;
margin: 0 auto;
#include test; // <- undefined
&--fluid {
max-width: 100%;
width: 100%;
}
}
$widths: (
'sm': 540px,
'md': 720px,
'lg': 960px,
'xl': 1140px,
'xxl': 1320px,
);
#each $breakpoint, $width in $widths {
#media (min-width: map.get($breakpoints, $breakpoint)) { // <- $breakpoints undefined
.container {
max-width: $width;
}
}
}
</style>
use
#import
in your vite config instead of
#use
vite.config.ts:
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: '#import "./src/styles/variables.scss";',
},
},
},
});
keep in mind that you cannot import the same file variables.scss again in your main.ts file otherwise, you will get this error
[sass] This file is already being loaded.
by the way, you can also import the scss file in every single component manually as you mentioned but that would be really tedious so using a global import in preprocessorOptions in vite.config.ts is a much better option for files used globally like a variables.scss file.
I've managed to "fix" the issue. Turns out, when I replace all #use rules for file imports, the sass code is imported correctly and works. But this produces a new problem as the #import rules cannot be placed before #use, so I had to remove the additionalData key from config and include the imports manually.

Why am I getting just a blank white page when I tried to migrate from using vue CLI to vite

I am unsure what is going wrong here. I followed the steps on switching from vue-cli to vite and it seems I have missed some steps because my website is not being displayed. I have checked several different repositories and I don't know how my code is any different than theirs who have working websites using vite. I am just going to post a few of my files that hopefully should make the issue I have obvious. If the answer is not obvious from the code I have posted I can go back to my codebase, troubleshoot again and if that fails then display more info in this question.
Edit:: I forgot to mention that the one error I get in the developer console for chrome is
"Failed to load resource: the server responded with a status of 404 (Not Found)" for Footer:1. I am unsure why this error is occuring.
Any feedback will be appreciated.
src/app.vue:
<template>
<router-view />
<Footer />
</template>
<script>
//import Navbar from "#/components/Navbar";
import Footer from "#/components/Footer";
export default {
name: "App",
components: {
//Navbar,
Footer
},
data: () => ({
}),
};
</script>
<style>
#app {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: black;
display: flex;
flex-direction: column;
height: 100%;
}
body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
margin: 0px ;
}
.centre-body{
flex: 1 0 auto;
}
</style>
src/main.vue
import { createApp } from 'vue'
import App from "./App.vue";
import router from "./router/index";
import store from "./store/index";
Vue.config.productionTip = false;
createApp(App).use(router).use(store).mount('#app')
vite.config.js
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
const path = require("path");
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"#": path.resolve(__dirname, "./src"),
},
},
});
package.json
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
},
"dependencies": {
"#vitejs/plugin-vue": "^1.6.1",
"#vue-leaflet/vue-leaflet": "^0.6.0",
"axios": "^0.21.1",
"global": "^4.4.0",
"highcharts": "^9.0.1",
"loading-visualization": "^1.2.14",
"mapbox-gl": "^1.0.0",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vue3-echarts": "^1.0.3",
"vue3-highcharts": "^0.1.3",
"vueperslides": "^3.2.0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"#vue/compiler-sfc": "^3.0.0",
"#vue/eslint-config-prettier": "^6.0.0",
"eslint": "^8.10.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^8.5.0",
"prettier": "^1.19.1",
"sass": "^1.26.5",
"vite": "^2.8.6",
"vue-loader-v16": "^16.0.0-beta.5.4"
}
}
src/router/index.js
import { createRouter, createWebHashHistory } from "vue-router"
import Home from "../views/Home.vue"
import Information from "../views/Information.vue"
import Contact from "../views/Contact.vue"
import ExploreScience from "../views/ExploreScience.vue"
import ProjectData from "../views/ProjectData.vue"
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/Information",
name: "Information",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: Information
},
{
path: "/Contact",
name: "Contact",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: Contact
},
{
path: "/ProjectData",
name: "ProjectData",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ProjectData
},
{
path: "/exploreScience",
name: "ExploreScience",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ExploreScience
},
];
const router = createRouter({
mode: "history",
base: import.meta.env.BASE_URL,
routes,
});
export default router
The error message seems to point here:
import Footer from "#/components/Footer";
Notice the file extension is missing. That worked in a Vue CLI scaffolded project because it was possible to configure default file extensions.
In Vite, the file extension is required in the path for the import to succeed:
import Footer from "#/components/Footer.vue";
👆

Could not find a declaration file for module 'prismjs/components/prism-core' vue-prism-editor

I am just trying to use this package (vue-prism-editor) in my vuejs 3 application, but I am always getting an error as preceding.
TS7016: Could not find a declaration file for module 'prismjs/components/prism-core'. 'C:/Sibeesh/GitHub/vue-resume/node_modules/prismjs/components/prism-core.js' implicitly has an 'any' type.
Try `npm i --save-dev #types/prismjs` if it exists or add a new declaration (.d.ts) file containing `declare module 'prismjs/components/prism-core';`
I did install #types/prismjs but no luck there. I followed the steps mentioned in the readme and trying exactly the same.
Below is my package.json file.
{
"name": "vue-resume",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"jsoneditor": "^9.2.0",
"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0",
"vue-prism-editor": "^2.0.0-alpha.2",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"#types/prismjs": "^1.16.3",
"#typescript-eslint/eslint-plugin": "^4.18.0",
"#typescript-eslint/parser": "^4.18.0",
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-plugin-router": "~4.5.0",
"#vue/cli-plugin-typescript": "~4.5.0",
"#vue/cli-plugin-vuex": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.0",
"#vue/eslint-config-prettier": "^6.0.0",
"#vue/eslint-config-typescript": "^7.0.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.0.0",
"prettier": "^2.2.1",
"prismjs": "^1.23.0",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"typescript": "~4.1.5"
}
}
Here is my vue component.
<template>
<div class="hello">
<prism-editor
class="code-editor"
v-model="code"
:highlight="highlighter"
line-numbers
></prism-editor>
</div>
</template>
<script lang="ts">
// import Prism Editor
import { PrismEditor } from 'vue-prism-editor';
import 'vue-prism-editor/dist/prismeditor.min.css'; // import the styles somewhere
// import highlighting library (you can use any library you want just return html string)
import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/components/prism-javascript';
export default {
components: {
PrismEditor,
},
data: () => ({ code: 'console.log("Hello World")' }),
methods: {
highlighter(code: string) {
return highlight(code, languages.js); // languages.<insert language> to return html with markup
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
/* required class */
.code-editor {
/* we dont use `language-` classes anymore so thats why we need to add background and text color manually */
background: #2d2d2d;
color: #ccc;
/* you must provide font-family font-size line-height. Example: */
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-size: 14px;
line-height: 1.5;
padding: 5px;
}
/* optional class for removing the outline */
.prism-editor__textarea:focus {
outline: none;
}
</style>
Have you ever been able to use this plugin in vue 3 application?
I try some ways with typescript, found that this is the easiest way
first
yarn add #types/prismjs
then
import { highlight, languages, highlightElement } from 'prismjs';
After spending some time on this issue, I could find out what mistake I am doing. Did you notice the lang="ts" in my script? Well, that is the root cause of this issue. After removing that from <script>, the error was gone. This issue in GitHub helped me find the solution for this. One drawback of this approach is that we no longer be able to use the Type annotations as this will be supported only with TypeScript files.
The other mistake was that I was not including the reference to import 'prismjs/components/prism-clike';. We will get the preceding error if we don't include that file.
Uncaught TypeError: Cannot read property 'class-name' of undefined
at eval (prism-javascript.js?416b:3)
The other approach:
As mentioned in the error, you can also create a .d.ts file and add the declare module 'prismjs/components/prism-core'. I created this file inside my components directory.
And then you can rewrite your script in the preceding way.
<script lang="ts">
import { PrismEditor } from "vue-prism-editor";
import { highlight, languages } from "prismjs/components/prism-core";
import "vue-prism-editor/dist/prismeditor.min.css";
import "prismjs/components/prism-clike";
import "prismjs/components/prism-json";
import "prismjs/themes/prism-tomorrow.css";
import sampleData from "../assets/resume-template.json";
import { Options, Vue } from "vue-class-component";
#Options({
components: {
PrismEditor,
},
data: () => ({
code: JSON.stringify(sampleData),
}),
methods: {
submit() {
console.log(this.code);
},
highlighter(code: string) {
return highlight(code, languages.json);
},
},
})
export default class CodeEditor extends Vue {}
</script>
Just sharing as it might be helpful to someone else.
If anyone is struggling with this too, heres my solution:
PrismEditor.vue
<template>
<prism-editor
class="my-editor"
v-model="code"
:highlight="highlighter"
line-numbers
readonly
></prism-editor>
</template>
<script>
import { PrismEditor } from "vue-prism-editor";
import "vue-prism-editor/dist/prismeditor.min.css";
import { highlight, languages } from "prismjs/components/prism-core";
import "prismjs/components/prism-clike";
import "prismjs/components/prism-javascript";
import "prismjs/themes/prism-tomorrow.css";
export default {
components: {
PrismEditor,
},
props: {
code: {
type: String,
default: "console.log('default value')",
},
lang: {
type: String,
default: "js",
},
},
methods: {
highlighter() {
return highlight(this.code, languages[this.lang]);
},
},
};
</script>
<style>
/* required class */
.my-editor {
/* we dont use `language-` classes anymore so thats why we need to add background and text color manually */
background: #2d2d2d;
color: #ccc;
/* you must provide font-family font-size line-height. Example: */
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-size: 14px;
line-height: 1.5;
padding: 5px;
}
/* optional class for removing the outline */
.prism-editor__textarea:focus {
outline: none;
}
</style>
CodeBlock.vue
<template>
<prism-editor :code="code" :lang="lang"></prism-editor>
</template>
<script setup lang="ts">
import { ref } from "vue";
import PrismEditor from "../components/PrismEditor.vue";
const code = ref("console.log(It's working)");
const lang = ref("js");
</script>
<style></style>

How do I only import Navbar, Dropdown and Modal from buefy in Nuxt?

I am trying to import only the Navbar, Modal and Dropdown from Buefy and running into errors trying to do the same
I also want only the relevant scss files
I have tried multiple methods so far and nothing works
Method 1
npx create-nuxt-app custombuefy
Do not select any frontend framework here
Step 1 Install Bulma
npm i node-sass sass-loader -D
npm i bulma
Create app.scss inside styles folder inside assets directory
#import "~bulma" inside app.scss
Include '~/assets/styles/app,scss' inside css section of nuxt.config.js
npm run build && npm run start, Check if page with Bulma runs on localhost:3000
Runs successfully at this stage
Step 2 Install Normal Buefy without nuxt-buefy
npm i buefy
Create buefy.js file inside plugins directory
Add '~/plugins/buefy.js' to plugins section of nuxt.config.js
Add the following code to import BDropdown, BModal, BNavbar from buefy
Included the CSS directly here initially
import Vue from 'vue'
import { BDropdown, BDropdownItem, BModal, BNavbar } from 'buefy'
import 'buefy/dist/buefy.min.css'
Vue.use(BDropdownItem)
Vue.use(BDropdown)
Vue.use(BModal)
Vue.use(BNavbar)
Add the dropdown to the code in index.
pages/index.vue file
<template>
<div class="container">
<div>
<logo />
<b-dropdown aria-role="list">
<button
slot="trigger"
slot-scope="{ active }"
class="button is-primary"
>
<span>Click me!</span>
<b-icon :icon="active ? 'menu-up' : 'menu-down'"></b-icon>
</button>
<b-dropdown-item aria-role="listitem">Action</b-dropdown-item>
<b-dropdown-item aria-role="listitem">Another action</b-dropdown-item>
<b-dropdown-item aria-role="listitem">Something else</b-dropdown-item>
</b-dropdown>
</div>
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo,
},
}
</script>
<style>
.container {
margin: 0 auto;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
.links {
padding-top: 15px;
}
</style>
nuxt.config.js
module.exports = {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{
hid: 'description',
name: 'description',
content: process.env.npm_package_description || '',
},
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: ['~/assets/styles/app.scss'],
/*
** Plugins to load before mounting the App
*/
plugins: ['~/plugins/buefy'],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'#nuxtjs/eslint-module',
// Doc: https://github.com/nuxt-community/stylelint-module
'#nuxtjs/stylelint-module',
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
'#nuxtjs/pwa',
// Doc: https://github.com/nuxt-community/dotenv-module
'#nuxtjs/dotenv',
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {},
},
}
Result
ERROR Cannot read property 'install' of undefined 16:19:41
at Function.t.use (node_modules/vue/dist/vue.runtime.common.prod.js:6:36869)
at Module.<anonymous> (server.js:1:559776)
at r (server.js:1:194)
at Object.<anonymous> (server.js:1:5233)
at r (server.js:1:194)
at server.js:1:1259
at Object.<anonymous> (server.js:1:1269)
at o (node_modules/vue-server-renderer/build.prod.js:1:77607)
at node_modules/vue-server-renderer/build.prod.js:1:78200
at new Promise (<anonymous>)
Method 2
Lets modify the plugins/buefy.js file to instead use dist/esm modules
import Vue from 'vue'
import { BDropdown, BDropdownItem } from 'buefy/dist/esm/dropdown'
import 'buefy/dist/buefy.min.css'
Vue.use(BDropdownItem)
Vue.use(BDropdown)
Result
ERROR Cannot use import statement outside a module 16:23:03
(function (exports, require, module, __filename, __dirname) { import './chunk-6ea13200.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at new Script (vm.js:88:7)
at createScript (vm.js:263:10)
at Object.runInThisContext (vm.js:311:10)
at wrapSafe (internal/modules/cjs/loader.js:1059:15)
at Module._compile (internal/modules/cjs/loader.js:1122:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Module.require (internal/modules/cjs/loader.js:1044:19)
at require (internal/modules/cjs/helpers.js:77:18)
Method 3
Lets use the components from the components directory instead. We again modify plugins/buefy.js file as follows
import Vue from 'vue'
import { BDropdown, BDropdownItem } from 'buefy/dist/components/dropdown'
import 'buefy/dist/buefy.min.css'
Vue.use(BDropdownItem)
Vue.use(BDropdown)
Result
Now I get a new error saying Unknown custom element in Browser console and the dropdown appears completely broken
In case this is a dependency issue, here is my package.json file
{
"name": "custombuefy",
"version": "1.0.0",
"description": "My marvelous Nuxt.js project",
"author": "",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"test": "jest"
},
"lint-staged": {
"*.{js,vue}": "npm run lint",
"*.{css,vue}": "stylelint"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"dependencies": {
"#nuxtjs/axios": "^5.9.7",
"#nuxtjs/dotenv": "^1.4.1",
"#nuxtjs/pwa": "^3.0.0-beta.20",
"buefy": "^0.8.15",
"bulma": "^0.8.2",
"cross-env": "^7.0.2",
"express": "^4.17.1",
"nuxt": "^2.12.2"
},
"devDependencies": {
"#nuxtjs/eslint-config": "^2.0.2",
"#nuxtjs/eslint-module": "^1.1.0",
"#nuxtjs/stylelint-module": "^3.2.2",
"#vue/test-utils": "^1.0.0-beta.33",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.3.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-nuxt": ">=0.5.2",
"eslint-plugin-prettier": "^3.1.3",
"husky": "^4.2.5",
"jest": "^25.3.0",
"lint-staged": "^10.1.5",
"node-sass": "^4.13.1",
"nodemon": "^2.0.3",
"prettier": "^2.0.4",
"sass-loader": "^8.0.2",
"stylelint": "^13.3.2",
"vue-jest": "^4.0.0-0"
}
}
Can someone please tell me how I can import only the Dropdown, Navbar and Modal from Buefy without running into all these errors?
import Vue from 'vue'
import { Dropdown, Icon } from 'buefy'
Vue.use(Dropdown)
Vue.use(Icon)
Fixed the issue but component wise scss is still not working
With app.scss as
#import "~bulma";
#import "~buefy/src/scss/buefy";
Buefy styles are not getting applied to the dropdown
UPDATE
Even SCSS can be imported partially
#import "~buefy/src/scss/utils/_all";
#import "~buefy/src/scss/components/_autocomplete";
#import "~buefy/src/scss/components/_dropdown";
#import "~buefy/src/scss/components/_notices";

Need help on Store and retrieve data using react js, node js, MySQL and webpack

The following is the react code used to create UI. I added the code to store the data to MySQL. This part is not working.
ContactUsClass.js
import React from 'react';
require('./styles.css');
//my SQL code (not working) - start
require('node-mysql');
var mysql = require('mysql');
//my SQL part - end
class ContactUsClass extends React.Component
{
constructor(props)
{
super(props);
this.state = {
text: {
n: '',
m: '',
p: '',
msg:''
}
};
this.handleSubmit = this
.handleSubmit
.bind(this);
}
handleChange(pty, event)
{
const text = this.state.text;
text[pty] = event.target.value;
this.setState({text: text});
}
handleSubmit(event)
{
alert('Text field value is: ' + this.state.text.e + '\nExtra:' + this.state.text.c + '\nTA:' + this.state.text.msg);
//mysql code (not working) - start
var connection = mysql.createConnection({host: '127.0.0.2', user: 'root', password: 'admin', database: 'dbcontactus'});
connection.connect(function (err) {
if (!err) {
alert("Database is connected ... ");
} else {
alert("Error connecting database ... ", err);
}
});
var user = {
'clientname': 'CH Yamini Sankar',
'email': 'mail#mail.com',
'phonenumber': '9999454551',
'message': 'hello world'
};
connection.query('Insert into tbcontactus SET ?', user, function (err, res) {
connection.end();
if (!err)
alert('The solution is: ', res);
else
alert('Error while performing Query.', err);
}
);
//mysql code (not working) - end
}
render()
{
return (
<div className="mainbox">
<div className="heading">
Contact Us</div>
<div><br/></div>
<div>
<input
className="tbox"
type="text"
placeholder="Name"
value={this.state.text.e}
onChange={this
.handleChange
.bind(this, 'e')}/>
<input
className="tbox"
type="text"
placeholder="E-mail ID"
value={this.state.text.c}
onChange={this
.handleChange
.bind(this, 'c')}/>
</div>
<div>
<input
className="tpbox"
type="text"
placeholder="Mobile/Phone no: +1"
value={this.state.text.p}
onChange={this
.handleChange
.bind(this, 'p')}/>
</div>
<div>
<textarea
className="mbox"
type="text"
placeholder="Message"
value={this.state.text.msg}
onChange={this
.handleChange
.bind(this, 'msg')}/>
</div>
<div>
<button className="btn" onClick={this.handleSubmit}>Submit</button>
</div>
</div>
);
}
}
export default ContactUsClass;
ContactUsMain.js
import React from 'react';
import ReactDOM from 'react-dom';
import ContactUsClass from './ContactUsClass.js';
ReactDOM.render(
<ContactUsClass/>, document.getElementById('container'));
ContactUs.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Contact Us</title>
</head>
<body>
<div id="container"></div>
<script src="BundleContactUs.js"></script>
</body>
</html>
webpack.config.js
var config = {
entry: './ContactUsMain.js',
output: {
path: './',
filename: 'BundleContactUs.js'
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['latest', 'react']
}
}, {
test: /\.css?$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader'
}
]
},
node: {
net: 'empty',
tls: 'empty',
dns: 'empty',
fs: 'empty'
}
}
module.exports = config;
package.json
{
"name": "hrportal",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --hot",
"test": "node ContactUsConn.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-preset-latest": "^6.16.0",
"babel-preset-react": "^6.16.0",
"css-loader": "^0.26.0",
"mysql": "github:mysqljs/mysql",
"node-mysql": "^0.4.2",
"popup": "0.0.3",
"react": "^15.4.0",
"react-dom": "^15.4.0",
"style-loader": "^0.13.1",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.16.2"
}
}
The following is the styles.css
.mainbox {
width: 40%;
margin: 0 auto;
height: 500px;
background-color: white;
}
.lbox {
width: 50px;
float: left;
height: 100px;
background-color: maroon;
}
.rbox {
width: 50px;
float: right;
height: 100px;
background-color: maroon;
}
.heading {
width: 25%;
padding: 15px;
border-bottom-style: solid;
border-radius: 5px;
border-bottom-color: gray;
margin: 0 auto;
font-size: 24px;
font-weight: 500;
font-family: 'Roboto', sans-serif;
text-align: center;
color: gray;
}
.tbox {
width: 48%;
height: 35px;
padding: 4px;
margin: 1%;
margin-bottom: 10px;
box-sizing: border-box;
}
.tpbox {
width: 98%;
height: 35px;
padding: 4px;
margin: 1%;
margin-bottom: 10px;
box-sizing: border-box;
}
.mbox {
width: 98%;
padding: 4px;
height: 125px;
margin: 1%;
margin-bottom: 10px;
box-sizing: border-box;
}
.btn {
width: 100px;
height: 35px;
padding: 4px;
margin: 0 auto;
}
body {
background-color: #F0EDED;
}
Using the above five files I want to store the data from the web page to the database and vice-versa.
You are attempting to directly access the MySQL database through client side code, but that should be done on your server. For more information on this, see this question/answer
What you should be doing on the client side is submitting the data through an ajax call. Then, on your server you should parse the request and insert the data into your database.
Example
In your ContactUs component, you would submit the data to your server. The example below uses the Fetch API.
ContactUs.jsx
class ContactUs extends React.Component {
handleSubmit(event) {
var user = {
'clientname': 'CH Yamini Sankar',
'email': 'mail#mail.com',
'phonenumber': '9490430491',
'message': 'hello world'
};
fetch('/api/contact-us', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
}
render() {
// ...
}
}
The language of the server is up to you, but since we're discussing JavaScript, I'll show a node server that uses express.
server.js
app.use(express.bodyParser());
app.post('/api/contact-us', (req, res) => {
// connect to your MySQL database and insert the data
})