Multiple entry points with Snowpack - snowpack

I'm looking to switch from Webpack to Snowpack for a development environment. But I have multiple entry points set up in Webpack and I haven't been able to find an example of how to do this in Snowpack. It seems that Snowpack is meant to be used with a true SPA that has only one HTML page and one entry point Javascript file.
Each HTML page on the site (20 altogether) has its own index.js that is the starting point for that page and is independent from the other pages on the site. How would this work in Snowpack?
I found some discussions on Github about multiple entry points, but reading through the comments I wasn't able to determine if this is supported or not. If it isn't supported, would I need to run Snowpack for each index.js? Or is there another fast development tool that would work in this use case?

If you check the config documentation, you will see the mount option is an object, meaning you mount multiple directories. If you have multiple top level modules in a mounted directory, you will get multiple entry points.
For example, following configuration takes any module from src folder and outputs it to dist folder in your build directory:
mount: {
src: { url: '/dist' },
},
Say you have src/index.tsx and src/module.tsx files, you will get dist/index.js and dist/module.js files in your output directory.
I just tested and it works.

Related

Where to install 3rd party scripts in Nuxt?

Im trying to upload static files(images and js) from "static" folder. And it works fine for index file and base route localhost:8000/, but if I go to the next route localhost:8000/reviews/master001 then static files disappears and I receive by route localhost:8000/reviews/js. And there is two things, first is how to remove prefix "reviews"?
I tried to use in nuxt.config.js
static: {
prefix: false
}
by documentation, but it does not work. Tried to use paths in nuxt.config like "../js", "#/static/js", "/js" - this one works for index file.
Also there are no any static files after I go through the router-link such it in nuxt documentation for path localhost:8000/reviews/master001.
Here there are.
And here there no any files.
As explained in the comments above, images should be in assets and static is only aimed for specific use cases, like exposing a publicly accessible .pdf file.
If you want to install and use jQuery properly into your Nuxt project, you can follow my answer here: https://stackoverflow.com/a/68414170/8816585
If you want to load a specific script and cannot do it in a more cleaner way (with NPM), you can also follow the instructions there: https://stackoverflow.com/a/67535277/8816585
Use this as a last resort tho and be aware that it will increase bundle size and loading time.

NuxtJS SPA mode (ssr false) still generates HTML for each vue file in the pages folder

The Nuxt documentation (latest) states that for SPA you need to set ssr: false in nuxt.config.js. Also, every vue file in the pages folder is added to the router configuration, so you don't have to do this yourself. This is both correct and works perfectly, but there is something I really don't understand.
When I run npm run build (nuxt-ts build), it builds the production output of the project and puts in the dist folder (default). I was surprised to see that even though I configured it to be a SPA, it still generates HTML files for each vue file in the pages folder.
It happens with newly generated projects using npx nuxt-create-app as well.
What I'd expect is that it only generates one HTML file (which is index) when ssr is set to false and when I want a static app, I would use npm run generate or set target to 'static' to create HTML files per route.
Nuxt documentation also states this for the target property:
https://nuxtjs.org/docs/2.x/get-started/commands#target-server-default-value (builds output to dist)
https://nuxtjs.org/docs/2.x/get-started/commands#target-static (generates HTML per route)
All I have in my config is ssr set to false, so it should not generate static files (HTML) per page.
What am I missing here, or am I misunderstanding how this works?
Thanks in advance!
Remember that in a static setup, your visitors may arrive at your site via any of your page routes— not just index.html.
For example, they may access https://www.your-app.com/contact-us. If you do not have a contact-us.html file available, and you don’t have a server configured to handle this request (as is the case with universal mode), you’re gonna end up with a 404.
What happens in static mode is contact-us.html is served, which contains the minimum javascript necessary to hydrate your nuxt app, then SPA mode kicks in— giving you client-side navigation.

Images uploaded in Vue.js production mode not showing

