404 not found ( webpack image ) - javascript

How can I import an image using this web pack config?
I get the following error in the console after I build the app using yarn build. How can I import the image to the dashboard file from the assets/public folder? (please see image). Thanks in advance.
this the webpack config file.
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const extractCSS = new ExtractTextPlugin('[name].fonts.css');
const extractSCSS = new ExtractTextPlugin('[name].styles.css');
const BUILD_DIR = path.resolve(__dirname, 'build');
const SRC_DIR = path.resolve(__dirname, 'src');
console.log('BUILD_DIR', BUILD_DIR);
console.log('SRC_DIR', SRC_DIR);
module.exports = (env = {}) => {
return {
entry: {
index: [SRC_DIR + '/index.js']
},
output: {
path: BUILD_DIR,
filename: '[name].bundle.js',
},
// watch: true,
devtool: env.prod ? 'source-map' : 'cheap-module-eval-source-map',
devServer: {
contentBase: BUILD_DIR,
// port: 9001,
compress: true,
hot: true,
open: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: ['react', 'env']
}
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(scss)$/,
use: ['css-hot-loader'].concat(extractSCSS.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {alias: {'../img': '../public/img'}}
},
{
loader: 'sass-loader'
}
]
}))
},
{
test: /\.css$/,
use: extractCSS.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
{
test: /\.(png|jpg|jpeg|gif|ico)$/,
use: [
{
// loader: 'url-loader'
loader: 'file-loader',
options: {
name: './img/[name].[hash].[ext]'
}
}
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader',
options: {
name: './fonts/[name].[hash].[ext]'
}
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
new webpack.NamedModulesPlugin(),
extractCSS,
extractSCSS,
new HtmlWebpackPlugin(
{
inject: true,
template: './public/index.html'
}
),
new CopyWebpackPlugin([
{from: './public/img', to: 'img'}
],
{copyUnmodified: false}
)
]
}
};
Please see images below.
What Am I missing here?
Thanks in advance.

first of all , you should import your image like :
import MyImage from '../relative/path/to/your/image'
then use it like:
function App() {
return (
<div className="App">
<img src={MyImage} alt='any kind of description'>
</div>
);
}

Related

React Webpack proces.env.PUBLIC_URL is undefined

In my React app, I have added console in src/index.js for process.env as below;
proces.env.PUBLIC_URL // undefined
proces.env.NODE_ENV // "development"
I am not sure why proces.env.PUBLIC_URL is coming as undefined. Anything specific I need to check in my app. I have the webpack config below.
config/webpack.dev.js
const merge = require('webpack-merge');
const path = require('path');
const webpack = require('webpack');
const common = require('./webpack.common');
const srcDirectory = path.resolve(__dirname, '../src');
module.exports = merge(common, {
entry: {
main: ['react-hot-loader/patch', path.join(srcDirectory, 'index.js')]
},
resolve: {
alias: {
}
},
output: {
filename: '[name].bundle.js'
},
mode: 'development',
devtool: 'eval-source-map',
module: {
rules: [
{
test: /\.(js|.ts|tsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
devServer: {
contentBase: 'src',
hot: true,
port: 3000,
historyApiFallback: {
disableDotRule: true
},
stats: 'minimal',
overlay: true,
proxy: {
'/api/**': {
target: {
port: 8080
},
secure: false
},
'/actuator/**': {
target: {
port: 8080
},
secure: false
}
}
},
plugins: [new webpack.HotModuleReplacementPlugin()]
});
Also below is config/webpack.common.js
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const srcDirectory = path.resolve(__dirname, '../src');
const srcDirectory1 = path.resolve(__dirname, '../src/public');
const distDirectory = path.resolve(__dirname, '../dist');
module.exports = {
entry: {
main: ['whatwg-fetch', 'raf/polyfill']
},
resolve: {
modules: [srcDirectory, 'node_modules'],
extensions: ['.ts', '.tsx', '.js', '.json', '.html', '.scss', '.css']
},
output: {
path: distDirectory,
publicPath: '/'
},
module: {
rules: [
{
test: /\.(js|.ts|tsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.txt$/,
exclude: /node_modules/,
use: 'raw-loader'
},
{
test: /\.(png|jpg|jpeg|svg|gif|woff|woff2|ttf|eot|ico)(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
}
]
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: path.join(srcDirectory, 'images'), to: 'images' }
]
}),
new HtmlWebpackPlugin({ template: path.join(srcDirectory, 'index.html') })
]
};
You need to use webpack EnvironmentPlugin.
plugins: [
// ...
new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']),
]

Optimize bundle.js file size

Below is the webpack config code and it's size is around 6.2 MB. In production mode it looks more time load the signin page url and from second time onwards it looks good , the problem with first time and need suggestion to reduce the bundle.js file size
webpack.base.js
module.exports = {
//Running babel to every file
module: {
rules: [
{
test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: [
'react',
'stage-0',
['env', { targets: { browsers: ['last 2 versions'] } }]
]
}
}, {
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.less$/,
use:[
{
loader: "style-loader"
},
{
loader: 'css-loader'
},
{
loader: "less-loader"
}
]
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg|otf)(\?[a-z0-9=.]+)?$/,
loader: 'url-loader?limit=100000'
}
]
}//end module
}
webpack.client.js:
const config = {
entry: './src/client/client.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public')
}
};
module.exports = merge(baseConfig, config)
webpack.server.js:
const server_config = {
//letting webapck know that this bundle is created for node server.
target: 'node',
entry: './src/server/server.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build')
},
externals: [webpackNodeExternals()],
node:{
__dirname:false
}
};
module.exports = merge(baseConfig, server_config);
Here is how I optimize webpack. You can view my full config here
First you need to run webpack production mode when you want to build in production
webpack -p --mode=production
Below is minial config
const path = require("path");
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const WebpackShellPlugin = require('webpack-shell-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({ // minify js file
cache: true,
parallel: true,
sourceMap: false,
extractComments: 'all',
uglifyOptions: {
compress: true,
output: null
}
}),
new OptimizeCSSAssetsPlugin({ // minify css
cssProcessorOptions: {
safe: true,
discardComments: {
removeAll: true,
},
},
})
]
},
plugins: [
new CompressionPlugin({ // gzip js and css
test: /\.(js|css)/
}),
new UglifyJsPlugin(), // uglify js
new WebpackShellPlugin({
onBuildStart: ['echo "Starting postcss command"'],
onBuildEnd: ['postcss --dir wwwroot/dist wwwroot/dist/*.css'] // uglify css using postcss
})
],
module: {
rules: [{
test: /\.scss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
minimize: true,
sourceMap: true
}
},
{
loader: "sass-loader"
}
]
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: ["babel-loader", "eslint-loader"]
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: "file-loader"
},
{
test: /\.(woff|ttf|otf|eot|woff2|svg)$/i,
loader: "file-loader"
}
]
}
};

