-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to import json as a static file? #501
Comments
require, import and fs.readFileSync will all include the json file into the bundle |
Hmm, @DeMoorJasper can you clarify a bit? I just tried using |
That's the point, it resolves the json file as an object, it parses it for you. |
Sorry, I read that as use require.... import and fs.readFileSync will all include the json file into the bundle. The doesn't really help answer my question, but rather just confirms what I already know. Does that mean there is no way to import a json file as a static file rather than having it included in the bundle? |
The only way i can think of resolving json as a raw asset is to overwrite the asset type by writing a plugin |
Hmm, I wouldn't really want to overwrite an asset type. I guess what I'm looking for is a way to use parcel in development that works like the |
Why do you need to copy the JSON file instead of bundling it into your code? Just trying to understand the usecase. |
@devongovett I use a few 3rd party libraries that only support passing a path to load json files via xhr. The example I ran into today was with phaser 2 sprite atlases: game.load.atlas('items', 'assets/sprites/items.png', 'assets/sprites/items.json') It's probably not too common, but I can recall using a few other libraries that have their own preload systems that treat json assets the same as images. |
@devongovett For example, I want to lazy load some (or a lot) json data. |
@sunnylqm Fair point. require & import does most the way we wanted, except with json files, it bundles json into javascript instead of return the path map. But what we wanted is the return the path way as other files do. The reason is, we are building a loading sequence for all the assets other than javascript files, to show a loading bar to users, which will indicates the loading progress. Webpack actually offers a extended require function |
See here for some potential strategies to allowing multiple import formats: facebook/create-react-app#3722 |
you can try parcel-plugin-json or babel-plugin-inline-json-import |
Just to say this is needed if you are using something like Or do: #1080 (comment) Thanks. |
@michaeljota Change file type from |
I just try that and I does not work.
The problem now, is exactly about the json atlas files. But not quite because is a json file or not.
Having a bundler tool with zero config is great, but I guess you need to consider what are the main use cases you want to cover, and at the end, I think is real hard to cover them all. |
@michaeljota It's not so straight forward to use neither If you want to get the real path after
If you want to load any file as json format file(of course they need to be parsed correctly by
If you want to patch json data to atlas resolver, you have to understand how |
I do it that way, and this is the way I use to load things that are not a
I don't know much about |
This is not strictly answering the question, but for those of you just looking to load a PIXI sprite sheet, you can bypass the PIXI loader and manually create the sprite sheet from the raw data:
|
@jedhastwell This will create an |
@michaeljota It's the same as if you'd just used the loader to load the atlas file directly from a JSON file. It will add all the textures defined in the atlas file to the TextureCache. Then you can just create sprites using the names defined in the atlas like: |
Oh! OK, OK... Will try that. Thanks you. @jedhastwell Thanks man. Really helpful. Worked as intended. Thanks again. |
To extend the point for adding static files serving/copying: I'm using some proprietary third-party library that expects me to pass URL to a static directory provided with the library. This directory contains about two hundreds of files, something that looks like this: These files are JS/CSS/HTML files, as well as images, cursors and fonts. I cannot require every single file, and even if I could it won't help as the library expects to get each of them using XHR under specific, compiled-in name. I can only change shared URL prefix. As far as I can see, in order to make this setup work under Parcel, I need two things:
Please let me know if this can be accomplished in some other way. |
@skozin Just try |
As I understand, the problem is not loading those files, but letting those files load themselves. |
@shunia, the problem is not loading those files, as @michaeljota correctly said. I don't need them; the library I'm using needs them, and it wants to load them using XHR, and expects them to have pre-defined file names which are compiled into the library code. It does this to avoid loading unnecessary stuff: the total size of all these files is something like 20Mb, and most of them are not needed in every case. I suppose that |
Just wanted to add my use case: loading Geojson files (that is, spatial data containing location information). It doesn't make any sense to me to bundle that data. It would make the bundle enormous, and presumably all the loading would have to happen before the site displayed. (In my case I'm using Really surprised there isn't a simple solution like, "anything in /static doesn't get bundled" and can be loaded using XHR. |
+1 for the aforementioned three.js use cases here. Looking into migrating a WebGL project away from Webpack, but we need to be able to load object files and other WebGL assets via XHR. |
@shunia thanks! we'll try this :) |
Just started using Parcel recently (❤️it, btw) and ran into this issue recently myself. My use case was much simpler... I just wanted to include (copy) some static HTML files over to the I eventually just used an anchor in my
... which is incredibly hacky. I don't want to link from the page, but this is how I got them to be included without bundling them. Like @stevage mentioned, it'd be great if there was a simple |
@shunia, parcel-plugin-json-url-loader works bad when you need to refer json from html. <link rel="manifest" href="~/../static/manifest.json"> |
@NotIntMan |
My use case is I want a separate JSON configuration file that my administrator can tweak in the deployment. (I would love to use continuous integration, but I have to fit my solution into the problem's constraints.) |
How do I get Parcel to resolve a path like this and add the JSON to the output? xhr. open('GET', '../data/some.json', true); This flat out doesn’t do anything expected. For some reason, the result is not even a 404 error, but my HTML entry point file. This is extremely confusing. Weird workaround:
xhr. open('GET', require('../data/some.json'), true); |
Just wanted to leave my use case here. I'm developing a Chrome Extension and it is required in the final build folder to have a |
A use case for bundling JSON as a string and deferring parsing to runtime: it can actually be faster. The JSON grammar is faster to parse than JS. |
For all of you who just need to copy a file from a static directory to the bundled one, I would recommend giving a shot at parcel-plugin-static-files-copy. |
Seems like everybody is adding their usage case here, so why not? :) I am beginning to use the amazing react-i18next library and it's ability to asynchronously load new translations and add them to the application context. It supports plugins for xhr and fetch, but in both cases I get the HTML entry point file. Both plugins try to fetch: I don't even have to tell i18next where to get the files from as long as I put them in the default path it looks for translation files (public/locales/...). I also have no say on how it's getting the translations, neither would I want to. That's the beauty of the plugin. That being said, I can't even use the "weird workaround" with require mentioned above. There will be dozens of use cases for stuff like this. Can Parcel be awesome at this too? |
With Parcel 2 alpha 3 and this parcelrc {
"extends": "@parcel/config-default",
"transforms": {
"url:*": ["@parcel/transformer-raw"]
}
} you can import files which will then be copied to the dist folder: import file from "url:./static.json"
fetch(file)... |
use import { Application, Sprite, Loader, Spritesheet } from 'pixi.js';
import myjosn from './assets/treasureHunter.json';
import mypng from './assets/treasureHunter.png';
const loader = Loader.shared;
const app = new Application({
width: 300,
height: 300,
antialias: true,
transparent: false,
resolution: 1,
backgroundColor: 0x1d9ce0
});
document.body.appendChild(app.view);
loader
.add('mypng', mypng)
.load(setup)
function setup() {
const texture = loader.resources["mypng"].texture.baseTexture;
const sheet = new Spritesheet(texture, myjosn);
sheet.parse((textures) => {
const treasure = new Sprite(textures["treasure.png"]);
treasure.position.set(100, 100);
app.stage.addChild(treasure);
});
} |
This worked for me, thanks @shunia ! 🥇 |
So I am using Parcel... love it and don't want to go back to webpack. I have been dealing with this and my use case is for Pixi.js with spritesheets. I can't get it to work without a static file name. (I have done d3 maps before and see how it would be the same problem) I also have cases where I want the JSON loaded as an object, so I can't just over-ride JSON imports. In the end I was able to get PIXI to work with a data url. I suppose if it was a huge file I'd have to learn about Parcel's Code Splitting for lazy loading. import sprite_png from "../sprites/sprites.png";
import sprite_data from "../sprites/sprites.json";
sprite_data.meta.image = sprite_png;
let data64 = btoa(JSON.stringify(sprite_data));
let dataURL = `data:text/json;base64,${data64}`;
const theGame = new PIXI.Application({
resizeTo: window
});
theGame.loader.add("sprites", dataURL); |
For playcanvas users struggling with .json model imports, you can rename model .json files to .modeljson and add a custom loader: (app.loader.getHandler("model") as pc.ModelHandler).addParser(
new (pc as any).JsonModelParser(app.graphicsDevice),
function (url, data) {
return pc.path.getExtension(url) === ".modeljson";
}
); |
Just leaving my workaround here for Phaser 3 + Parcel for the simple case where there's one spritesheet, in case it helps anyone. ls -1 assets
other.png
spritesheet.json
spritesheet.png
import Phaser from 'phaser'
// @ts-ignore
import images from '../assets/*.png'
import spritesheetJson from "../assets/spritesheet.json"
export default class BootScene extends Phaser.Scene {
constructor () {
super({ key: 'boot' })
}
preload () {
console.table(images)
this.load.image('other', images.other)
spritesheetJson.textures[0].image = images.spritesheet.substring(1)
this.load.multiatlas('mysprites', spritesheetJson)
}
update () {
this.scene.start('next-scene')
}
}
Elsewhere: this.add.sprite(0, 0, 'mysprites', 'the-key') |
It seems |
A few days ago, I tried importing a I then discovered this thread and saw that different from my expectation, many people want to lazy load *.json files to optimize for their user experience. Here's a few of those:
However, the problem is that I think the From parcel, what I'd expect when inputting To import JSON with |
Thanks for this! The only tweak I would suggest is to use const urlToFetchForJson = new URL("url:../content/messages-compiled/zh-CN.json", import.meta.url); |
I'm using a few libraries that want to load json from a path. Is there a way to serve static files (similar to what the
copy-webpack-plugin
does)?The text was updated successfully, but these errors were encountered: