I hope you're holding on in these hard times. I'm building a React app but by configuring the webpack first. So, I'm trying to use an image by importing it or referencing it in the image tag but it's not working as it should. May anyone please tell me what I'm doing worng? Thanks in advance.
My webpack file
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './index.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'index_bundle.js',
publicPath: 'dist'
},
devServer: {
inline: true,
contentBase: './dist',
port: 8080
},
performance: {
hints: 'warning',
maxEntrypointSize: 400000
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{loader: 'babel-loader'},
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(jpg|png|svg)$/,
use:{
loader: 'url-loader',
}
},
{
resolve: {
alias: {
public: path.join(__dirname, '/public')
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
}
My Navbar file
import { NavbarBrand, Navbar, NavLink } from 'reactstrap';
import logo from '../public/clean_boy';
const imageStyle={
height: "60px",
width: "100%",
padding: "20px 20px -10px 10px",
marginRight: "10px"
}
const NavBar = () => {
return (
<div>
<Navbar dark color="dark">
<NavbarBrand href="/" className="fluid"><img src={logo} style={imageStyle}/>Domestic Workers</NavbarBrand>
<NavLink href="#">Log In</NavLink>
</Navbar>
</div>
)
}
export default NavBar;
Server Error
Module not found: Error: Can't resolve '../public/clean_boy' in '/Users/moise.rwibutso/Andela - Sims Apps/Domestic-workers-system/UI/components'
# ./components/NavBar.js 3:0-39 19:9-13
# ./components/App.js
# ./index.js
ℹ 「wdm」: Failed to compile.
Related
I am trying to use scss with tailwindcss, but I cannot get webpack to transpile the tailwind code into destination site.css.
This is my scss used.
_base.scss
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
// Also tried below
#import '~tailwindcss/base.css';
#import '~tailwindcss/components.css';
#import '~tailwindcss/utilities.css';
Once transpiled, I expected the file to have bunch of tailwind styling, like below:
site.css
from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color,rgba(72,187,120,0))}.from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color,rgba(56,161,105,0))}...
But instead, I got the raw import statements below.
#tailwind base;#tailwind components;#tailwind utilities; ...
My webpack.common.js is below. Does anyone have suggestions on how to properly get the actual transpiled the css content into site.css?
webpack.common.js
'use strict';
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const SOURCE_ROOT = __dirname + '/src/main/webpack';
const resolve = {
extensions: ['.js', '.ts'],
plugins: [new TSConfigPathsPlugin({
configFile: './tsconfig.json'
})]
};
module.exports = {
resolve: resolve,
entry: {
site: SOURCE_ROOT + '/site/main.ts'
},
output: {
filename: (chunkData) => {
return chunkData.chunk.name === 'dependencies' ? 'clientlib-dependencies/[name].js' : 'clientlib-site/[name].js';
},
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
},
{
loader: 'glob-import-loader',
options: {
resolve: resolve
}
}
]
},
{
test: /\.(sc|sa|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('autoprefixer')]
}
}
},
{
loader: 'sass-loader',
},
{
loader: 'glob-import-loader',
options: {
resolve: resolve
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new ESLintPlugin({
extensions: ['js', 'ts', 'tsx']
}),
new MiniCssExtractPlugin({
filename: 'clientlib-[name]/[name].css'
}),
new CopyWebpackPlugin({
patterns: [
{ from: path.resolve(__dirname, SOURCE_ROOT + '/resources'), to: './clientlib-site/' }
]
})
],
stats: {
assetsSort: 'chunks',
builtAt: true,
children: false,
chunkGroups: true,
chunkOrigins: true,
colors: false,
errors: true,
errorDetails: true,
env: true,
modules: false,
performance: true,
providedExports: false,
source: false,
warnings: true
}
};
I have the below webpack.config. I'm trying to use relative url in my style.css to point to some svg files. The problem is the relative url is referencing a copy of the svg file which is just an export statement. Does anyone know why my webpack.config is creating these copied svg files? The files aren't working to show the image but the original svg does, so just trying to get webpack to stop creating the copied export file and just reference the actual svg. Thanks.
webpack.config.cs:
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { VueLoaderPlugin } = require("vue-loader");
const srcPath = path.resolve(__dirname, './src');
const stylePath = path.resolve(srcPath, './styles');
const bldPath = path.resolve('../SpeedRunApp/wwwroot/dist');
module.exports = {
devtool: 'source-map',
entry: {
master: path.resolve(srcPath, 'index.js'),
style: `${stylePath}/style.css`
},
mode: 'development',
watch: true,
module: {
rules: [
{
test: /\.scss$/,
use: [{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [ require('autoprefixer') ]
}
}
},
{ loader: 'sass-loader' }]
},
{
exclude: /(node_modules|bower_components)/,
include: srcPath,
test: /\.js$/,
use: [{ loader: 'babel-loader' }]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
publicPath: './fonts/',
outputPath: './fonts/',
esModule: false
}
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './images/',
publicPath: './images/',
esModule: false
}
}
]
}
]
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
chunks: 'all',
name: 'vendor',
test: /[\\/]node_modules[\\/]/
}
}
},
},
output: {
filename: '[name].min.js',
chunkFilename: '[name].min.js',
globalObject: 'this',
path: `${bldPath}`,
publicPath: '/dist/'
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [`${bldPath}/**`],
dry: false,
verbose: true,
dangerouslyAllowCleanPatternsOutsideProject: true
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].min.css'
})
]
};
style.css:
.twitter-logo {
background: url(../fonts/Twitter_Logo_WhiteOnBlue.svg)
}
.twitch-logo {
background: url(../fonts/TwitchGlitchPurple.svg)
}
.youtube-logo {
background: url(../fonts/youtube_social_square_red.svg)
}
Weird copy files webpack is creating:
Content of copied files:
I bailed on using the css and just went with importing the svgs, changed code to this and works. I put my own non-fontawesome svgs in the "font" folder in the Node.js project (webpack project) and that is correctly copying them to the static font folder in the Web MCV project.
Index.js
import '#fortawesome/fontawesome-free/js/all.min.js'
import './fonts/TwitchGlitchPurple.svg';
import './fonts/Twitter_Logo_WhiteOnBlue.svg';
import './fonts/youtube_social_square_red.svg';
import './fonts/pie-chart.svg';
Node.js (webpack) project:
Successful copy to static folder in Web.MVC project:
Code using svg:
The JS is bundling, the css is importing, but I am unable to change the font-family with this imported font. I believe it's an issue with the output config in my Webpack config but I've had no luck so far. All three formats of the font are valid, and I've used them in other projects. My "dist" folder is "public". In dev mode and after building the font does not apply.
Webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["#babel/env"] }
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'file-loader',
options: {
name: './[name].[ext]',
outputPath: "./CovesTypeface",
},
},
},
],
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "public/"),
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "/public/"),
port: 3000,
publicPath: "http://localhost:3000/",
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
index.css
#font-face{
font-family: 'CovesBold';
src: url("CovesTypeface/CovesBold.woff") format("woff"),
url("CovesTypeface/CovesBold.ttf") format("truetype"),
url("CovesTypeface/CovesBold.otf") format("opentype");
}
*{
margin: 0;
padding: 0;
font-family: 'CovesBold' !important;
}
Structure after building
I'm getting an error when I compile a React application with webpack:
You may need an appropriate loader to handle this file type. <svg
This at first seems like an easy issue to solve, but my issue is that I can't find any answers that match my use case. I'm not importing the svg from a file with the .svg extension
Instead my svgs are in React components:
Example:
import React from 'react';
import PropTypes from 'prop-types';
const SvgIcon = ({ icon: Icon, ...rest }) => (
<span>
<Icon { ...rest } />
</span>
);
Icon:
import React from 'react';
const TickIcon = (props) => (
<svg { ...props }>
<path
d="M7.8,15.5c-0.3,0-0.7-0.1-0.9-0.3l-5-4.6c-0.5-0.5-0.5-1.2,0-1.7c0.5-0.5,1.3-0.5,1.8,0l4.1,3.8l8.5-7.8 c0.5-0.5,1.3-0.5,1.8,0c0.5,0.5,0.5,1.2,0,1.7l-9.4,8.6C8.5,15.4,8.2,15.5,7.8,15.5"
/>
</svg>
);
export default TickIcon;
Used like this:
<SvgIcon icon={ TickIcon } />
I can't find any way to make this work, I've installed a ton of different svg loaders and implemented them in my webpack config but none of them are working due to there being no actual svg files?
Here is my webpack.config
const webpack = require('webpack');
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const htmlPlugin = new HtmlWebPackPlugin({
template: './source/index.html',
filename: 'index.html',
});
const buildPlugin = new webpack.DefinePlugin({
BUILD_INFO: JSON.stringify('BUILD-000'),
});
module.exports = {
entry: './source/client.js',
output: {
path: path.resolve('build'),
filename: 'bundled.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$|\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
],
},
resolve: {
alias: {
api: path.resolve(__dirname, './source/js/api'),
config: path.resolve(__dirname, './source/js/config'),
components: path.resolve(__dirname, './source/js/components'),
init: path.resolve(__dirname, './source/js/init'),
context: path.resolve(__dirname, './source/js/context'),
views: path.resolve(__dirname, './source/js/views'),
utilities: path.resolve(__dirname, './source/js/utilities'),
helpers: path.resolve(__dirname, './source/js/helpers'),
store: path.resolve(__dirname, './source/js/store'),
styles: path.resolve(__dirname, './source/styles'),
},
extensions: ['.js', '.jsx'],
},
plugins: [htmlPlugin, buildPlugin],
watchOptions: {
aggregateTimeout: 300,
poll: 1000,
},
devServer: {
disableHostCheck: true,
historyApiFallback: true,
port: 80,
hot: false,
host: '0.0.0.0',
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: true,
},
},
};
Thanks
The code you show does not import ReactDOM:
import ReactDOM from 'react-dom'
If you are using JSX syntax, that is certainly needed.
Also, there are no options stated for the babel-loader. You will at least need to state #babel/preset-react as a preset to compile it:
module: {
rules: [
{
test: /\.js$|\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
}
]
}
#babel/preset-env isn't strictly needed, but will do the downcompiling so that you do not have to worry about browser copatibility.
I have a small trial web application that I'm working on that uses the vue webpack template (https://github.com/vuejs-templates/webpack). I'm pretty new to webpack so I was assuming that I could add in to plugins a new webpack.ProvidePlugin and it would be available globally but when I do a npm run dev I get the following error:
/var/www/public/leadsStatsDashboard/liveleadstats/src/components/Hello.vue
18:17 error 'd3' is not defined no-undef
Which sounds like to me that it can't find the d3 reference. I'm no sure if there's some configuration I skipped over or what but any help would be appreciated. Here is the source for my files
Webpack.dev.conf.js:
var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var projectRoot = path.resolve(__dirname, '../')
module.exports = {
plugins: [
new webpack.ProvidePlugin({
d3: 'd3',
crossfilter: 'crossfilter',
dc: 'dc'
})
],
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
publicPath: config.build.assetsPublicPath,
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components'),
'd3': path.resolve(__dirname, '../bower_components/d3/d3.min.js'),
'crossfilter': path.resolve(__dirname, '../bower_components/crossfilter/crossfilter.min.js'),
'dc': path.resolve(__dirname, '../bower_components/dcjs/dc.js')
}
},
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
module: {
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
include: projectRoot,
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.html$/,
loader: 'vue-html'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: utils.cssLoaders()
}
}
Hello.vue
<template>
<div id="pieChartContainer">
</div>
</template>
<script>
export default {
data () {
return {
// note: changing this line won't causes changes
// with hot-reload because the reloaded component
// preserves its current state and we are modifying
// its initial state.
msg: 'Hello World! This is a test'
}
},
ready () {
console.log(d3.version)
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1 {
color: #42b983;
}
</style>
Your error isn't emitted from webpack, but from eslint.
I think the webpack part works as it should, in fact!
no-undef complains that you are using the global d3 without importing or defining it somewhere.
The good news is, that's easy to fix. Use any of the following three possibilities:
Just add the following block to your .eslintrc.js:
"globals": {
"d3": true
}
...or use eslint comments within the file that requires d3 implicitly (but that doesn't make much sense as you made it available globally and you would need to do this in every file you wish to use the global var):
/* eslint-disable no-undef */
...or you could relax the eslint rule in your .eslintrc.js config:
'rules': {
// all other rules...
'no-undef': 0
}
Additional links:
Direct link to the template's eslintrc file
The eslint 'standard' file the template extends
Further reading on eslint's no-undef rule