I made a simple website using Vue and Element UI. I used Laravel Mix to compile my code.
During development, the icons are showing up but when I run "npm run prod" and upload it to Github Pages they wont show up.
This is my webpack.mix.js
let mix = require('laravel-mix');
mix.js('src/js/app.js', 'public/')
.sass('src/styles/app.scss', 'public/')
.babelConfig({})
.disableNotifications();
I am using on demand components and followed this doc so my root vue file looks like this:
import Vue from 'vue'
import store from './vuex'
import router from './vue-router'
import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import lang from 'element-ui/lib/locale/lang/es'
import locale from 'element-ui/lib/locale'
locale.use(lang)
Vue.use(Loading.directive);
Vue.component(Select.name, Select)
Vue.component(Option.name, Option)
Vue.component(Input.name, Input)
Vue.component(Icon.name, Icon)
new Vue({
el: '#app',
router,
store,
});
Following the same doc, I added a .babelrc file on my root directory but I didn't managed to get it working with the preset es2015 so I used #babel/preset-env instead. I dont actually know how to properly use Babel so the whole error might be over here but idk.
{
"presets": [["#babel/preset-env", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
I noticed something weird, when I run npm run prod, the output shows something like this:
The fonts folder and the needed fonts are being copied to my root directory, so when its on Github it makes a request to the root domain, the root folder, the right url should be over (I guess?) /h3lltronik.github.io/my-site/ but it is on /h3lltronik.github.io/.
Just in case is needed, Im using the icons like this:
<el-input v-model="search" prefix-icon="el-icon-search" class="filter_input element-input bordered" #input="onChangeSearch"
placeholder="Search for a country..."></el-input>
And this is my index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H3lltronik</title>
<link rel="stylesheet" href="./public/app.css">
</head>
<body>
<div id="app" :class="modeClass">
<transition name="el-fade-in">
<router-view class="content-body"></router-view>
</transition>
</div>
<script src="./public/app.js"></script>
</body>
</html>
Related
I have two vue apps that are developed independently of each other.
User UI
Admin UI
Both have own routes, store, configs, etc.
I found this comment https://forum.vuejs.org/t/composing-multiple-apps-as-a-single-spa/12622/16 which handles each app as a component inside a main app.
I tried and it and got it working till i tried it with my "real" apps.
They fail miserably because they cant resolve paths and missing stuff like the routing.
Main: App.vue
<script>
export default {
name: "MainApp",
data() {
return {
app: "user",
};
},
methods: {
changeApp(name) {
console.log("Change app called", name);
this.app = name;
},
},
};
</script>
<template>
<div>
<UserApp v-if="app === 'user'" #changeApp="changeApp"></UserApp>
<AdminApp v-else-if="app === 'admin'" #changeApp="changeApp"></AdminApp>
<div v-else>Default App ({{ app }})</div>
</div>
</template>
Main: main.js
import { createApp } from "vue";
import Main from "./App.vue";
import UserApp from '../apps/user/src/App.vue';
import AdminApp from '../apps/admin/src/App.vue';
const main = createApp(Main);
main.component("UserApp", UserApp);
main.component("AdminApp", AdminApp);
main.mount("#main");
Main: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>OpenHaus</title>
</head>
<body>
<div id="main"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
Inside the main vue app i have a folder called "apps" which contains the admin & user apps.
Each App.vue file is then imported and handled as a file.
Doing this, a important step is missing: How tho handle from each sub-app the main.js file?
Treating each app as a component for the main app sees not as good as thought as first.
How can i combine the two apps together as a single app, while i maintain/develop/test each app separate?
Perhaps after "compiling" as library: https://vitejs.dev/guide/build.html#library-mode ?
User App: https://github.com/OpenHausIO/frontend
Admin App: https://github.com/OpenHausIO/admin-frontend
Main App: https://github.com/OpenHausIO/frontend-composition
I have personally never heard of a setup where two apps are combined into one. I can understand why this would cause the conflicts that you mention. If I was in your shoes I would probably go with a different approach.
It seems that you have a user and admin app. If the intention is to have a user and admin environment where the content is similar, but certain things can only be accessed if you are an admin. I would create one app that establishes based on your credentials whether you will be in the 'admin' or 'user' environment. Which will be one app that is not split up into two.
If the user and admin apps will be completely different in content, then I would simply create two different apps. This will not only resolve the conflicts, but I think it will also give you a clearer overview of the apps that you are working on. It can become difficult to make the distinction on which of the apps you are making a change when both are combined into one. Especially if you intend to upscale the apps in the future.
I am learning Rails 7 with the new default Importmap jsmp syntax. I have tried to follow what few tutorials are out there, but am still unable to get either jQuery or Stimulus to respond to a simple alert function on page load.
I started over with a bare-bones Rails 7 application, ran bundle install, followed by rails turbo:install, rails stimulus:install and created a Static controller to route to a Landing page at Static#Landing.
My `landing.html.erb' file contains:
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
I get the expected string output, so I know Javascript is enabled in the Browser.
My importmap.rb file contains:
# Pin npm packages by running ./bin/importmap
pin "application", preload: true
pin "#hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "#hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "#hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "jquery", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery#3.6.0/dist/jquery.js"
pin "jquery-ui-dist", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery-ui-dist#1.13.1/jquery-ui.js"
pin "jqtree", to: "https://ga.jspm.io/npm:jqtree#1.6.2/lib/tree.jquery.js"
pin_all_from "app/javascript/controllers", under: "controllers"
The only lines I added were the 3 invoking a form of jQuery.
I next added the 3 import statements for jQuery, jQuery-ui-dist, and jqtree to the application.js file. The complete file contains:
// Javascript document
// Document Name: application.js
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "jQuery"
import "jquery-ui-dist"
import "jqtree"
import "controllers"
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
$(function(){
window.alert("It looks like jQuery is too.");
});
export { application }
I next edited my app/assets/config/manifest.js file to include the following:
//= link_tree ../images
//= link_tree ../icons
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../javascript/library .js
//= link_tree ../../../vendor/javascript .js
However, even though inline <script>s work as outlined above, I get no response from either jQuery or Stimulus to the alert function in application.js. When I check my source code, I see the following:
<!DOCTYPE html>
<html>
<head>
<title>Testingjquery</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="LkQZA1mB-KU38K8S1lg_BMJWPx4HLonSyQ0s8W2vCotmw3aHIXZNDnPcJCtbgeXSTWrEuWJBZWlkOZcLe7Ru9w" />
<link rel="stylesheet" href="/assets/application-e0cf9d8fcb18bf7f909d8d91a5e78499f82ac29523d475bf3a9ab265d5e2b451.css" data-turbo-track="reload" />
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js",
"#hotwired/turbo-rails": "/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js",
"#hotwired/stimulus": "/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js",
"#hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
"jquery": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jquery-ui-dist": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jqtree": "https://ga.jspm.io/npm:jqtree#1.6.2/lib/tree.jquery.js",
"controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
"controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
"controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js"
}
}</script>
<link rel="modulepreload" href="/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js">
<link rel="modulepreload" href="/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js">
<link rel="modulepreload" href="/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js">
<link rel="modulepreload" href="/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js">
<script src="/assets/es-module-shims.min-d89e73202ec09dede55fb74115af9c5f9f2bb965433de1c2446e1faa6dac2470.js" async="async" data-turbo-track="reload"></script>
<script type="module">import "application"</script>
</head>
<body>
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
</body>
</html>
As you can see, jQuery is not being loaded at all and Stimulus is being loaded, but is unresponsive to any code references. I am new to Stimulus, intermediate with Javascript/jQuery and new to Rails 7. From what I have read, I like the conceptualization behind these radical shifts in Rails methodology, but so far, haven't been able to get it to work.
The files are all in their appropriate places according to the references to them. For illustration, this is my file tree:
-app
-assets
-config
-manifest.js
-javascript
-controllers
-application.js
...
-library
-jquery.js
-jquery-ui.js
-application.js
...
-config
-importmap.js
...
The final application.js file contains no code that I changed and is as follows:
import { Application } from "#hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
export { application }
Granted, there are two application.js files that Importmaps/Stimulus/Turbo seem to rely upon, and perhaps I inserted some code into the wrong application.js file. If so, it was because the tutorials that I was following didn't specify or clarify which file to insert certain code into.
Does anyone see a fundamental error in my code or can suggest another approach? Thanks in advance.
I am a newbie to Vue.js. I don't like working with cli, so I am using CDN for everything but stuck in some unknown problem. I googled many thing but couldn't understand what going on. Any help would be really appreciated.
Here is my index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="8-utf" />
<meta name="author" content="Yash Gaikwad">
<meta name="description" content="">
<meta name="keyword" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="style.css"> <!--Stylesheet-->
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400&display=swap" rel="stylesheet"> <!--Google Fonts-->
<script src="https://www.w3schools.com/lib/w3.js"></script> <!--W3.Css-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js" type="text/babel"></script><!--Bable Hosting-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!--Vue Hosting-->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <!--Vue Router-->
</head>
<body>
<div id="app">
</div>
<script src="script.js"></script> <!--Javascript-->
</body>
</html>
Here is my script.js
import app from "./main.vue"
new Vue({
el: "#app",
data: {
},
methods: {
},
render: h => h(app)
});
This is my main.vue (root component)
<template>
<app-header></app-header>
<app-footer></app-footer>
</template>
<script>
import Header from "./components/header.vue";
import Footer from "./components/footer.vue";
export default {
components: {
"app-header": Header,
"app-footer": Footer
}
}
</script>
<style scoped>
</style>
Seems to me that importing main.vue is causing error. And something is going wrong there.
This are the errors I being getting from both ff and chrome
Uncaught SyntaxError: Cannot use import statement outside a module
SyntaxError: import declarations may only appear at top level of a module
Thankyou every much guys.
.vue is not a file type that a browser understands. If you want to build VueJS applications without using any CLI tools you'll have to learn about ES6 Modules and understand that your application won't be supported by all browsers.
CLI tools like Webpack transforms your JavaScript and Vue code into JavaScript code that is compatible with more browsers, minifies your code (makes the size of the files that are downloaded smaller), etc. It also makes it much easier for you to use third-party packages in your code, as well as to keep them updated.
Using a CLI tool like Webpack or VueCLI for Vue apps will make your life much easier in the long run and is the standard way of doing things across the industry.
Always import statement should be at the top of the file,
you are using template and then the import
in main.vue put script block to the top and then the template
The browser cannot understand .vue extension while using vue CDN so replace that with .js or load vue via CLI instead.
Next inside the JS (vue) files, remove the template, style and script tag and make it look like this:
//header.js
export default {
data: () => ({
}),
template:`<h1>Header</h1>`
}
//footer.js
export default {
data: () => ({
}),
template:`<h1>Footer</h1>`
}
Next, add a type module to your script tag like:
<script type="module">
import Header from "./components/header.js";
import Footer from "./components/footer.js";
export default {
components: {
"app-header": Header,
"app-footer": Footer
}
}
</script>
You can also replace ES6 import statement with ES5 require if you don't want to use type="module"
I have a Vue CLI app that I want to connect to a server back-end.
The server will return a view template with a data payload, and I want to inject that payload as JSON into the Vue app as a data property.
The index.html file generated by Vue CLI looks like the following (I set filenameHashing to false in vue.config.js to avoid random file names):
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link href=/css/app.css rel=preload as=style>
<link href=/css/chunk-vendors.css rel=preload as=style>
<link href=/js/app.js rel=preload as=script>
<link href=/js/chunk-vendors.js rel=preload as=script>
<link href=/css/chunk-vendors.css rel=stylesheet>
<link href=/css/app.css rel=stylesheet>
</head>
<body>
<div id=app>
</div>
<script src=/js/chunk-vendors.js></script>
<script src=/js/app.js></script>
</body>
</html>
And main.js looks like the following:
import Vue from 'vue';
import SiteContainer from './components/layout/SiteContainer.vue';
new Vue({
render: h => h(SiteContainer)
}).$mount('#app');
I want to be able to do something like the following:
<div id="app" :data="{{ json-string-of-data-payload-from-server }}">
So that I can then access the data in SiteContainer as follows:
props: [
'data'
]
I've tried essentially doing what I wrote above, but because the render method seems to completely replace the #app div with the site-container component, the :data property is lost as well.
I also saw that you can pass a second argument to render with data, but I couldn't figure out how to make it work, and ultimately, that's in main.js, not the view template file that the server will use, which is where I need the JSON data to be to get it from the server to the Vue app.
How can I pass data from the server-generated view template to the Vue CLI app to get everything going? Thank you.
I was able to figure it out.
By defining the SiteContainer component as a Vue.js component in main.js first, I am able to freely use the component in the HTML file to get what I want.
Specifically, I changed the main.js file as follows:
import Vue from 'vue';
import SiteContainer from './components/SiteContainer.vue';
Vue.component('SiteContainer', SiteContainer); // This is the key.
new Vue({
el: '#app'
});
And then the body part of the HTML file becomes the following (i.e., replace the #app div that I had in my question above):
<SiteContainer id="app" :data="{{ json-string-of-data-payload-from-server }}">
</SiteContainer>
I am creating a project with react, redux and next.js, and want to import CSS files in js.
I followed instructions in next.js/#css and next-css, but find out that CSS styles do not work.
My code is as follow:
pages/index.js:
import React from 'react'
import "../style.css"
class Index extends React.Component {
render() {
return (
<div className="example">Hello World!</div>
);
}
}
export default Index
next.config.js:
const withCSS = require('#zeit/next-css')
module.exports = withCSS()
style.css:
.example {
font-size: 50px;
color: blue;
}
package.json:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#zeit/next-css": "^0.1.5",
"next": "^6.0.0",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-redux": "^5.0.7",
"react-scripts": "1.1.4",
"redux": "^4.0.0",
"redux-devtools": "^3.4.1"
},
"scripts": {
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"dev": "next",
"build": "next build",
"start": "next start"
}
}
Questions:
1. There is an "Uncaught SyntaxError" in Chrome, but it seems to not affect the rendering of the page. But I still wondering the reason and the solution. index.js error in chrome is below img
2. As shown in Chrome, there's no "example" class, which means the style.css file is not loaded. Am I missing anything? no CSS file in chrome
Thanks in advance.
EDIT 2: As of Next.js > 10, you can import a global CSS file into _app.js, and you can use CSS modules in your components. More in the Next.js docs.
EDIT: As of Next.js 7, all you have to do to support importing .css files is to register the withCSS plugin in your next.config.js. Start by installing the plugin as dev dependency:
npm install --save-dev #zeit/next-css
Then create the next.config.js file in your project root and add the following to it:
// next.config.js
const withCSS = require('#zeit/next-css')
module.exports = withCSS({/* my next config */})
You can test that this is working by creating a simple page and importing some CSS. Start by creating a CSS file:
// ./index.css
div {
color: tomato;
}
Then create the pages folder with an index.js file. Then you can do stuff like this in your components:
// ./pages/index.js
import "../index.css"
export default () => <div>Welcome to next.js 7!</div>
You can also use CSS modules with a few lines of config. For more on this check out the documentation on nextjs.org/docs/#css.
Deprecated: Next.js < 7:
You'll also need to create a _document.js file in your pages folder and link to the compiled CSS file. Try it out with the following content:
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'
export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
<link rel="stylesheet" href="/_next/static/style.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
The stylesheet is compiled to .next/static/style.css which means that the CSS file is served from /_next/static/style.css, which is the value of the href attribute in the link tag in the code above.
As for the first question, it's probably Chrome not understanding the import syntax. Try to enable the Experimental Web Platform flag in chrome:flags and see if that solves it.
For anyone who comes here ,the new Next JS supports CSS out of the box. The catch is that for modules (components), they must be named as the component. So, if you have a header inside a components directory, it must be named header.module.css
built-in-css-module-support-for-component-level-styles
Add {name}.css to src/static/styles/.
Then modify the Head in src/pages/_document.js to include the following link:
<Head>
<link href="/static/styles/{name}.css" rel="stylesheet">
</Head>
for next above 9.3, global css is written in "styles/globals.css" and you can import it to _app.js
import "../styles/globals.css";
Then for each component, you can write its own css and import it into the component. Pay attention to the naming:nameOfFile.module.css
Let's say you have "product.js" component and "product.module.css". you want to load css from "product.css" into "product.js"
import classes from "./product.module.css" // assuming it's in the same directory
you put all class names into product.module.css. Assume you have .main-product in product.module.css. Inside product.js, let's say you have a div to style
<div className={classes.main-product} > </div>
with the css module feature, you can use the same className in other components and it wont conflict. Because when next.js compiles, it will hash the name of the className, using its module. So hashed values of same classnames from different modules will be same
you need create to custom _document.js file.
Custom document when adding css will look like:
import React from "react";
import Document, { Head, Main, NextScript } from "next/document";
export default class MyDocument extends Document {
render() {
const { buildManifest } = this.props;
const { css } = buildManifest;
return (
<html lang="fa" dir="rtl">
<Head>
{css.map(file => (
<link rel="stylesheet" href={`/_next/${file}`} key={file} />
))}
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}
As Zeit said :
Create a /static folder at the same level the /pages folder.
In that folder put your .css files
In your page components import Head and add a to your CSS.
import Head from 'next/head'
function IndexPage() {
return (
<div>
<Head>
<title>My page title</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<p>Hello world!</p>
</div>
)
}
export default IndexPage
And that's it, this way Next.js should render the link tag in the head of the page and the browser will download the CSS and apply it.
Thanks Sergiodxa at Github for this clear solution.
If you use next.js do this.
create next.config.js in root projects
const withCSS = require('#zeit/next-css');
function HACK_removeMinimizeOptionFromCssLoaders(config) {
console.warn(
'HACK: Removing `minimize` option from `css-loader` entries in Webpack config',
);
config.module.rules.forEach(rule => {
if (Array.isArray(rule.use)) {
rule.use.forEach(u => {
if (u.loader === 'css-loader' && u.options) {
delete u.options.minimize;
}
});
}
});
}
module.exports = withCSS({
webpack(config) {
HACK_removeMinimizeOptionFromCssLoaders(config);
return config;
},
});
Don't forget to restart the server
Global CSS Must Be in Your Custom <App>
Why This Error Occurred
An attempt to import Global CSS from a file other than pages/_app.js was made.
Global CSS cannot be used in files other than your Custom due to its side-effects and ordering problems.
Possible Ways to Fix It
Relocate all Global CSS imports to your pages/_app.js file.
Or, update your component to use local CSS (Component-Level CSS) via CSS Modules. This is the preferred approach.
Example:
// pages/_app.js
import '../styles.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
Set this to false if your app works directly with the web 5 package.
module.exports = {
// Webpack 5 is enabled by default
// You can still use webpack 4 while upgrading to the latest version of
// Next.js by adding the "webpack5: false" flag
webpack5: false,
}
You can use webpack 4.
yarn add webpack#webpack-4