Need help injecting assets into a compiled index.html file

I'm trying to replace Gulp with WebPAck. I have this WebPack configuration that compiles a Nunjucks template and bundles js code and css code.
Instead of bundling, I'm trying to configure webpack to inject the vendor assets into the index.html header and body.
I looked into a few webpack plugins but it appears none of the work correctly. This is what I have now :
The nunjucks compilation breaks and the individual vendor assets dont get injected.
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const NunjucksWebpackPlugin = require('nunjucks-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const nunjuckspages = require('./nunjuckspages');
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = env => {
const devMode = !env || !env.production;
return {
mode: devMode ? 'development' : 'production',
entry: {
main: './src/index.js',
typescript_demo: './src/typescript_demo.ts',
vendor: './src/vendor.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'assets/js/[name].js',
library: 'MainModule',
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader'},
{ loader: 'postcss-loader', options: { sourceMap: true } },
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
]
},
{
test: /\.ts(x?)$/,
enforce: 'pre',
exclude: /node_modules/,
use: [
{
loader: 'tslint-loader',
options: { /* Loader options go here */ }
}
]
},
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
query: {
presets: [
'#babel/preset-env'
]
}
},
{
loader: 'ts-loader'
}
]
},
{
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [
'#babel/preset-env'
]
}
},
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: '/assets/fonts/'
}
}]
}
]
},
stats: {
colors: true
},
devtool: 'source-map',
plugins: [
new NunjucksWebpackPlugin({
templates: nunjuckspages
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name].css'
}),
/// new StyleLintPlugin(),
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
server: { baseDir: ['dist'] }
}),
new ExtraWatchWebpackPlugin({
dirs: ['templates']
}),
new CopyWebpackPlugin([
// copyUmodified is true because of https://github.com/webpack-contrib/copy-webpack-plugin/pull/360
{ from: 'assets/**/*', to: '.' },
{ from: 'img/*', to: './img' },
], { copyUnmodified: true }),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
inject: true,
hash: true,
publicPath: '/',
title: 'TEST1',
template: 'templates/_layouts/layout.html',
showErrors: true
}),
]
};
};

webpack 4 gives background: url([object Module]) as bg image

