My Angular app is configured with a JSON file. I was loading it via an HTTP GET, but recently decided to include it directly by adding JSON support to TypeScript with a Definition file:
declare module "*.json" {
const value: any;
export default value;
}
And then importing it where needed:
import * as config from '../config.json';
This works great; config
is the JSON object itself.
The problem is that I'm bundling with Webpack and I want the JSON file to be in the package, but not bundled with anything else, that is, config.json
should be its own file in the package, rather than being bundled with other files.
I tried doing this with file-loader and move-file-loader:
module: {
rules: [
// ...
{
test: /\.json$/,
loader: 'file-loader?name=[name].json'
}
// OR
{
test: /\.json$/,
loader: "move-file-loader?name=[name].json!json-loader"
}
// ...
]
}
This prevents the JSON file from being bundled and places it where I want it in the package, but it also makes config
become the relative path to the JSON file, i.e., "./config.json"
, rather than the JSON object itself.
Any thoughts on why this might be?
Apparently file-loader emits a path to where the file was loaded, rather than the file contents itself. So
making
config
into a string containing a path to the file is the correct behavior.As far as move-file-loader is concerned, since I'm using it with json-loader, the contents of the "moved" file is actually a TypeScript module definition, and it seems to still be loading a bundled version of the file rather than the "copied" version.
These insights lead me to the following solution: First of all, we'll copy JSON files using file-loader in the Webpack config:
Then we'll import the file path emitted by file-loader using TypeScript's require syntax
This import method doesn't require the JSON definition file I mention in my question.
Lastly, we can load the file from its file-loader path via an HTTP GET:
where
config
is the parsed contents of the JSON file.I won't mark this as the answer right away in case someone knows how to get this working without HTTP.