Как переместить json файл и js файл который использует информацию из него в сборочную папку webpack и при этом сохранить рабочим путь
Собираю проект на webpack. Структура такая:
app - выход webpack
src(вход) > js > primer.js | prediction.json
в primer.js есть следующий код:
const data = require(./prediction.json);
const people = Object.entries(data).map(([key, value]) => ({
name: key,
percent: Math.round(value * 100)
}));
export default people;
Нужно чтоб при сборке проекта в папке app > js > (тут) генерировались primer.js (это я сделал) и prediction.json с учетом того, что данные в этом json файле именно уже в собранном проекте (паке app) в дальнейшем будут изменятся и primer.js должен динамично их использовать.
Но я столкнулся с проблемой, когда я пытаюсь перенести json файл в папку сборки используя и
new CopyWebpackPlugin({
patterns: [
{ from: 'js/prediction.json', to: 'js' },
{ from: 'js/prediction.json', to: 'js', noErrorOnMissing: true },
],
}),
и
{
test: /\.json$/,
use: ['file-loader'],
type: 'javascript/auto',
},
даже такие вариации
// {
// test: /\.json$/,
// use: {
// loader: 'file-loader',
// options: {
// outputPath: 'js',
// name: 'prediction.json',
// },
// },
// type: 'javascript/auto',
// },
а так же меняю различные способы подключения json к primer.js, даже пробовал создать отдельную переменную под путь, но всегда получаю один из этих вариантов:
- если использовать только CopyWebpackPlugin то во время сборки проекта js файл который формируется меняется так, что он перестает считывать то, что находится в json в данный момент, вместо этого он просто передает ту строку, которая находится в json в момент сборки
- ошибка типа: Module build failed (from ../node_modules/json-loader/index.js): SyntaxError: Unexpected token / in JSON at position 0 at JSON.parse ()
- Critical dependency: the request of a dependency is an expression
Подскажите как решить данный вопрос, может кто-то сталкивался с подобным. Заранее спасибо.
содержимое конфига вебпак:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require ('css-minimizer-webpack-plugin');
const TerserWebpackPlugin = require ('terser-webpack-plugin');
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const isDev = process.env.NODE_ENV === 'development';
const isProd = !isDev;
const filename = (ext) => isDev ? `[name].${ext}` : `[name].[contenthash].${ext}`
const optimization = () => {
const confObj = {
splitChunks: {
chunks: 'all'
}
};
if (isProd) {
confObj.minimizer = [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeViewBox: false,
addAttributesToSVGElement: {
params: {
attributes: [
{ xmlns: "http://www.w3.org/2000/svg" },
],
},
},
},
},
},
],
},
],
],
},
},
}),
];
}
return(confObj);
};
module.exports = {
context: path.resolve(__dirname, 'src'),
mode: 'development',
entry: {
index: './js/main.js',
upload: './js/upload.js',
result: './js/result.js'
},
output: {
path: path.resolve(__dirname, 'app'),
filename: `./js/${filename('js')}`
},
devServer: {
static: {
directory: path.resolve(__dirname, 'app'),
},
historyApiFallback: true,
open: 'firefox',
compress: true,
port: 3000,
},
optimization: optimization(),
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html',
chunks: ['index'],
minify: {
collapseWhitespace: isProd
}
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/upload.html'),
filename: 'upload.html',
chunks: ['upload'],
minify: {
collapseWhitespace: isProd
}
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/result.html'),
filename: 'result.html',
chunks: ['result'],
minify: {
collapseWhitespace: isProd
}
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: `./css/${filename('css')}`
}),
// new CopyWebpackPlugin({
// patterns: [
// { from: 'js/prediction.json', to: 'js' },
// ],
// })
// new CopyWebpackPlugin({
// patterns: [
// { from: 'js/prediction.json', to: 'js' },
// { from: 'js/prediction.json', to: 'js', noErrorOnMissing: true },
// ],
// }),
],
devtool: isProd ? false : 'source-map',
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader'
},
{
test: /\.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
{
test: /\.(?:gif|png|jpg|jpeg|svg)$/i,
type: 'asset/resource',
generator: {
filename: `./img/${filename('[ext]')}`
}
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [{loader: 'babel-loader'}]
},
// {
// test: /\.json$/,
// use: {
// loader: 'file-loader',
// options: {
// outputPath: 'js', // Путь в папке сборки
// name: 'prediction.json', // Имя сохраняемого файла
// },
// },
// type: 'javascript/auto',
// },
// {
// test: /jsonPath\.js$/,
// use: ['json-loader'],
// },
// {
// test: /\.json$/,
// use: ['file-loader'], // Используйте file-loader для копирования JSON-файлов
// type: 'javascript/auto',
// },
// },
// {
// test: /\.json$/,
// use: 'json-loader'
// }
]
}
}
Ответы (1 шт):
У вас в файле "webpack.config.js" закомментирована часть кода.
Напишите так:
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: 'src/js/prediction.json', to: 'js' }
]
})
],
module: {
rules: [
{
test: /\.json$/,
use: 'json-loader',
type: 'javascript/auto'
}
]
}
А файле primer.js:
import data from './prediction.json';
const people = Object.entries(data).map(([key, value]) => ({
name: key,
percent: Math.round(value * 100)
}));
export default people;
Теперь при сборке проекта, плагин copy-webpack-plugin скопирует файл prediction.json из папки src/js в папку app/js, сохраняя путь. Затем, с помощью загрузчика json-loader, JSON файл будет корректно загружен в коде primer.js.