Webpack collecting wrong src path - reactjs

I think that the whole problem is in configuring the webpack, the images are successfully collected in the folder when building, but when importing ...
Somewhere I found a solution indicating the public path, but somehow it did not grow together
webpack.config.js
const path = require('path');
// const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: { main: './src/lib/index.js' },
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: "umd",
library: "#compassplus/ui-mobicash"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: true,
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
],
include: /\.module\.css$/,
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
],
exclude: /\.module\.css$/,
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[hash:12].[ext]',
outputPath: 'images/',
esModule: false,
},
},
],
},
]
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: 'index.css',
}),
// new HtmlWebpackPlugin({
// template: './public/index.html',
// }),
// new webpack.ProvidePlugin({
// "React": "react",
// }),
],
externals: {
react: 'react',
},
resolve: {
extensions: ['.js', '.jsx'],
},
}
Путь указанный в src / Path in the src:
src="images/809853c38dec.svg"
In the React component, I hook it up via import and pass it as an object
import imgLight from './img/theme-light.svg';
<img src={img} alt='Картинка' className={style.img}></img>

Solved the problem using url-loader:
{
loader: "url-loader",
options: {
limit: 8192,
name: "static/media/[name].[hash:8].[ext]"
},
}

Related

Webpack 5, Server-Side rendering, and FOUC

I'm upgrading an existing web site from Webpack 3 to Webpack 5.
The site uses server side rendering for the first load, the client side routing for any in-site navigation. All this worked fine with Webpack 3, but after migrating to Webpack 5 it looks like some of the styles are being applied via javascript and that's creating a FOUC during the first load (after that, in-site navigation works fine and looks correct). As a test, I turned off javascript in my browser; the old site loads fine and looks correct, but the upgraded site does not. It feels like I need style-loader in the server config somewhere, but when that's added, I get a "Cannot GET /" when trying to load the site. Any help is appreciated.
Server-side config
require('dotenv').config({ silent: true });
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const includePaths = [path.resolve(__dirname, 'stylesheets')];
module.exports = {
bail: true,
entry: {
main: './src/entry-server',
},
output: {
path: path.join(__dirname, 'build', 'prerender'),
filename: '[name].js',
publicPath: '/bundle/',
libraryTarget: 'commonjs2',
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
PRERENDER: true,
ASSETS_CDN_PREFIX: JSON.stringify(process.env.ASSETS_CDN_PREFIX || ''),
},
}),
// only load moment english locale: https://github.com/moment/moment/issues/2517
new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en)$/),
new webpack.optimize.ModuleConcatenationPlugin(),
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
use: 'babel-loader',
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
},
},
'postcss-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.svg$/,
use: `svg-inline-loader?removeTags&removingTags[]=${['defs', 'style', 'title'].join(',removingTags[]=')}`,
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.scss', '.json'],
},
target: 'node',
};
Server entry point
export default function (req, res, environmentConstants, callback) {
// ...setup
match({ routes, location: targetUrl }, (error, redirectLocation, renderProps) => {
// ...setup
fetchSomeData().then(() => renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>,
))
.then((content) => {
callback(null, {
helmet: Helmet.renderStatic(),
content,
initialState: serialize(store.getState(), { isJSON: true }),
env: serialize(someEnvConstants),
});
})
Client-side config
require('dotenv').config({ silent: true });
const AssetsPlugin = require('assets-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const webpack = require('webpack');
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const includePaths = [path.resolve(__dirname, 'stylesheets')];
// Match all routes that we want to lazy load
const lazyRouteRegex = /route\/([^/]+\/?[^/]+)Route.jsx$/;
module.exports = {
bail: true,
entry: {
main: './src/entry-client',
vendor: [
'react',
'react-dom',
'react-router',
'redux',
'react-redux',
'xmldom',
],
},
output: {
path: path.join(__dirname, 'build', 'public', '[fullhash]'),
filename: '[name].js',
chunkFilename: '[id].chunk.js',
publicPath: `${process.env.ASSETS_CDN_PREFIX || ''}/build/public/[fullhash]/`,
},
plugins: [
// only load moment english locale: https://github.com/moment/moment/issues/2517
new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en)$/),
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
PRERENDER: false,
ASSETS_CDN_PREFIX: JSON.stringify(process.env.ASSETS_CDN_PREFIX || ''),
},
}),
new AssetsPlugin(),
new CleanPlugin([path.join(__dirname, 'build', 'public')]),
new CompressionPlugin(),
// new BundleAnalyzerPlugin(),
],
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
exclude: lazyRouteRegex,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: lazyRouteRegex,
include: path.resolve(__dirname, 'src'),
use: [
{
loader: 'bundle-loader',
options: {
lazy: true,
},
},
{
loader: 'babel-loader',
},
],
},
{
test: /swiper.*\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.s?css$/,
exclude: /swiper.*\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.svg$/,
use: `svg-inline-loader?removeTags&removingTags[]=${['defs', 'style', 'title'].join(',removingTags[]=')}`,
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.scss', '.json'],
},
target: 'web',
};

Webpack Error - You may need an appropriate loader to handle this file type,

I was trying to add webpack config in my react project, but i am facing issue as when i run the project , i get an error which says -
ERROR in ./src/index.js 14:2
Module parse failed: Unexpected token (14:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| ReactDOM.render(
> <React.StrictMode>
| <App/>
| </React.StrictMode>,
here below is my configuration for webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: path.join(__dirname, "src", "index.js"),
output: {
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
filename: "./index.html",
}),
new MiniCssExtractPlugin(),
],
resolve: {
extensions: [".js", ".jsx"],
},
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader, // instead of style-loader
"css-loader",
],
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: ["file-loader"],
},
{
test: /\.svg$/,
use: ["file-loader"],
},
],
},
};
Your configuration has 2 module keys. They conflict with each other. Merging them should resolve your issue:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: path.join(__dirname, "src", "index.js"),
output: {
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
filename: "./index.html",
}),
new MiniCssExtractPlugin(),
],
resolve: {
extensions: [".js", ".jsx"],
},
module: {
rules: [
{
test: /\.?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader, // instead of style-loader
"css-loader",
],
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: ["file-loader"],
},
{
test: /\.svg$/,
use: ["file-loader"],
},
],
},
};

Webpack Dev Server (Uncaught SyntaxError: Unexpected token '<' )

Building TS/SASS with Webpack works fine, running this through VSCode Live Server plugin renders the index.html perfectly to the app folder.
Running webpack-dev-server with it looking at the same app folder does not. The page opens but there is a Javascript error Uncaught SyntaxError: Unexpected token '<'
And the page does not render the JS/CSS.
webpack.config.js
// Imports
var path = require("path");
// Plugins
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// Exports
module.exports = {
mode: 'development',
entry: './src/main.ts',
devtool: "inline-source-map",
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
output: {
filename: 'main.min.js',
path: path.resolve(__dirname, 'app')
},
devServer: {
open: 'http://localhost',
port: 80,
publicPath: path.resolve(__dirname, 'app'),
hot: true
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
]
}
tsconfig.json
{
"compilerOptions": {
"sourceMap": true
}
}
main.ts
console.log('Main.ts has loaded')
import './styles/main.scss'
Any help with this would be appreciated, I'm losing my mind lol.
My issue was with syntax in the webpack.config.js file.
I was neglecting to insert a comma at the end of the last entry in every object and array, believing it not to be necessary.
Here is a working config:
// Imports
var path = require("path");
// Plugins
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// Exports
module.exports = {
mode: 'development',
entry: './src/main.ts',
devtool: "inline-source-map",
output: {
filename: 'main.min.js',
path: path.resolve(__dirname, 'app'),
},
devServer: {
open: 'http://localhost',
port: 80,
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true },
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
]
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader",
]
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
]
}

electron-webpack-react error "Module parse failed: Unexpected character '#'"

