Where is "vue.config.js" file? - javascript

I've just started to learn Vue but I simply can't set up enviroment for my container.
I use Cloud9 and I have to assign my host for serving Vue app according to this link.
Unfortunately, I can't find vue.config.js file to do this.
Also there is no path indication in Vue docs.
"if it's present in your project root..." but what if not? Whatever, go use React? :)
Vue version: 3.1.1

See the documentation of Vue CLI:
vue.config.js is an optional config file that will be automatically
loaded by #vue/cli-service if it's present in your project root (next
to package.json). You can also use the vue field in package.json, but
do note in that case you will be limited to JSON-compatible values
only.
The file should export an object containing options:
// vue.config.js
module.exports = {
// options...
}
So just create the file by yourself. It is completely optional.

It's simple just create file vue.config.js in ROOT folder of project.
Its very important file. it's on top of vue project.
People usualy use more than one page in old fasion style.
vue.config.js is right place to define main dependency pages.
I used to create main sigle-page app (pwa) but i also need
some other pages. Like error pages or google verify for example.
You can change dev server port , sourceMap enable/disable or PWA configuration...
module.exports = {
pages: {
'index': {
entry: './src/main.ts',
template: 'public/index.html',
title: 'Welcome to my vue generator project',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
'bad': {
entry: './src/error-instance.ts',
template: 'public/bad.html',
title: 'Error page',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
/* Disabled - Only one time
'googleVerify': {
entry: './src/error-instance.ts',
template: 'public/somelink.html',
title: 'Error page',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
*/
},
devServer: {
'port': 3000
},
css: {
sourceMap: false
},
pwa: {
name: 'My App',
themeColor: '#4DBA87',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
},
}
For this config here's main instance file:
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App, {
props: { error: 'You can not search for assets...' }
}),
}).$mount('#error')

if you used vue-cli this is in your root like this
your project
node_module
public
src
...
vue.config.js
if you dont have it,
your project is not vue-cli, it is vit-vue ,
and your config file name is vit.config. vue

Related

Vite HMR doesn't detect changes to components nested under sub folders

In a Vue + Vite project, I have folder structure like this
The problem is vite doesn't detect changes (ctrl+s) in A.vue or B.vue i.e., components nested under NestedFolder in components folder. Everywhere else works fine.
My vite.config.js looks like this,
import { fileURLToPath, URL } from 'node: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)),
'#public': fileURLToPath(new URL('./public', import.meta.url))
}
},
server: {
proxy: {
'/api': {
target: 'XXX',
changeOrigin: true,
secure: false,
ws: true,
}
}
}
})
I've tried custom HMR functions as per the vite HMR API docs, got it to send full reload using this.
...
plugins: [
vue(),
{
name: 'custom-hmr',
enforce: 'post',
// HMR
handleHotUpdate({ file, server }) {
if (file.endsWith('.vue')) {
console.log('reloading json file...');
server.ws.send({
type: 'reload',
path: '*'
});
}
},
}
], ...
I looked through vite's HMR API docs but couldn't figure out how to send update event to vite when using custom hmr function
Any help/suggestion on how to solve this would be greatly appreciated.
Ok I solved the problem. The problem is not with nested folders.
Vite seems to ignore components that are imported with absolute path.
E.g. Vite doesn't detect changes in components imported as:
import Dropdown from '#/components/GlobalDropdown.vue'
//# resolves to /src
but detects changes in imports that are relative:
import LoadingSpinner from '../LoadingSpinner.vue'
I couldn't find any setting that addresses this. But having relative paths for component imports solved the issue. Is this an issue?
I think issue is that you made a caseSensitive typo, please check that your path is correct, I had similar issue and this was one letter typed in uppercase.

ChunkLoadError: Loading chunk register failed

I am currently trying to implement lazy loading of routes in VueJS3 and Laravel. I'm using vue-router to implement my routes.
Unfortunately, whenever I click on a link, nothing happens and after 30 seconds, I see a timeout error pop up in my browser console. If I replace lazy loading of the routes with a direct import, everything runs fine.
I would appreciate any hints as to what might be going on here. I've had the problem for a couple of weeks now. All other posts and suggestions to clear browser cache or set the public path in webpack.config.js have not worked for me. I have also replaced laravel-mix with webpack and the problem remains.
Pre-conditions:
Webpack 5.69.1
Webpack-cli ^4.9.2
Vue ^3.2.31
Vue-router ^4.0.12
Laravel 7.2
Steps to reproduce
Run npm run production
Run php artisan serve
Open browser
Enter desired URL in browser: http://127.0.0.1:8000/login
Click on "Register" link after login page opens.
Expected behavior
Npm runs successfully manifest.json is updated. Webpack generates all chunks in dists folder.
Laravel server starts
Website is reacheable over http://127.0.0.1:8000
Login page opens component configured in the route. Login.js is downloaded by the browser.
Browser downloads register.js dynamically. Registration page is displayed
Observed behavior
Npm runs successfully manifest.json is updated. Webpack generates all chunks in dists folder.
Laravel server starts
Website is reacheable over http://127.0.0.1:8000
Login page opens component configured in the route. Login.js is downloaded by the browser.
register.js chunk is never downloaded. Registration page is never displayed. After 30 seconds timeout, error is printed in browser console.
ChunkLoadError: Loading chunk register failed.
(timeout: http://127.0.0.1:8000/dist/register.d3e633a9a1aea3ebf47b.js)
at Object.__webpack_require__.f.j (main.34a1a3da92d476b41479.js:4051:29)
at main.34a1a3da92d476b41479.js:3905:40
at Array.reduce (<anonymous>)
at Function.__webpack_require__.e (main.34a1a3da92d476b41479.js:3904:67)
at component (routes.js:35:55)
at extractComponentsGuards (vue-router.esm-bundler.js:2037:40)
at eval (vue-router.esm-bundler.js:3156:22)
webpack.config.js
const path = require('path');
const {VueLoaderPlugin} = require('vue-loader');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const options = {basePath:'/dist/',fileName:'../mix-manifest.json',publicPath:'dist/'};
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './resources/js/main.js',
output: {
clean: true,
filename: "[name].[chunkhash].js",
publicPath: './dist/',
path: path.resolve(__dirname, 'public/dist'),
chunkLoadTimeout: 30000,
},
resolve:{
alias: {
'#': path.resolve(__dirname,'resources/js'),
},
extensions: ['.js', '.vue', '.json']
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
new VueLoaderPlugin(),
new WebpackManifestPlugin(options),
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: false,
__VUE_PROD_DEVTOOLS__: false,
}),
]
};
routes.js
const routes = [
{
path: "/",
component: DefaultLayout,
children: [
{
path: "/publicidade",
name: "publicidade",
component: () => import (/* webpackChunkName: "publicity" */ '../pages/Publicidade')
},
{
path: "/login",
name: "login",
component: () => import(/* webpackChunkName: "login" */ '../pages/login.vue')
},
{
path: "/cadastro",
name: "cadastro",
component: () => import(/* webpackChunkName: "register" , webpackPrefetch: true */ '../pages/Register.vue')
},
{
path: "perfil",
name: "perfil",
component: () => import('../pages/Profile')
},
],
},
{ path: "/:catchAll(.*)", component: NotFoundPage }
];
I had the same problem in vue, I solved it using a method similar to the method Polymer uses to import the lazy loading resources.
Example:
setTimeout(() => {
for (let i in routes[0].children ){
routes[0].children[i].component();
}
}, 1000)
After a couple of weeks of head banging I was able to locate the problem by stepping through the Webpack code starting at the Webpack.require call (See my error log above).
My issue was that my chunks were being blocked by the Osano GPDR Consent service, which I use in my website to satisfy EU privacy laws.
As soon as I removed the osano script tag from the header of my site, everything just worked.
<script src="https://cmp.osano.com/AzZcqMSBLrjhQ2PZ1/4e3118ce-1798-4f27-93be-f6c9e99f1537/osano.js"></script>
Since GPDR Consent is a must here in Europe, I had to add a rule to the Dashboard of my Osano account in order to allow scripts from 127.0.0.1:8080 domain.

Bundle JS and CSS into single file with Vite

