VUE CLI different paths for files in 'public' folder - vue.js

My application structure is -
folder -> frontend - folder with the applications
folder -> html -> spa - and this is where I put my app that was built
There are 2 folder in 'spa' - assets and static. In static folder there are files from 'frontend -> public'.
Here is the problem
I need to add an external script, so i put in head of index.html
<script src="<%= BASE_URL %>static/js/advert.js"></script>
When I have built my app everything is fine, but locally(npm run serve) it has the wrong URL.
I tried to play with publicPath in vue.config.js and even set it up correctly by ternary process.env.NODE_ENV === 'production'. On local and built mode the file was fount, but it also has changed all of the routes(links, menu, etc).
Please help me with a work around

So, here is the solution that I figured out.
In my index.html
<script src="<%= BASE_URL %><%= NODE_ENV === 'production' ? 'spa/' : ''%>static/js/advert.js"></script>

Related

How do I make vue app load its js files and css files from a cdn?

What I'm trying to do is make my vue ssa app load all its static files from a cdn instead from a server hosting it. I build the app using the command npm run build and modify the file index.html like this, I changed
src="/js/chunk-vendors.0704b531.js" to src="https://cdn.example.com/js/chunk-vendors.0704b531.js"
href="/css/app.c7158abb.css" to href="https://cdn.example.com/css/app.c7158abb.css"
(Could not change
src="/js/app.ee558821.js" to src="https://cdn.example.com/js/app.ee558821.js"
without causing an error. I'll explain later)
and I upload all the files in the dist folder including the index.html to a shared hosting server. I'm using bunny cdn and configured it to work with my domain. All works fine. However when I tried to include the file app.ee558821.js on the cdn (Issue I said I'll explain later)
src="/js/app.ee558821.js" to src="https://cdn.example.com/js/app.ee558821.js"
I got these error messages on the browser console
ChunkLoadError: Loading chunk 245 failed.
(missing: https://example.com/https://cdn.example.com/js/245.e400d699.js)
What I can see in the browser console is that all the files viz 'chunk-vendors.0704b531.js', 'app.c7158abb.css' and 'app.ee558821.js' successfully load from the cdn but the all the other files 'app.ee558821.js' somehow called where getting the path wrong. Instead of the normal path like https://cdn.example.com, the path instead look like this https://example.com/https://cdn.example.com.
Now my question is how do I make my vue app loads all its static assets from a cdn?
This is the content of my vue.config.js file
const { defineConfig } = require('#vue/cli-service');
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
});
These are the contents of my dist folder
css
some files here
js
|114.b704aee6.js
|245.e400d699.js
|439.027f133c.js
|623.76b80e83.js
|724.ebcd23c0.js
|app.ee558821.js
|chunk-vendors.0704b531.js
favicon.ico
index.html
Thank you very much any help is greatly greatly appreciated. I recently taught myself how to code and this is my first question on stackoverflow.
Thank you Michal LevĂ˝ for pointing me in the right direction. I changed the publicPath property to 'https://cdn.example.com/' and that fixed the problem.

Assets in Vue app not loading when published to Github pages

