Prevent JSON file from becoming part of chunk.js/app.js when I build my vue app - vue.js

I have a JSON file that I included in my vue app. But the problem is that when I build the app, the JSON file disappears and becomes a part from a js file.
How can I keep it as a JSON file after build, since I want to manipulate it?

If you are using Vue CLI 3, you can place your static files in public directory and reference them by absolute paths.
For more information you can visit the CLI documents.
Update
Place your JSON file in public directory
Import axios or any similar tools you use for AJAX calls.
You need a .env file in your project root. And store your base url in BASE_URL variable. (Read More!)
Add a data property containing your base URL:
data() {
return {
baseUrl: process.env.BASE_URL,
}
},
And then you can access you JSON value with an ajax call:
axios.get(this.baseUrl + 'test.json').then(response => {
console.log(response);
})

I think you want to configure the externals option.

Related

Fetch data from local JSON file with Nuxt Pinia

Is it possible to fetch a local .json. file using fetch()? I originally used the import method but the site's data doesn't get updated unless the page gets reloaded.
I tried doing this but it's not working:
stores/characters.ts
export const useCharactersStore = defineStore("characters", {
state: () => ({
characters: [],
}),
getters: {
getCharacters: (state) => {
return state.characters;
},
},
actions: {
fetchCharacters() {
fetch("../data.json")
.then((response) => response.json())
.then((data) => {
this.characters = data.characters;
});
},
},
});
app.vue
import { useCharactersStore } from "~/stores/characters";
const store = useCharactersStore();
onMounted(() => {
store.fetchCharacters();
});
Any help would be appreciated.
maybe a bit late but I have encountered the same problem migration from Nuxt 2 to Nuxt 3.
I'm certainly no expert on this, so if anyone finds a better way or if I'm totally wrong please let me know !
Whenever you import a json file in vue code they are imported as a module, that get's embedded within the code compilation on build (Vue Docs). Tu use json as a external file you need to place your json within the /public directory and use axios or fetch to load the file with a lifecyle hook.
This could be mounted() for options api or beforeMount()/onMounted() with composition api.
However some important annotations for this method.
If the json file you want to use in your app is not reactive, i.e. won't change, you should place this in the static folder of the nuxt app.
In your example you fetch '../data/...', this would imply the server knows the domain to look for. It can't call the route like this, you would have to give the full url if you put your json file in the static folder.
Set the baseUrl in the of your nuxt.config.ts, see docs for specifications.
Then you can access the static folder with your .env variables
--> $fe
Then in you data script you can access your json file
async getJson(some parameters){
const data = $fetch('your domain with the runtimeConfig composable').then((data)=>{ console.log(data)});
Sidenote you can also load the file from the server-side using fs.readFile
read more about this in this awesome post here

How can I ensure this vue application doesn't exceed the recommended 244kb in production?

There is a vue file here that imports a json file that has about 9000 records in it.
How do I ensure that the json file is not compiled with the component?
A simple way would be to put the JSON file you want to access in the public folder (Webpack won't process anything in this folder). Then use AJAX to call the file at run time.
This will avoid expanding your app bundle, but Vue may still show that you're including a large resource. This approach would also allow you to split the data into smaller chunks and load them as needed in your app.
Here's an example, assuming the data file is located at /public/data/mydata.json. Also, I suggest using Axios to make the AJAX stuff easier.
import axios from 'axios'
export default {
name: 'Vue Component',
created() {
this.fetchData();
},
methods: {
fetchData() {
axios.get('/data/mydata.json').then(response => {
// do something with response.data
})
}
}
}
Use dynamic import. Like this:
import(
/* webpackChunkName: "my_json" */
'./src/my.json'
).then(({default: myJson}) => {
// do whatever you like here~
console.log(myJson);
});
doc:
https://webpack.js.org/guides/code-splitting/#dynamic-imports
If the json file is too big, you will still get the size exceeding warning.
But the json file would load async, so it would not cause any performance problem.
🔽 🔽 🔽 if you really don't want to see the warning, try this: 🔽 🔽 🔽
Use copy-webpack-plugin,it can copy your json file to dist folder, which means you can fire a XHR get request to load the json file, like this axios.get('/my.json').
By doing this, you can get the FULL control about when to load the file.

how to access xml static resource in react native

I want to add a static xml asset to my react native project and access it just like accessing images.
I added
resolver: {
assetExts: ['png', 'xml'],
},
to metro.config.js and const asset = require('asset.xml') returns me a number. But how to get the file content from this number?
Below code gets me a URI in development mode that I can use axios to fetch it, but in release mode it only returns a filename like asset, how to read it in release mode?
Image.resolveAssetSource(asset).uri;
You can use expo-asset to get the localUri:
const [{ localUri }] = await Asset.loadAsync(require('path/to/your/asset.xml'))
Then you can use expo-file-system to get the contents of the file as string:
const xmlString = FileSystem.readAsStringAsync(localUri)
Then you can convert the xml string to a JS object with a package like fast-xml-parser.
In order for this to work, you should edit your metro.config.js just as you mentioned above, namely: assetExts array should contain xml.
Also, if you use Typescript, you should add a declaration file, like xml.d.ts with the content of:
declare module '*.xml' {
const moduleId: number; // the react-native import reference
export default moduleId;
}
and that declaration file should be in a folder, that's added to typeRoots property in tsconfig.json.
Just a quick reminder: you can use this solution without Expo in a bare react-native app, you just have to install unimodules, which is described in the above links.
Good luck! :)

Add static text in html generated by nuxt

I have a nuxt app, and I want to create static html files for all my routes.
I generate my static files successfully.
So after run nuxt generate I have e.g. these folders with index.html inside:
buy/apple
buy/orange
buy/banana
My problem is here.
In my page I want to have this:
<h1>Buy {{fruit_name}}</h1>
and I want fruit_name be static on generated html file.
so e.g. for apple in final html I want to have:
<h1>Buy apple</h1>
for now apple is empty.
So what should I do to set this variable base on route name on generate time.
assume my routes are constant and I set my routes on nuxt.config.js
UPDATE
I try to change them in generated html files, but when I serve it changes not applied. Why?
I found solution:
When generating routes pass payload to related page:
{
route: `/fruit/${name}`,
payload: { fruitName: name }
},
and set data in asyncData hook:
async asyncData({ params, error, payload }) {
if (payload) {
return {
name: payload.name
}
}
}
and here a data set in component and can access it through component and it is static and set in generated html file for each route.

how do I open a file when Vue.js router path is /apple-app-site-association

I have a Vuejs project with the following folder structure
https://ibb.co/dpGPBNw
I would like to open the file named apple-app-site-association inside the path static/config which is outside my src folder, using vue-router routing.
That means when a user redirects to https://myDomain/apple-app-site-association, the file static/config/apple-app-site-association should open up instead of routing to a component (which is how vue-router usually handles routing)
I require this for something called as deep-linking, i.e when a user navigates to https://myDomain/apple-app-site-association, the mobile app should open instead of navigating to the browser.
I do not know exactly how deep-linking works, but my mobile-app developer instructed that this is how we can achieve it.
As far as I know, Vue router, which is in charge of all routes within application, can't redirect you outside of it. You can, however, create component, that will only contain this specific document, and then you can point specific route to this component.
Regarding deep-linking it only means you get straight at some point within your app and not to the home page.
This is how I solved:
Option 1:
Create a component that will open the file:
<template>
<div></div>
</template>
<script>
export default {
name: 'WellKnown',
props: {
file: String
},
mounted () {
window.open(this.file)
}
}
</script>
Create a route in your vue router that uses that component and passes the file url:
{
path: '/.well-known/apple-app-site-association',
component: WellKnown,
props: {
file: '<URL to your file>'
}
}
Deploy your app, whenever you go to <yourapp>/.well-known/apple-app-site-association you should be promp to download that file (the expected result)
Thats it.
Notes:
The component created in step 1 receives the file URL as prop. That prop can be passed from the route definition it self.
The file can be hosted whereever you want, what's important is that can be accesable from the url you defined in the router.
Option 2:
This one is actually more straight forward. Place the file in your public directory:
And for the apple-app-site-association file change the content-type header to application/pkcs7-mime. More info here
Hope this makes sense and help others.