The setting I am referencing is shown in the snippet bellow
{
"compilerOptions": {
"resolveJsonModule": true,
}
}
I don't really understand why TS language engineers would add a flag for "resolveJsonModule"? Either an environment supports resolving JSON as module via an import statement (or require() method), or the environment doesn't. Why bother with the extra complexity?
Context
Historically, Node has included a specialized JSON loader (unrelated to ECMA standards) to allow importing JSON data only in CommonJS mode.
Standardized importing of anything at all (ES modules) is only a relatively recent phenomenon in ECMAScript. Importing text files containing valid JSON, parsed as native JS data ("importing JSON") is described in a proposal that is still only in stage 3.
However, there has been recent movement in regard to implementation of the above mentioned proposal:
V8 implemented it in June (Chrome 91+)
TypeScipt v4.5.0 implemented it in November
Deno v1.17.0 implemented it in December
Node LTS v16.14.0 implemented it last Tuesday (behind a CLI flag --experimental-json-modules)
TypeScript
TypeScript is a static type-checker, but also a compiler (technically a transpiler), and transforms your TS source code syntax into a syntax that is valid JavaScript for the runtime environment you have specified in your TSConfig. Because there are different runtime environments with different capabilities, the way that you configure the compiler affects the transformed JavaScript that is emitted. In regard to defaults, the compiler uses an algorithmic logic to determine settings. (I can't summarize that here: you honestly have to read the entire reference in order to understand it.) Because loading of JSON data has been a non-standard, specialized operation until extremely recently, it has not been a default.
Alternatives
All JS runtimes offer alternatives to an import statment for importing of textual JSON data (which can then be parsed using JSON.parse), and none of them require configuring the compiler in the ways that you asked about:
Note: the data parsed from the JSON strings imported using these methods will not participate in the "automatic" type inference capabilities of the compiler module graph because they aren't part of the compilation graph: so they'll be typed as any (or possibly unknown in an extremely strict configuration).
Browser and Deno: window.fetch
Deno: Deno.readTextFile
Node: fs.readFile
Additionally, because all JSON (JavaScript Object Notation) is valid JS, you can simply prepend the data in your JSON file with export default , and then save the file as data.js instead of data.json, and then import it as a standard module: import {default as data} from './data.js';.
Final notes about inferred types:
I prefer to audit the JSON I'm importing and use my own manually-written types (written either by myself or someone else: imported from a module/declaration file) for the data, rather than relying on the compiler's inferred types from import statements (which I have found to be too narrow on many occasions), by assigning the parsed JSON data to a new variable using a type assertion.
Related
For better or worse our codebase relies heavily on Newtonsoft.Json. There are various type converters etc. based on this framework and it is simply not worth the effort to rewrite them using some other JSON framework (if even possible).
We use appsettings.json (+ other custom files) to load settings into our applications.
Typically we used to configure this like:
configurationBuilder.AddJsonFile(pathToFile, ...);
Now, we need to use some of the converters we usually rely on when parsing regular JSON for the settings JSON as well. These are usually being automatically picked up by Newtonsoft.Json so we thought the solution would simply be to reference
Microsoft.Extensions.Configuration.NewtonsoftJson and change to:
configurationBuilder.AddNewtonwoftJsonFile(pathToFile, ...);
However this does not appear to be the case. The converters are not being invoked when we call.
var someSettings = configurationSection.Get<SomeSettings>();
If we paste the same settings into a string and manually parse it the usual Newtonsoft.Json way. This works just fine.
Our conclusion is that either we are doing something wrong (hopefully) or the "binding" part where a configuration section is transferred into actual properties on the object is not part of the Newtonsoft.Json configuration extension.
Any suggestions?
I've got a project that gets metadata from Minecraft mods, and I'm having some trouble with the Minecraft Forge's old mcmod.info format - which is a JSON format read with GSON for those that don't know.
Specifically, GSON unfortunately allows for strings to be multi-line (it allows for unescaped newlines in a string) - which Go's encoding/json doesn't allow for. See the below example from the Chisel mod to see what I mean.
[{
"credits": "AUTOMATIC_MAIDEN for the original mod,
asie for porting to 1.7.2,
and Pokenfenn/Cricket for continuing it in 1.7.
This mod uses textures from the Painterly Pack: http://painterlypack.net/."
}]
This results in an error of invalid character '\n' in string literal.
I did take a brief look at using an alternative JSON parser (the aptly-named jsonparser specifically took my eye), but without testing them all - I've been unable to determine which, if any, support what I need.
I suspect the solution to this problem will be in using an alternative JSON parser, I'm just not aware enough of the available libraries or JSON's use in Golang to make a highly informed decision.
I simply want to validate a JSON file with the proper JSON schema I have written, just to check if I did everything right. Is there a command line tool or anything else for this (I'm on Ubuntu)? Everything I found yet, are packages for several programming languages for writing validation methods in code. I just need a tool where I can specify my JSON file and my custom schema and check it. That's it...
You have a couple of options. Please have a look at json-schema validators implementations to find the one that most suits your needs.
You can use fge java json schema validator from the command line as it is explained here.
If you are comfortable with python, you can also use jsonschema python package and run it from any python console:
from jsonschema import validate
validate(json, schema)
Another popular javascript library is tv4. You can use it directly in the browser, or in node console.
var valid = tv4.validate(json, schema);
While working on scala REPL with Play Json support(play.api.libs.json), it possible to specify that all REPL output of JsValues should be automatically formatted?
e.g. By specifying another formatter via implicits
I know Json.prettyPrint does JSON pretty on Play, I was interested to know if there is a mechanism, either in play.json to specify a formatter to be used on toString, or if there is a Scala 2.10 construct I can use to automatically wrap every call with minimal or preferably no overhead to the calls.
Probably in Play 2.1+ with Scala there Json.prettyPrint should work (can't confirm now, have no any Scala project atm, but doc says that).
On the other hand, if only destination for prettifying the JSON is possibility to check it 'with your own eyes' I'd rather suggest to leave it in compressed form, and then use some browser plugin to display it in prettified version, it also validates the code, allows to fold the sections etc. ie this one: https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc
What's most important you still save your transfer as just source JSON is still compressed ;)
Could someone explain to me why in GWT you cannot convert a client/shared pojo (that implements Serializable) into a JSON object without jumping through a load of hoops like using the AutoBeanFactory (e.g GWT (Client) = How to convert Object to JSON and send to Server? ) or creating javascript overlay objects (and so extends JavaScriptObject)
GWT compiles your client objects into a javascript object, so why can't it then simply convert your javascript to JSON if you ask it to?
The GWT JSON library supplied only allows you to JSONify java objects that extend JavaScriptObject
I am obviously misunderstanding something about GWT since a GWT compiles a simple java POJO into a javascript object and in javascript you can JSON.stringify it into JSON so why not in GWT?
GWT compiles your app, it doesn't just convert it. It does take advantage of the prototype object in JavaScript to build classes as it needs, usually following your class hierarchy (and any GWT classes you use), but it makes many other changes:
Optimizations:
Tightens up types - if you refer to something as List, but it can only be an ArrayList, it rewrites the type declarations. This by itself doesnt give much, but it lets other steps do better work, such as
Making methods static - if nothing ever overrides ArrayList.add, for example, this will turn any calls it can prove are to ArrayList.add into a static call, preventing the need for dynamic dispatch, and allowing the 'this' string in the final JS to be replaces with a shorter arg name. This will prevent a JS object from having a method you expect it to have.
Inline Methods - if a method is simple enough, and is called in few enough places, the compiler might remove the method entirely, since it knows all places where it is called. This will directly affect your use case.
Removes/Inlines unreferenced fields - if you read to a field but only write it once, it will assume that the original value is a constant. If you don't read it, there is no reason to assign it. Values that the compiler can't tell will ever be used don't need to be using up space in the js and time in the browser. This also will directly affect treating gwt'd Java as JS.
After these, among others, the compiler will rename fields, arguments, and types to be as small as possible - rarely will a field or argument be longer than 1 character when this is complete, since those are most frequently used and have the smallest scope, so can be reused the most often by the compiler. This too will affect trying to treat objects as JSON.
The libraries that allow you to export GWT objects as JSON do so by making some other assumption.
JavaScriptObject (JSO) isn't a real Java object, but actually represents a JavaScript instance, so you can cast back and forth at will - the JSNI you write will emerge relatively unoptimized, as the compiler can't tell if you are trying to talk to an external library.
AutoBeans are generated to assume that they should have the ability to write out JSON, so specific methods to encode objects are written in. They will be subject to the same rules as the other Java that is compiled - code that isn't used may be removed, code that is only called one way might be tightened up or inlined.
Libraries that can export JS compile in Java details into the final executable, making it bigger, but giving you the ability to treat these Java objects like JS in some limited way.
One last point, since you are talking both about JSON and Javascript - Some normal JS isn't suitable for writing out as JSON. Date objects don't have a consistent way to serialize that is recognized by JSON. Non-tree object graphs can't be serialized:
var obj = {};
obj.prop = {};
obj.prop.obj = obj;
Autobeans come with a built in checker for these circular references, and I would hope the JSO serialization does as well.