I'm publishing my SPA that I'm making with Vue and Buefy to my a gh-pages branch a of private repo, just so I can test if everything will load normally.
Later, I'll upload the finished website to the actual public repo, which is tied to my custom URL (I'm redesigning the website from scratch, using a diff tech).
Since Vue websites needs to be built for distribution, I'm using an NPM package to do this for me: https://github.com/KieferSivitz/vue-gh-pages
"deploy": "node ./node_modules/vue-gh-pages/index.js --branch gh-pages -m \"Deploy to gh-pages.\""
When deploying the website, it loads only partially. The images won't load, and the router will not work (links to other pages won't work).
I'm storing images in the assets folder, and using require('#/assets/logo.png') to load them (at least it works with localhost).
The images are trying to be loaded from https://<username>.github.io/img/logo.d2151712.png.
I read that I would need to set the publicPath to my project name, since currently the website is being served from https://<userName>.github.io/<projectName>/, but with that, the whole website is 404-ing.
With that property, the whole website would try to load from https://<username>.github.io/<projectName>/<projectName>.
I think that somewhere, there's a setting adding <projectName> to router, but not adding elsewhere.
Edit
I tried to force vue-router to get the correct base, without setting the publicPath:
base: "<projectName>/", //process.env.BASE_URL,
But the routes are stil not working, since I'm lazy loading them using import("#/views/Page.vue").
It seems that your issue is, that you want to run your Vue app in a subfolder of a domain (domain.com/subfolder/index.html). This needs to be configured in Vue CLI. Add a new file to the root of your repository, called vue.config.js and add the following content:
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/subfolder/' : '/',
};
This will set the webpack publicPath to /subfolder/ when running the build process in production mode. If you are using Vue CLI < 3.3, you need to use baseUrl instead. You need to make sure, that your path starts with a slash.
See also the documentation of publicPath.
Vue CLI has also a special section for the deployment to GitHub pages. You might also want to take a look at this: https://cli.vuejs.org/guide/deployment.html#github-pages
I read that I would need to set the publicPath to my project name, since currently the website is being served from https://.github.io//, but with that, the whole website is 404-ing.
Indeed, the publicPath property is required to be set to the GitHub repo name, surrounded by slashes (i.e., /github_repo_name/). The 404's are caused by vue-gh-pages removing the leading slash from URLs in index.html:
<!-- <script src=/github-pages-vue-demo/js/chunk-vendors.c4b075fb.js></script> --> <!-- before -->
<!-- <script src=/github-pages-vue-demo/js/app.9b45ea45.js></script> --> <!-- before -->
<script src=github-pages-vue-demo/js/chunk-vendors.c4b075fb.js></script>
<script src=github-pages-vue-demo/js/app.9b45ea45.js></script>
With that property, the whole website would try to load from https://<username>.github.io/<projectName>/<projectName>.
That's a side effect of the slash-removal, making the URLs relative. Relative URLs are relative to the current location (appended to the current directory). For example, with this GitHub pages URL - https://tony19-sandbox.github.io/github-pages-vue-demo/, a relative URL of github-pages-vue-demo/js/app.9b45ea45.js would resolve to:
https://tony19-sandbox.github.io/github-pages-vue-demo/github-pages-vue-demo/js/app.9b45ea45.js
And an absolute URL of /github-pages-vue-demo/js/app.9b45ea45.js would resolve to:
https://tony19-sandbox.github.io/github-pages-vue-demo/js/app.9b45ea45.js
I think that somewhere, there's a setting adding <projectName> to router, but not adding elsewhere.
vue-router has a base property for that purpose, but Vue CLI (#vue/cli-plugin-router) correctly defaults it to process.env.BASE_URL. That environment variable is already equal to publicPath from your Vue CLI config, so there's no need to set it.
Workaround
If you wish to continue using vue-gh-pages, you could use patch-package to disable the slash-removal (index.js line 109) as shown below:
//editForProduction();
if (repository !== null) {
pushToGhPages();
}
GitHub demo
Otherwise, I would skip that library entirely, and use gh-pages directly in a deploy script.
Vue has a configuration for that. If you use vue client then add vue.config.js the next lines por public path property
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './':'/' };

Vue js problems when building outside the src folder

I am working on an MPA with Vue and codeigniter. I have the following architecture:
-htdocs(root)
- application
- src
- views
- models
- controllers
I work with my frontend basically in the src directory and the others are codeigniter MVC model directories. What I am doing is configuring the webpack to build directly in the views directory so that my codeigniter can consume the generated htmls, configured as follows: (in this case I set it up in the vue.config.js file
)
outputDir: './views'
Up to this point everything works fine, wepback does the bundles and generates all the necessary files inside my views directory.The problem now is that the path to the files is the root of the project. Then he tries to fetch the files like this:
<link rel="preaload" href="/css/chunk-common.45fe69c2.css" as="style">
So that it points to the correct path (application/views) I made the following configuration in the vue.config.js:
assetsDir: './views'
But now when he is going to do the build I have the following warning and the files bundle is not completed.
Does anyone know why this happens?
Assuming you want to access static assets under the base URL http://example.com/application/views/..., you'll want to set the publicPath property in your config
// vue.config.js
module.exports = {
outputDir: 'views',
publicPath: '/application/views/',
// ...
}
FYI, if you ever do want to use assetsDir, don't prefix it with ./
A directory (relative to outputDir) to nest generated static assets (js, css, img, fonts) under.
An example would be
assetsDir: 'assets'
which would dump files in views/assets/css, views/assets/js, etc.