I'm having issues with setting up web-pack 4 and svg-sprite-loader to render svg icons as background images. I was following these instructions from official docs for svg-sprite-loader (https://github.com/kisenka/svg-sprite-loader/tree/master/examples/extract-mode).
I have successfully managed to create sprite.svg file in my dist folder and use it as reference for my use tags inside of html. However, i was also trying to use svg icons from my src/images/icons folder for a background image like this:
background: url('../images/icons/upload_icon.svg') 10% 50% no-repeat;
when doing this, webpack compiles correctly, but creates this in dist css file:
background: url([object Module]) 10% 50% no-repeat;
Any help would be great.
here is my webpack config file:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
sourceMap: true
}
}
},
{
// scss configuration
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
{
// html configuration
test: /\.html$/,
use: {
loader: "html-loader"
}
},
{
// images configuration
test: /\.(jpg|jpeg|gif|png|woff|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]"
}
}
]
},
{
test: /\.svg$/,
use: [
{
loader: "svg-sprite-loader",
options: {
extract: true,
spriteFilename: "sprite.svg"
}
}
]
}
]
},
plugins: [
// all plugins used for compiling by webpack
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "Style Guide",
template: path.resolve(__dirname, "src", "index.html")
}),
new MiniCssExtractPlugin({
filename: "app.css"
}),
new SpriteLoaderPlugin()
]
};
Adding esModule: false to the file-loader options did the trick for me.
{
test: /\.(jpg|png|gif|svg)$/,
use: {
loader: 'file-loader',
options: {
name: "[name].[ext]",
outputPath: "img",
esModule: false
}
},
You have to pass esModule: false for svg-sprite-loader options.
By the way (it is not related to esModule): With MiniCssExtractPlugin you can not to extract svg sprite. I've faced this problem one hour ago..
After a few hours, I have managed to make this thing to work, thanks to #WimmDeveloper for pointing me in right direction. Main change from prior webpack config file is that I have added esModule: false in svg-sprite-loader options and replaced MiniCssExtractPlugin with extract-text-webpack-plugin. Mind you that this solution is not ideal since this webpack plugin is deprecated.
here is my full webpack config file:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
sourceMap: true
}
}
},
{
test: /\.(s*)css$/,
use: ExtractTextPlugin.extract({
use: ["css-loader", "postcss-loader", "sass-loader"]
})
},
{
// html configuration
test: /\.html$/,
use: {
loader: "html-loader"
}
},
{
test: /\.svg$/,
use: [
{
loader: "svg-sprite-loader",
options: {
esModule: false,
extract: true,
spriteFilename: "sprite.svg"
}
}
]
},
{
// files configuration
test: /\.(jpg|jpeg|gif|png|woff|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]"
}
}
]
}
]
},
plugins: [
// all plugins used for compiling by webpack
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "Style Guide",
template: path.resolve(__dirname, "src", "index.html")
}),
new ExtractTextPlugin({ filename: "app.css" }),
new SpriteLoaderPlugin()
]
};

Webpack - devtool: source-map for CSS and eval-source-map for JS?

If I use devtool: 'source-map' it works great with CSS:
But, my JavaScript variable names are no fun:
So, if I use devtool: eval-source-maps. Life is great - debugging JS. But my CSS then points to the big bundle-css instead of the separate files:
How do I have my cake and eat it too?!
I would like to use eval-source-map for JS and source-map for CSS during the same build.
This is my webpack config (using the latest of everything as of this writing):
/* eslint no-console:"off" */
const {resolve} = require('path');
const webpack = require('webpack');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const {getIfUtils, removeEmpty} = require('webpack-config-utils');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// const OfflinePlugin = require('offline-plugin/runtime').install();
module.exports = (env) => {
const {ifProd, ifNotProd} = getIfUtils(env);
const config = {
context: resolve('src'),
entry: './js/index/index.js',
output: {
filename: 'bundle.[name].[hash].js',
path: resolve('dist'),
pathinfo: ifNotProd()
},
// devtool: 'source-map' //This works for CSS but not JS,
devtool: 'eval-source-map' //This works for JS but not css
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /(node_modules)/
},
{
test: /\.js$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {importLoaders: 1, minimize: false, sourceMap: true}
}
]
})
},
{
test: /\.html$/,
use: {
loader: 'html-loader'
}
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
query: {
name: 'static/media/files/[name].[hash:8].[ext]'
}
}, {
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader',
query: {
name: 'static/media/fonts/[name].[hash:8].[ext]'
}
},
{
test: /\.(gif|jpe?g|png)$/,
loader: 'url-loader?limit=25000',
query: {
limit: 10000,
name: 'static/media/images/[name].[hash:8].[ext]'
}
}
]
},
plugins: removeEmpty([
// ifProd(new InlineManifestWebpackPlugin()),
// ifProd(new webpack.optimize.CommonsChunkPlugin({
// names: ['manifest']
// })),
new HtmlWebpackPlugin({
template: './index.html'
// inject: 'head'
}),
// new OfflinePlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: ifProd('"production"', '"development"')
}
}),
new UglifyJSPlugin({
parallel: {
cache: true
},
sourceMap: true
}
),
new OptimizeCssAssetsPlugin({
cssProcessorOptions: {
preset: 'default',
map: {inline: false}
}
}),
new ExtractTextPlugin('styles.[name].[hash].css'),
new BundleAnalyzerPlugin(),
new ProgressBarPlugin(),
])
};
if (env.debug) {
console.log(config);
debugger // eslint-disable-line
}
return config;
};
This seems to work:
{
...webpackConfig,
devtool: false,
plugins: [
new webpack.SourceMapDevToolPlugin({
test: /\.s?[ac]ss$/
}),
new webpack.EvalSourceMapDevToolPlugin({
test: /\.(vue|[jt]sx?)$/
}),
]
}
This will give you inline-source-map for css, scss and sass and eval-source-map for vue, js, jsx, ts and tsx

Categories

Resources