I'm having a devil of a time figuring out how to build a single .js file from Vite in my Svelte project that includes all of the built javascript and CSS from my Svelte projects. By default, Vite bundles the app into one html file (this is ok), two .js files (why??), and one .css file (just want this bundled into the one js file).
I ran this very basic command to get a starter project:
npx degit sveltejs/template myproject
I tried adding a couple of plugins, but nothing I added achieved the results I wanted. Primarily, the plugins I found seem to want to create a single HTML file with everything in it. It seems like PostCSS might be able to help, but I don't understand what configuration I can set via Vite to get it to do what I want.
What is the magic set of plugins and config that will output a single HTML file with a single js file that renders my Svelte app and its CSS onto the page?
Two steps,
We can inject css into js assets with vite-plugin-css-injected-by-js.
We can emit a single js asset by disabling chunks in rollup's config.
Final result,
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
export default defineConfig({
plugins: [cssInjectedByJsPlugin()],
build: {
rollupOptions: {
output: {
manualChunks: undefined,
},
},
},
});
If you're looking for a solution to this, you might want to take a look at vite-plugin-singlefile.
That doesn't come out of the box for vite but you can write a quick plugin which will be doing exactly that
const bundle_filename = ''
const css_filename = 'style.css'
defineConfig({
build: {
lib: {
entry: 'src/mycomponent.js',
name: 'mycomponent.js',
fileName: () => 'mycomponent.js',
formats: ['iife'],
},
cssCodeSplit: false,
rollupOptions: {
plugins: [
{
apply: 'build',
enforce: 'post',
name: 'pack-css',
generateBundle(opts, bundle) {
const {
[css_filename]: { source: rawCss },
[bundle_filename]: component,
} = bundle
const IIFEcss = `
(function() {
try {
var elementStyle = document.createElement('style');
elementStyle.innerText = ${JSON.stringify(rawCss)}
document.head.appendChild(elementStyle)
} catch(error) {
console.error(error, 'unable to concat style inside the bundled file')
}
})()`
component.code += IIFEcss
// remove from final bundle
delete bundle[css_filename]
},
},
],
},
},
})
I created a boilerplate Vite project for this problem:
https://github.com/mvsde/svelte-micro-frontend
Maybe the configuration helps with your case:
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
export default defineConfig({
plugins: [
svelte({
emitCss: false
})
],
build: {
assetsDir: '',
sourcemap: true,
lib: {
entry: 'src/main.js',
formats: ['iife'],
name: 'SvelteMicroFrontend',
fileName: 'svelte-micro-frontend'
}
}
})
I had the same issue and was able to fix by editing vite.config.ts as follows tested on vite#2.3.8
export default {
build: {
rollupOptions: {
output: {
manualChunks: undefined,
},
},
},
};
If you are working with Svelte, you can use emitCss:
export default defineConfig({
plugins: [svelte({
emitCss: false,
})],
})
As manualChunks are no longer working in a latest versions of Vite, there's no any way to combine all the chunks into one.
But found a hacky solution to have an index.html + bundle.js after the build: https://github.com/d-velopment/SvelteKit-One-Bundle - it rewraps the project's initial .js files to go from bundle.js, which could be loaded from index.html or external project.

multiple pages in Vue.js CLI