I'm using Electron, Webpack and React on this project. When I try to build the project, I end up with this error:
Module parse failed: Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type.
#keyframes
The error always points to a specific .css file that is inside a node_modules folder, and the error occurs at this point:
#keyframes activeSwitchCircleAnimation {
from {
left: 0;
} to {
left: 14px; }
}
#keyframes deactiveSwitchCircleAnimation {
from {
left: 14px;
} to {
left: 0; }
}
I've already looked through a bunch of "unexpected character '#'" error questions, and most of them point towards errors occuring at .sass or .scss files, which is not the case here.
This is the webpack config file:
const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BabiliPlugin = require('babili-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const defaultInclude = path.resolve(__dirname, 'src')
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
include: defaultInclude
},
{
test: /(\.scss|\.sass)$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
],
include: defaultInclude
},
{
test: /\.jsx?$/,
use: [{ loader: 'babel-loader' }],
include: defaultInclude
},
{
test: /\.(jpe?g|png|gif)$/,
use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
}
]
},
target: 'electron-renderer',
plugins: [
new HtmlWebpackPlugin(),
new MiniCssExtractPlugin({
filename: 'bundle.css',
chunkFilename: '[id].css'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new BabiliPlugin()
],
stats: {
colors: true,
children: false,
chunks: false,
modules: false
}
}
Try to remove the include: defaultInclude and then put a entry point. Your webpack.config file should be like this:
const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BabiliPlugin = require('babili-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const defaultInclude = path.resolve(__dirname, 'src')
module.exports = {
entry: defaultInclude,
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
{
test: /(\.scss|\.sass)$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
},
{
test: /\.jsx?$/,
use: [{ loader: 'babel-loader' }]
},
{
test: /\.(jpe?g|png|gif)$/,
use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }]
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }]
}
]
},
target: 'electron-renderer',
plugins: [
new HtmlWebpackPlugin(),
new MiniCssExtractPlugin({
filename: 'bundle.css',
chunkFilename: '[id].css'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new BabiliPlugin()
],
stats: {
colors: true,
children: false,
chunks: false,
modules: false
}
}

Webpack - "css-loader/locals" miss matched for server.build and client.build

I setup a webpack config to build server.build and client.build, but they both producing different css/locals.
webpack.server.js
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const serverConfig = {
name: 'server',
target: 'node',
externals: [nodeExternals()],
entry: [
__dirname+'/index.js'
],
output: {
path: path.join(__dirname, '/.build'),
filename: 'server.build.js',
publicPath: '.build/',
libraryTarget: 'commonjs2'
},
module: {
loaders: [
{
test:/\.(?:js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(?:css|less)$/,
use: "css-loader/locals?import=1&modules=1&localIdentName=[name]__[local]__[hash:base64:7]",
exclude: /\.(eot|woff|woff2|ttf|svg)(\?[\s\S]+)?$/
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?[\s\S]+)?$/,
loader: 'url-loader?limit=1000&name=./fonts/[name].[ext]?[hash:base64:5]#icomoon',
}
]
},
resolve: {
extensions: ['.jsx', '.js', '.json','.less']
}
};
module.exports = serverConfig;
webpack.client.js
const webpack = require('webpack');
const path = require('path');
const context = path.resolve(__dirname, 'src');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const config = {
name:"client",
context,
entry: __dirname+'/src/app.js',
output: {
path: __dirname+"/.build/assets",
filename: 'bundle.js'
},
devtool: "source-map",
module: {
rules: [
{
test:/\.(?:js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(?:css|less)$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader?module',
options: {
sourceMap: true,
importLoader: true,
localIdentName:'[name]__[local]__[hash:base64:7]'
}
},
{
loader: 'less-loader',
options: {
sourceMap: true,
importLoader: true,
}
}
],
fallback: 'style-loader',
}),
exclude: /\.(eot|woff|woff2|ttf|svg)(\?[\s\S]+)?$/
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?[\s\S]+)?$/,
loader: 'url-loader?limit=1000&name=./fonts/[name].[ext]?[hash:base64:5]#icomoon',
}
]
},
plugins: [
new ExtractTextPlugin({
filename: 'bundle.css',
allChunks: true,
}),
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true),
NODE_ENV: JSON.stringify("production")
}
}),
],
resolve: {
extensions: ['.jsx', '.js', '.json']
}
};
module.exports = config;
Ex: server.build.js -> style__cont__2KTI-wF
bundle.js/bundle.css (client) -> style__cont__58B3ts_
I am really stuck at this point, i am new to react and there is no perfect approach to import css server side.

Resources