I'm new in Webpack (before I used Gulp) and now I want to move the existing application from Gulp to Webpack.
But I'm getting issues like Module not found: Error: Can't resolve '/src/app/index.js' in '/var/www/project' or Module not found: Error: Can't resolve '/src/styles/main.scss' in '/var/www/project' and same for every file i'm using on my enty chain.
Here is my file structures:
package.json
.env
.env.example
webpack.conf.js
src/
app/
index.js
other js/vue related files
styles/
main.scss and all related styles
public/
index.html
favicon.ico
images/
all images
and here is mine webpack.conf.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const Dotenv = require('dotenv-webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
const ENV = process.env.APP_ENV;
const isDev = ENV === 'dev'
const isProd = ENV === 'prod';
function setDevTool() {
if (isDev) {
return 'inline-source-map';
} else if (isProd) {
return 'source-map';
} else {
return 'eval-source-map';
}
}
const config = {
entry: {
'bundle.min.css': [
path.resolve(__dirname, '/src/styles/main.scss'),
],
'bundle.js': [
path.resolve(__dirname, '/src/app/index.js')
]
},
output: {
filename: '[name]',
path: path.resolve(__dirname, 'dist'),
},
devtool: setDevTool(),
module: {
rules: [
// fonts loader
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
},
// babel loader
{
test: /\.js$/,
use: 'babel-loader',
exclude: [
/node_modules/
]
},
// raw html loader
{
test: /\.html/,
loader: 'raw-loader'
},
// css loader
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
// sass loader
{
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['style-loader', 'css-loader', 'sass-loader']
})
},
// vue loader
{
test: /\.vue$/,
loader: 'vue-loader'
},
// image url inliner
{
test: /\.(jpe?g|png|gif)$/,
loader: 'url-loader',
options: {
limit: 50 * 1024
}
},
// svg url inliner
{
test: /\.svg$/,
loader: 'svg-url-loader',
options: {
limit: 50 * 1024,
noquotes: true,
}
},
// image loader
{
test: /\.(jpg|png|gif|svg)$/,
loader: 'image-webpack-loader',
enforce: 'pre'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/src/public/index.html",
inject: 'body'
}),
new Dotenv({safe: true}),
new ExtractTextPlugin("bundle.min.css"),
new VueLoaderPlugin()
],
devServer: {
contentBase: './src',
port: 7700,
}
}
if (isProd) {
config.plugins.push(
new UglifyJSPlugin(),
new CopyWebpackPlugin([{
from: __dirname + '/src/public'
}])
);
};
module.exports = config;
I do not understand why it can't find those files if for examlpe '/var/www/project//src/styles/main.scss' it mention in error is correct path?
Try to remove the initial slashes from path.resolve(). For example:
path.resolve(__dirname, '/src/styles/main.scss')
should be:
path.resolve(__dirname, 'src/styles/main.scss')
Related
I have a react app that contains 2 different applications with different stylings and images.
I am trying to exclude the images for 1 application being bundled.
The folder structure is the following:
- src
-- app
-- images
--- images_app1
--- images_app2
-- app1.js
-- app2.js
-- app1.html
-- app2.html
- webpack.config.js
Webpack config:
const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const globImporter = require('node-sass-glob-importer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// App directory
const appDirectory = fs.realpathSync(process.cwd());
// Gets absolute path of file within app directory
const resolveAppPath = relativePath => path.resolve(appDirectory, relativePath);
// Host
const host = process.env.HOST || 'localhost';
const devMode = process.env.NODE_ENV !== 'production';
// Required for babel-preset-react-app
process.env.NODE_ENV = 'development';
module.exports = {
mode: 'development',
entry: {
app: resolveAppPath('src/app1.js'),
polyfill: resolveAppPath('src/polyfills.js'),
vendor: resolveAppPath('src/vendor.js'),
},
output: {
path: resolveAppPath('dist'),
filename: 'js/[name].js',
publicPath: '/',
},
devServer: {
clean: true,
port: 8082,
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
include: resolveAppPath('src'),
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: devMode,
sassOptions: {
importer: globImporter()
}
}
}
],
},
{
test: /\.(jpe?g|png|svg|jpg|gif)$/,
exclude: [resolveAppPath('src/images/app2')],
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
],
},
{
test: /\.(ico|xml)$/,
use: [
{
loader: 'file-loader',
},
],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'url-loader',
options: {
name: 'fonts/[name].[ext]',
},
},
],
}
],
},
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
new HtmlWebpackPlugin({
template: resolveAppPath('src/app1.html'),
filename: 'index.html',
chunks: ['polyfill', 'vendor', 'app'],
inject: true,
}),
],
}
However, I get the following errors:
ERROR in ./src/images/app2/walkthrough/walkthrough-start-image.png 1:0
Module parse failed: Unexpected character '�' (1:0)
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
(Source code omitted for this binary file)
# ./src/images/ sync .* ./app2/walkthrough/walkthrough-start-image.png
# ./src/app1.js 33:0-39
I tried to use webpack ignore plugin as well however I could not succeed exclude.
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()
]
};
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>
);
}
My first "Hello Webpack" project was going great until I started integrating purifycss-webpack. If I delete my /dist folder manually and then build, this config works. But if the /dist folder exists and CleanWebpackPlugin deletes it as its designed to do, then PurifyCSS throws this error:
clean-webpack-plugin: \dist has been removed.
purifycss-webpack\dist\index.js:52 \ if (!_fs2.default.existsSync(p))
throw new Error('Path ' + p + ' does not exist.');
Is there another way to have Webpack run PurifyCSS only AFTER all the other plugins have executed? I thought I was doing that by placing it last in the plugins array, but this feels like execution order issues to me. Here's my config:
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const globAll = require('glob-all');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const PurifyCSSPlugin = require('purifycss-webpack');
const webpack = require("webpack");
var extractPluginCSS = new ExtractTextPlugin({
filename: "app.css"
});
module.exports = {
entry: "./src/js/app.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: ["env"]
}
}
]
},
{
test: /app\.scss$/,
use: extractPluginCSS.extract({
use: [
{
loader: "css-loader",
options: {}
},
{
loader: "sass-loader",
options: {}
}
]
})
},
{
test: /\.html$/,
use: ["html-loader"]
},
{
test: /\.(jpg|png)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "img/"
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: "./src/html/index.html"
}),
new webpack.optimize.UglifyJsPlugin(),
extractPluginCSS,
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: globAll.sync([
path.join(__dirname, '/dist/*.html')
]),
// minimize: true,
verbose: true
})
]
};
I get this error in app.js:
Uncaught ReferenceError: require is not defined
Why webpack require not work? Is any additional wabpack configutarion needed to make this work?
webpack.config.js
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: ['./src/app.js', './src/styles/styles.scss'],
output: {
filename: 'dist/bundle.js'
},
resolve: {
extensions: ['.js'],
},
module: {
rules: [
{ // regular css files
test: /\.css$/,
loader: ExtractTextPlugin.extract({
loader: 'css-loader?importLoaders=1',
}),
},
{ // sass / scss loader for webpack
test: /\.(sass|scss)$/,
loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
},
{
test: /\.hbs$/,
loader: 'handlebars-loader'
}
]
},
plugins: [
new ExtractTextPlugin({ // define where to save the file
filename: 'dist/[name].bundle.css',
allChunks: true,
}),
],
};
app.js
const something = require("./something.js");