I'm having trouble figuring out how to have multiple pages in a Vue CLI project. Right now I have my home page with a few components and I want to create another page but I do not know how to do that. Am I supposed to create multiple html files where the index.html by default is? In a simple file structure with css js img folder and html files as pages I know that creating another html file means making another page. But I don't understand how this works with Vue CLI project.
I saw stuff like vue-router and "pages" in Vue documentation but I do not understand them very well. What are my alternatives? Is there a guide that explains that in detail, because I wasn't able to find any, let alone detailed. Would be very happy if you could help! Thank you!
First: always read the official documentation. With Vue you can build a SPA, and a MPA is also no problem. Just follow the guides:
https://cli.vuejs.org/
https://cli.vuejs.org/guide/html-and-static-assets.html#building-a-multi-page-app
https://cli.vuejs.org/config/#pages
You should create a new project with Vue CLI 3. Once you've created your project set it to be manually configured. Make sure you don't choose the SPA option. Vue will then create a nice "start" project using a MPA approach. After that, just repeat the config on vue.config.js.
Updated #1
It seems that some updates on Vue Cli, have changed the way to build a MPA app, so:
Create a new application vue create test
Choose Manual configuration
The boilerplate created will be for a SPA. So make the following changes:
Create a folder under src named pages (optional)
Into this folder create your own pages: Home, About, etc.
Copy and paste the App.vue and main.js from src, into your new folders - Home, etc.
Format the App.vue into this folders, to your liking.
Create a vue.config.js and set it like this: https://cli.vuejs.org/config/#pages
Below, I have three images demonstrating this:
First: a fresh new app
Second: this same app, with the changes I made above
Third: the vue.config.js from this app
You don't need to create the pages folder, this is just to get the idea.
Link to GitHub: Building a MPA App
EDIT: Vue has this built-in. Skip to the bottom for more.
Original answer:
There are two ways to interpret your question, and therefore to answer it.
The first interpretation is: "how can I support routing to different pages within the same single-page app, e.g. localhost:8080/about and localhost:8080/report etc?". The answer to this is to use the router. It's reasonably straightforward and works well.
The second interpretation is: "my app is complex, and I have multiple single-page applications, e.g. one app for the 'website' part, one app for consumers to log in and do work, one app for admins, etc - how can vue do this, without making three entirely separate repositories?"
The answer to the latter is a single repository with multiple single-page apps. This demo looks like exactly what you're after:
https://github.com/Plortinus/vue-multiple-pages/
Look in particular at: https://github.com/Plortinus/vue-multiple-pages/blob/master/vue.config.js
Updated answer:
It turns out that vuejs has the idea of multiple top-level pages built-in. I mean, it makes sense - it's going to be really common, despite what many incorrect answers are saying about "no, it's for single page apps"!
You want the pages option in the vue.config.js file:
https://cli.vuejs.org/config/#pages
If your project doesn't have that file in the root directory, create it and vuejs will discover it.
There is a long and a short way to define each page. I used the short form here:
module.exports = {
pages: {
index: 'src/pages/index/main.ts',
experiment: 'src/pages/experiment/main.ts'
}
}
You don't have to put your work under "pages". It could be "/src/apps/index/index.ts" or whatever.
After moving code around and changing some imports from:
import HelloWorld from './components/HelloWorld'
to
import HelloWorld from '#/components/HelloWorld'
The app works - but the "experiment" app in my repo had to be loaded like this:
http://localhost:8080/experiment.html
Pretty ugly, and even worse because it uses the router which resulted in URLs like:
http://localhost:8080/experiment.html/about
Ugh.
Fortunately, this stackoverflow answer solved it. Update the vue.config.js file to include devServer options (make sure this is at the top level of the exported object:
devServer: {
historyApiFallback: {
rewrites: [
{ from: /\/index/, to: '/index.html' },
{ from: /\/experiment/, to: '/experiment.html' }
]
}
}
Then also modify the router.ts file to append the extra path (in my case "experiment/":
export default new Router({
mode: 'history',
base: process.env.BASE_URL + 'experiment/',
...
Then URLs resolve nicely, e.g.: http://localhost:8080/experiment/about
This may not be relevant to the question, but bear with me, maybe my answer can help someone.
I use webpack+vue, and I have figured out how to build multiple pages applications. Here my webpack.config.js:
const path = require('path');
const fs = require('fs')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
entry: {
app: './src/app.js',
mgmt: ['./src/modules/mgmt/mgmt.js'],
login: './src/modules/login/login.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
// publicPath: '/ahezime/',
filename: (chunkData) => {
console.log('chuckData.chunk.name => ', chunkData.chunk.name)
return chunkData.chunk.name === 'app' ? './[name].bundle.js' : './[name]/[name].bundle.js';
}
},
optimization: {
minimizer: [
new TerserPlugin(),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new CleanWebpackPlugin(['dist']),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
title: 'app',
template: './src/app.html',
// inject: false,
chunks: ['app'],
filename: './index.html'
}),
new HtmlWebpackPlugin({
title: 'mgmt',
template: './src/modules/mgmt/mgmt.html',
// inject: false,
chunks: ['mgmt'],
filename: './mgmt/index.html'
}),
new HtmlWebpackPlugin({
title: 'login',
template: './src/modules/login/login.html',
// inject: false,
chunks: ['login'],
filename: './login/index.html'
})
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-proposal-object-rest-spread']
}
}
}
],
rules: [
{
test: /\.vue$/,
exclude: /node_modules/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.scss?$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}
};
And here's my directory structure:
https://i.stack.imgur.com/uFvKx.png
And you can jump pages:
<template>
<div>
<h1>App</h1>
<div>
Please click me, and let take you into the login page!!!
</div>
<span>Before computed: {{ message }} </span>
<br>
<span>Afer computed: {{ computedMessage() }} </span>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello World!'
}
},
computed: {
reversedMessage: function() {
return this.message.split('').reverse().join('')
}
},
methods: {
computedMessage: function() {
return this.message.split('').reverse().join('')
}
}
}
</script>
Note pointing users to what should be the accepted answer
At the moment of posting my initial answer I wasn't aware of the possibility of actually building MPAs in VueJS. My answer doesn't address the question asked therefore I will recommend to take a look at the answer provided by PJ.Wanderson bellow which should be the accepted answer
Inital Answer
Vue.js projects are SPAs(single page applications). You only have one .html file in the entire project which is the index.html file you mentioned. The "pages" you want to create, in vue.js are referred to as components. They will be plugged into the index.html file and rendered in the browser. A vue.js component comprises 3 parts:
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
Template: it contains all the html your page should display (this is where you put the html of your pages)
Script: it contains all JavaScript code that will be executed on the page/component
Style: it contains the CSS that will style that specific component/page
You can check this tutorial out for a quick-start Vue.js 2 Quickstart Tutorial 2017
It explains vue.js project structure and how the various files relate to each other