I am a bit new to Vue.js. I am doing a social media application that allows users to upload and share images with others. I store my images in src/assets folder during development. However, when I build the project, all images are put in the dist folder. Therefore, what can I do to enable users to still upload images on production? Do I create the assets directory in the dist folder?
I have since tried different ways, including storing images on the backend. In dooing this, I reference the backend path relatively, using, for example, ../../../backend/public/assets..., and it works on development. However, when I build, the images that existed in the backend directory at the time of building are visible, however, whenever I try uploading more on production to the ../../../backend/public/assets... directory, they are uploaded successfully but are not visible (that is on production). I get an error that Cannot find module './image_name.image_extension'.
What am I doing wrong?
I have seen similar questions like this but there was no answer.
You must set your public path and change your way!!
first step to do is creating vue.config.js in your root directory, if you want to know more details, read this: https://cli.vuejs.org/config/
for example, I define prefix path for my files:
module.exports = {
publicPath:
process.env.NODE_ENV === "production" ? "/" : "/",
};
remember, It's better if you use "#" to define your paths.
for example, if you want to load a image which located in src/assets/files/img/myImage.png, you can use #/assets/files/img/myImage.png in template section for binding or script section of your .vue files!
It always help you to find correct path of your files.
and finally your way is not standard because "src/assets/..." will used for compiled scripts and styles and also your files which you want to use on your UI layout like static images. so you have to use "public/assets/..." directory to save your file, then you will see everything is going well for you.
if you have a more question or stuck solving this problem again, I'm here to fix your issues.

Vue-cli 3 Environment Variables all undefined

