Reputation: 2981
I am trying to import the contents of a JSON file in TypeScript but instead of the contents of the JSON, I get its URL.
App.tsx
import * as videosInfo from './videos-info.json'
console.log("Print");
console.log(videosInfo);
console output:
Print
http://localhost:3000/src/videos-info.json
In tsconfig.json
I use "resolveJsonModule": true
.
How can I consume the contents of the JSON and not its path?
EDIT: Here is my webpack.config.js
for reference:
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
module: {
rules: [
{
test: /\.json/,
type: 'asset/resource',
generator: {
filename: '[name][ext][query]'
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
},
output: {
filename: 'client.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
filename: 'index.html'
})
],
devServer: {
static: {
directory: path.join(__dirname, 'dist')
},
compress: true,
port: 3000
}
};
Upvotes: 2
Views: 1866
Reputation: 2981
As @T.J. Crowder
rightfully suggested the problem comes from my misunderstanding of the asset/resource
loader in Webpack 5
. According to the documentation:
asset/resource emits a separate file and exports the URL. Previously achievable by using file-loader.
My goal here is to copy videos-info.json
from /src/
into the /dist
folder when I do npm run build
, so that I can host it statically somewhere and set up an AWS Lambda to overwrite it on regular intervals. Therefore, I cannot load the JSON inside the client.bundle.js
through Webpack because the data will be hardcoded in the bundle. This note about how Webpack builds resources statically helped me understand it better: https://stackoverflow.com/a/44424933/9698467
Therefore I must use asset/resource
loader in Webpack 5 to produce a URL, which I can later load into the webpage via a React hook
for example:
const videosFile = require('./videos-info.json');
// videosFile is a URL
React.useEffect(() => {
const resp = await fetch(videosFile);
const data = await resp.json() as VideoResult;
const videos: VideoResultItem[] = data.items;
}, []);
Upvotes: 2