How do I compile a preload script w/ webpack in Electron?

Electron 1.6.5, Webpack 2.4.1
I'm using electron-react-boilerplate with a webview component. I inject a preload script into the webview that does something like this:
const { ipcRenderer } = require('electron');
const doSomething = require('./utils/do-some-thing.js');
document.addEventListener('DOMContentLoaded', event => {
doSomeThing()
// tell scraper to get started
ipcRenderer.sendToHost('THING IS DONE', [{ url: document.URL }]);
});
webview needs this script passed as a file:// path like so:
<webview
preload={'./some/folder/preload.js''}
{...props}
/>
The problem is that my webpack setup doesn't transpile preload.js because it isn't explicitly called via require(). Then, when I build the app, the path ./some/folder/ doesn't exist.
I've tried setting webpack to create a second compiled script like so:
entry: [
'babel-polyfill',
'./app/index',
'./some/folder/preload.js'
],
output: {
path: path.join(__dirname, 'app/dist'),
publicPath: '../dist/'
},
But this leads to a JavaScript heap out of memory error, which leads me to believe this isn't correct.
Also: wouldn't this approach duplicate electron in the ./dist folder since it's require()'d by both preload.js and index.js ?
You could use the electron-main and electron-preload configurations of webpack:
const path = require('path');
module.exports = [
{
entry: './src/index.js',
target: 'electron-main',
output: {
path: path.join(__dirname, 'dist'),
filename: 'index.bundled.js'
},
node: {
__dirname: false,
}
},
{
entry: './src/preload.js',
target: 'electron-preload',
output: {
path: path.join(__dirname, 'dist'),
filename: 'preload.bundled.js'
}
},
]
You get two bundles after building, but Electron is not in either of them, so no duplicates.
Notice the __dirname: false, which is required since otherwise webpack replaces __dirname always replaced by / by webpack, leading to an unexpected behaviour in almost all cases (see here for further information, should be false by default, but wasn't for me).
We had a similar issue where we had several preload scripts instead of one. Our solution was to use the CopyPlugin. So for us, the config looks like this:
const CopyPlugin = require("copy-webpack-plugin");
plugins.push(new CopyPlugin([{ from: "src/container-with-scripts/", to: "preloadScripts/" }]));
module.exports = {
module: { rules }, // imported from elsewhere
target: "electron-renderer",
node: { global: true },
plugins,
resolve: {
extensions: [".js", ".ts", ".jsx", ".tsx", ".css", ".scss"]
}
};
So we just take the folder containing all our scripts and copy them to the autogenerated .webpack folder.
I was having the same problem and here's solution that worked for me:
Electron-webpack documentation now contains example how to add additional entries.
"electronWebpack": {
"main": {
"extraEntries": ["#/preload.js"]
}
}
Note that you can use the # alias to reference your main.sourceDirectory
in this case it's path to your main process script which will be src/main by default
This adds preload script from src/main/preload.js into webpack entries.
Then you need to add preload script into window with
new BrowserWindow({
webPreferences: {
nodeIntegration: true,
preload: path.resolve(path.join(__dirname, "preload.js")),
}
})
That's all. __dirname was giving me relative path and electron requires absolute path for preload script so it was failing. path.resolve will get you absolute path needed to make it work.
Electron provides an option to load a script before any other execution in your DOM.
You have to provide your pre-load script file path while creating a browser window and file path of the script should be the absolute.
You can find reference here

Categories

Resources