Provide enviroment variables for production vue build

I would like to achieve following:
a Vue application is build with npm build,
then the /dist result is copied to some environment
in this enviroment I have some static setting file with name=value settings
the Vue application should read this setting from local folder where it is running or default to some setting
What is the best way to do this.
If you want "to inject" some settings to the bundled app so I think it can be possible only with another js file (globalConfig.js) with global object like:
window.myAppSettings = {
MY_VARIABLE: 'some_value'
}
Which will be copied somehow to your dist folder on a particular environment.
You should also prepare your app to reference that file:
Firstly, add this settings object as external lib in vue.config.js
module.exports = {
chainWebpack: config => {
config.externals({
'my-app-settings': 'myAppSettings'
})
}
}
So you can get your settings in code:
import mySettingsObject from 'my-app-settings'
//...
let myValue = mySettingsObject.MY_VARIABLE
Add reference to globalConfig.js in index.html file in the head section:
<script src="<%= BASE_URL %>globalConfig.js"></script>
Local Development
Probably you will need some default settings to be able to debug your app locally. In this case you can create localConfig.js in your public folder with some default values.
Then change your script in index.html to this:
<script src="<%= BASE_URL %><%= VUE_APP_GLOBAL_SETTINGS_VERSION %>Settings.js"></script>
Then create two files in the project root .env.local and .env.production:
// .env.local
VUE_APP_GLOBAL_SETTINGS_VERSION=local
and
// .env.production
VUE_APP_GLOBAL_SETTINGS_VERSION=global
So when you run npm run serve it will load your local config and your app will load localSettings.js.
And when it builds with npm run build it will load globalSettings.js because building uses a production mode by default.
If you created your project using Vue CLI 3 you can do like this.
Make sure your settings file is named .env and place it in your project root.
In the .env file, your variables should be prefixed with "VUE_APP_"
VUE_APP_SOMEKEY=SOME_KEY_VALUE.
Access them with process.env.*.
console.log(process.env.VUE_APP_SOMEKEY) // SOME_KEY_VALUE
Here's some more info on evironment variables in vue: Vue CLI 3 - Environment Variables and Modes
EDIT:
Sorry. I probably misunderstood your question. This solution will not work if your settings file is in the dist folder.

express js blank root page

I have simple vue js app with next express js config file
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.use(express.static('.'));
server.listen(1111);
Result of build is located in /dist folder. However my express js file is located in /
After I run it I see blank page on localhost:1111 and actually it retrieves index.html from / but, I see my app on localhost:1111/dist and it retrieves index.html from /dist
My purpose is to receive index.html from /dist when I visit localhost:1111.
I've tried to change express config to app.use(express.static('./dist')) and similar to this. But it only breaks anything (i'm not able to reach my app on localhost:1111/dist and localhost:1111/)
In general I have next project structure
/ -> express js config is here and basic index.html is here
/dist -> build result is located here (index.html + static files)
/dist/static -> static files are here
/build -> webpack config is here
The problem why app.use(express.static('dist')); didn't work was that in index.html I had link to other files like /dist/static/.. what is not correct if my root folder is dist. So, despite moderator set that webpack doesn't related to this the solution was to change webpack config for production to make build script generate links to file in /dist/index.html like /static/.. instead of /dist/static/..
And obviously I had to change
app.use(express.static('.'));
to
app.use(express.static('dist'));
As a conclusion - it make sense to check generated index.html and analyze if the paths there are correct.
Sometimes this issue may come because of, the app doesn't server from the root folder.
For example, /home/user/path-to-the-project" The app need to serve like this.
So here you need to change like below,
app.use(express.static(__dirname + '/dist'));
For more information, you check express doc. See here