I've tried all of the solutions out there but none seem to work for me. I just want to store some values in a .env file within my Vue app but simply trying to log process.env returns an empty object from within the component.
My .env file
VUE_APP_URL={api url}
VUE_APP_TOKEN={token}
My plan was to set these environment variables to data properties but it always returns undefined. If I do console.log(process.env.NODE_ENV) from webpack.config.js it will show that I'm in development but if I tried doing the same from within the component like
mounted() {
this.$nextTick(() => {
console.log(process.env.VUE_APP_URL);
})
}
It just returns undefined.
A few tips for people who land here:
Make sure your .env files are in the project root folder (and not in say src/)
Variable names should start with VUE_APP_ if to be statically embedded into the client bundle
Restart the dev server or build your project for changes to take effect
If you are migrating from a webpack based solution make sure that you replace : (from JSON config) with = (dotenv format). Easy to miss
Make sure you've saved any changes to your .env files.
In old Vue versions environment variables were defined in e.g. config/dev.env.js instead of the .env files in root
I figured it out - I had to install dotenv-webpack and initialize it in webpack.config.js which is odd because none of the docs stated that I needed to do so.
Install dotenv-webpack and configure the vue.config.js file as follows.
npm install dotenv-webpack --save-dev
Add this to your config file:
const Dotenv = require('dotenv-webpack');
module.exports = {
configureWebpack: {
plugins: [
new Dotenv()
]
}
}
In your .env file make sure you add VUE_APP_ before your variables like this:
VUE_APP_VAR1=example
VUE_APP_VAR2=value
Now you can access these variables in your Vue application:
console.log(process.env.VUE_APP_VAR1); // "example"
console.log(process.env.VUE_APP_VAR2); // "value"
Here some links for reference:
https://www.npmjs.com/package/dotenv-webpack
https://cli.vuejs.org/guide/webpack.html
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
so I use
VUE_APP_API_URL (this doesn't work)
then I change it to
VUE_APP_APIURL (this works)
hope it helps
If your vue-cli version is higher than 3.x and you put your .env files in root directory like said in comments. Than you can access your environmental variables from components (like this process.env.VUE_APP_YOUR_VARIABLE).
As said in vue-cli docs
Only variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. You can access
them in your application code: console.log(process.env.VUE_APP_SECRET)
I put my .env file in the root directory and appended each variable with VUE_APP_.
To demonstrate this, for example, if the variable you want to use is API_BASE_URL
In your .env file, you put the variable as VUE_APP_API_BASE_URL=baseurl/api/v1
To access it in your files, you do process.env.VUE_APP_API_BASE_URL.
CAVEAT:
Never put any sensitive information you don't want anybody to see, on your front-end. The most common thing you won't want anybody to see (as regards web development) is your API Key. There are real consequences to doing this. This is one such example of someone who has been burned exposing API keys to the public.
However, even if you put your sensitive data in a .env file and add the .env file to a .gitignore file (hence not pushing it to a Git repository hosting service e.g Github, BitBucket, Gitlab etc.), your data is still not safe on the front-end. It's only safe when this is done on back-end code as it will be hosted on a server.
In the front-end, anyone who is determined enough can find your sensitive information. All your information is available on a browser and all that person needs to do is to open the dev tools and check the Sources tab, and BOOM all your sensitive information is laid bare.
Environment variables on the front-end are only useful when you want one reference point for NON-SENSITIVE information, such as a BASE URL, as seen in the example above. A BASE URL can change during the course of development and you won't want to change all references in the application folder manually. It is tedious plus you may miss a few, which would lead to errors.
If you want to avoid exposing your API keys and other sensitive information you may require on the front-end, take a look at this article.
This is what worked for me. I previously created my .env.development and .env.production files in the root folder by manually by right-clicking in the Exploer in VS Code and adding a new file. This kept giving me undefined.
I deleted the files and first installed npm install touch-cli -g
Once installed, i added the environment files as such touch .env.production and touch .env.productionand itworks. So I think there's a difference between how these env files are generated.
NOTE: I do not have webpack installed. Just using the vue cli to build
VS Code ExplorerChrome Developer Tools
IF you are using VITE, use VITE_ in stead of VUE_APP
Vue CLI dotenv usage suffers the inability to provide the .env variables other than prefixed with VUE_APP_. This is OK but this is far not enough to satisfy any even little serious web project that wants to conveniently and securely manage its (sometimes huge) list of variables for different environments.
Here is the solution that makes use of .env variables as convenient as on backends with dotenv.
With this solution you could access your MY_EXTERNAL_API_KEY from your .env[.environment] file in your code like this const key = process.env.MY_EXTERNAL_API_KEY.
It provides:
The convenience of using non-prefixed with VUE_APP_ variables' names and use .env variable expansion feature (use ${VARNAME} kind of variables)
The necessary security: your variables are neither available at browser console with console.log(pocess.env.MYVAR) at run time nor are explorable via text search by their names from .env files within the built application's JS bundle.
You can still use original Vue CLI solution along;
For this use dotenv-webpack plugin in your vue.config.js as follows:
const Dotenv = require('dotenv-webpack');
const envPath = function() {
return (!process.env.NODE_ENV || (process.env.NODE_ENV === 'development')) ?
'./.env' :
`./.env.${process.env.NODE_ENV}`;
}
const dotenvArgs = {
expand: true,
path: envPath()
};
module.exports = {
//... some other config here
configureWebpack: {
plugins: [
new Dotenv(dotenvArgs)
]
}
};
Here:
expand: true allows for ${MYVAR} variables expansion;
path: envPath() allows to define custom .env file name depending on your Vue CLI project environments, and the path depending on you project structure;
There are other useful dotenv-webpack options you could use.
I believe this solution is good enough to fully satisfy most frequent use cases.
NB: Remember as you pass your secret variables set via .env into HTTP requests from your front-end (e.g. an API key in a call to some external API) they are visible to any one who knows where to look. To diminish security risks for this situation there are different solutions.
Just to hint you have either to:
provide only publicly open data via your application;
or authenticate your application (or parts of it) via some authentication service (login/password + JWT|sessions, external authentication providers e.g. Facebook, Google etc.);
or resort to server-generated application.
But this is the whole separate subject.
if you are cominng from VUE-cli-2 or you just cloned/installed an old vuejs project and you can't find .env file, this article explains what you have to do to set your .env variables as they environment files are probably located in config/dev.env.js (Note: this is peculiar to Vue-cli-2 files)
Here is also a solution and a detailed explanation for Vue-cli-3 .env related issue
What worked for me was changing from .env to .env.local. Haven't investigated WHY but I checked an old project and saw that I had a .env.local instead and did same for this project that would not pick the values from .env irrespective of whether vars where prefixed with VUE_APP and it worked.
It seems environment variables are not accessible in child Vue components. Best to declare them globally in main.js with Vue.prototype.env = process.env;
I know that this question was asked about vue-cli 3, which generates code for Vue 2. But it is the top result if you google for "vue3 does not embed env" and similar queries, so I assume that a lot of people end up here when having trouble with process.env variables being undefined in their Vue 3 app.
So this is an answer about how to fix your Vue 3 env issues.
This is what causes the confusion
If you google for env problems with vue, you end up in the vue-cli docs. But vue-cli was replaced by create-vue in Vue 3. There is a alert box at the top of the page that tells you this, but you've probably missed it.
If you did not miss it and followed one of the two links in the box, you ended up in the Vue 3 tooling guide or in the create-vue repo. None of those resources mention env variables. But you learn that create-vue is based on Vite.
If you follow that lead and google for "vite env", you end up in the vite documentation, where you finally find the answer:
env variables have to be prefixed with VITE_ to be compiled into the app (as opposed to VUE_APP_ in vue 2)
env variables will be available in import.meta.env in your app (as opposed to process.env in vue 2)
The latter one is what took me the longest to figure out.
This is how you need to do it
in an .env file in your project root:
VITE_MY_ENV_VAR=foo
The docs will also tell you about the different naming patterns for .env files in Vite. Very useful information if you work with different environments!
in your app:
const my_env_var = import.meta.env.VITE_MY_ENV_VAR
I hope this saves someone the time for figuring this out.
It might also help: make sure your .env files are in lowercase letters because in Linux it won't work even if it is working in windows
The answer provided here helped me out. I'm using Laravel with an odd setup for Vue 2.x. The project is also using Laravel Mix. Here's the solution:
Inside of your .env file, which is a sibling of package.json:
MY_ENVIRONMENT_VARIABLE=my_value
Inside of webpack.mix.js:
const { mix } = require('laravel-mix');
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.EnvironmentPlugin (
['MY_ENVIRONMENT_VARIABLE']
)
]
};
});
Afterwards, an npm run dev or npx mix should allow you to use these variables.
Credit: Thorsten Lünborg

export and maintain vue application

I have developed a vue application and did run npm run build
After that I uploaded the content in the dist file to my webpage but it returned a blank page.
Since I did this for testing I uploaded it to a folder in my public_html/mypage.com/vueapplication To get all the paths right I added a vue.config.js with this content:
// vue.config.js
module.exports = {
publicPath: '/vueapplication/'
}
The application now works but I wounder however:
how do I best publish/upload the application to my site? Just by simply dragging the content inte the right folder?
how can I best maintain my site? Do I need to build again and upload, overwriting my files when everytime I make an update on my site?
And what is the difference between build and deploy your application?
Drag and dropping your code should work. But as your app grows you may want to look into automating this. For instance if you use an S3 bucket you can use the aws cli to automate the upload.
Yes, you should overwrite your deploy folder(s). You need to also take care of deploying different binary files, that have the same name. An example is if you have a global css file (main.css for instance). The file will probably change content between deployments, but keep the same name. Browsers may cache the file so users that downloaded older versions of the file will not use the new one. There are different techniques to handle this, but if you use webpack, it uses cache busting techniques and you should be fine.
Build is the process of transforming source code into an artifact(s). Exactly what this means differs from language to language, platform to platform. In the vuejs world this usually means a couple of js files, a couple of css files and some assets.
Deploying means taking the output of a build and making it available to your users. Again this differs from project to project. In the vuejs world this usually means taking the artifacts from the build and uploading them to an http enabled web server.