DEV Community

Cover image for How to configure Webpack 4 or 5 from scratch for a basic website

How to configure Webpack 4 or 5 from scratch for a basic website

Anton Melnyk on March 13, 2019

🌼 Introduction Hello, reader! 🐱 As you may know, configuring Webpack can be a frustrating task. Despite having good documentation, this...
Collapse
 
sibyllecodes profile image
Sibylle

You're a hero! Saved my sanity after hours of trying to get Webpack to work with Ghost CMS :-)

Collapse
 
robinnnnnn profile image
Robin

Hey Anton,

I am having one issue when I run build I am getting this error :

ERROR in ./src/sass/styles.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src!./node_modules/sass-loader/dist/cjs.js??ref--5-3!./src/sass/styles.scss)
    Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
    Error: Dart Sass version 1.25.1-test.1 is incompatible with ^1.3.0.
        at getSassImplementation (/Users/robinsmac/Desktop/OdinCode/Odin_ToDoList/node_modules/sass-loader/dist/getSassImplementation.js:40:13)
        at Object.loader (/Users/robinsmac/Desktop/OdinCode/Odin_ToDoList/node_modules/sass-loader/dist/index.js:40:61)

Enter fullscreen mode Exit fullscreen mode

Any ideas why this is happening?

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Hey Robin!

Well, it basically what it says, sass dependency probably was outdated for sass loader, since the article is 2 years old!

But no worries, I updated all dependencies in the repository (including Webpack, it works now for the latest Webpack 5!), and fixed some typos and wording in the article. You can try to check out the repo and run the code again if you still need it :)

Collapse
 
quazzzar profile image
quazZzar

Hi,
fix this one please:

{
      // Now we apply rule for images
      test: /\.(png|jpe?g|gif|svg)$/,
      use: [
             {
               // Using file-loader for these files
               loader: "file-loader",

               // In options we can set different things like format
               // and directory to save
               options: {
                 outputPath: 'fonts'
               }
             }
           ]
    }
Collapse
 
antonmelnyk profile image
Anton Melnyk

Thanks, I just noticed what was wrong! Fixed.

Collapse
 
alittlebyte profile image
Vlad

Loved this article, it's concise and up to date.
The most confusing part for me is Webpack using a .js file for an entry point, instead of an .html.
Speaking of which... there should be an HTML loader setup of some sort, so my .html content is packed into the bundle too, right?
Gonna go search the documentation for it. Cheers!

Collapse
 
antonmelnyk profile image
Anton Melnyk

Correct, there is a html plugin that will automatically create html from template and insert your JS bundle there.

Collapse
 
aga007 profile image
aga007

Hi Anton, thanks for this article, very helpful! however when I try it in the production mode I get "You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on postcss.parts/ and use them in postcss.config.js.". I installed postcss-loader, created postcss.config.js file the same as you did but it's not working. Any idea what could be the issue?

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Hi!

It's because in postcss.config.js there is a check for process.env.NODE_ENV variable. Even if you set Webpack mode to production it won't automatically change Node environment variable.

The simplest way to configure this is to install cross-env package:

$ npm install --save-dev cross-env

Then just add another npm script in package.json for production mode:

"scripts": {
  "build": "webpack --config webpack.config.js",
  "build-production": "cross-env NODE_ENV=production webpack --config webpack.config.js"
}

Now when you run npm run build-production the process.env.NODE_ENV variable will be production and postcss.config.js check is going to work:

if(process.env.NODE_ENV === 'production') {
    module.exports = {
        plugins: [
            require('autoprefixer'),
            require('cssnano')
        ]
    }
}

From Webpack documentation:

Technically, NODE_ENV is a system environment variable that Node.js exposes into running scripts. It is used by convention to determine dev-vs-prod behavior by server tools, build scripts, and client-side libraries. Contrary to expectations, process.env.NODE_ENV is not set to "production" within the build script webpack.config.js. Thus, conditionals like process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js' within webpack configurations do not work as expected.

Collapse
 
aga007 profile image
aga007

Many thanks! Now it works :)

Collapse
 
muratx10 profile image
Murat

@Anton, Big big thank you!!! You've saved my nerves 😊 I had a problem with paths where webpack puts assets after building project. Now you made it absolutely clear!!! THANK YOU BRO! Big plus to your karma 😉

Collapse
 
antonmelnyk profile image
Anton Melnyk

Thank you! Glad it helped! 😊👍

Collapse
 
rajatsingh91 profile image
rajat singh • Edited

Hey Anton ,

I am very new to JS and everything written here is clearly understandable to me , thank you for this.
though i am getting exception in build for module not found for third party java script libraries .

dev-to-uploads.s3.amazonaws.com/i/...

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Thanks, man.

It's hard to say what exactly is wrong with your build, as I can't see your gulp or Webpack config file and what you are actually doing there.

But the error message is pretty clear, you miss jquery and slick-carousel modules. Maybe you declare them globally like window.jQuery as it usual for WordPress websites, but Webpack doesn't know about them. You might need to install them via npm or expose them via expose-loader.

stackoverflow.com/questions/290801...

Check this, it might be your case

Collapse
 
rajatsingh91 profile image
rajat singh • Edited

Hi Anton,

i am using babel-loader..

this is my gulpfile

var gulp = require('gulp'),
settings = require('./settings'),
webpack = require('webpack'),
browserSync = require('browser-sync').create(),
postcss = require('gulp-postcss'),
rgba = require('postcss-hexrgba'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import'),
mixins = require('postcss-mixins'),
colorFunctions = require('postcss-color-function');

gulp.task('styles', function() {
return gulp.src(settings.themeLocation + 'css/style.css')
.pipe(postcss([cssImport, mixins, cssvars, nested, rgba, colorFunctions, autoprefixer]))
.on('error', (error) => console.log(error.toString()))
.pipe(gulp.dest(settings.themeLocation));
});

gulp.task('scripts', function(callback) {
webpack(require('./webpack.config.js'), function(err, stats) {
if (err) {
console.log(err.toString());
}
console.log(stats.toString());
callback();
});
});

gulp.task('watch', function() {
browserSync.init({
notify: false,
proxy: settings.urlToPreview,
ghostMode: false
});

gulp.watch('..//*.php', function() {
browserSync.reload();
});
gulp.watch(settings.themeLocation + 'css/
/.css', gulp.parallel('waitForStyles'));
gulp.watch([settings.themeLocation + 'js/modules/
.js', settings.themeLocation + 'js/scripts.js'], gulp.parallel('waitForScripts'));
});

gulp.task('waitForStyles', gulp.series('styles', function() {
return gulp.src(settings.themeLocation + 'style.css')
.pipe(browserSync.stream());
}))

gulp.task('waitForScripts', gulp.series('scripts', function(cb) {
browserSync.reload();
cb()
}))


*and following is my webpack configuration *

const path = require('path'),
settings = require('./settings');

module.exports = {
entry: {
App: settings.themeLocation + "js/scripts.js"
},
output: {
path: path.resolve(__dirname, settings.themeLocation + "js"),
filename: "scripts-bundled.js"
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
mode: 'development'
}

following is how i am importing the 3rd party libraries ..
import $ from 'jquery';
import slick from 'slick-carousel';

i tried to use the plugin configuration in webpack setting also but no luck.

Thread Thread
 
rajatsingh91 profile image
rajat singh • Edited

Hi Anton,

i added following line in my webpack configuration with absolute path of my node_modules and now its able to build..

resolve: {
modules: [
'__dirname','/Users/rajat.c.singhaccenture.com/Local\ Sites/cp-unique-convent-school/app/public/build-setup/node_modules'
]

Collapse
 
lauragyre profile image
Laura Gyre

Thank you, this is the only tutorial I have found that really helped me understand and get the basics of webpack working! However, in case any other beginners are reading, I want to mention that I would not have been able to get past the first section if I hadn't just come from another tutorial that told me to initialize with "npm init -y". When I tried without the -y, a bunch of confusing questions that I didn't know how to answer came up. With -y, everything worked perfectly.

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Yes, a good point! That's one way to do it.

You can just press Enter on each of those questions to accept defaults!

Glad you liked the guide :)

Collapse
 
mona_calibani_002e7a7e9cf profile image
Mons

Hi Anton,

I wrote the exact same code and I have an error that I can't fixe..

"Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleParseError: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See webpack.js.org/concepts#loaders"

Do you have an idea of what's happened ?

Thank for your article !!

Collapse
 
samayo profile image
samayo • Edited

Simply amazing guide Anton!! Really, very simple and understandable. I already followed you before I even finished reading.

Just one pro-tip. In English, if you are talking about objects (non-living things) use "it" instead of "he/she". Simply, use "it" when talking about everything except humans or animals. So, webpack == "it"

Cheers!

Collapse
 
antonmelnyk profile image
Anton Melnyk

Glad you enjoyed the guide!

Simply, use "it" when talking about everything except humans or animals.

Oh, sorry! Good to know! I'm not a native speaker, but I try to improve my English constantly, so thanks 😊

Collapse
 
andfinally profile image
And Finally • Edited

Great tutorial, thanks Anton! It would really help if you could let us see your full webpack.config.js though. I'm getting a weird error TypeError: this.getOptions is not a function from sass-loader. I'm pretty sure it's because something's in the wrong place in my config.

My problem was due to package versions. On npm install I was getting these warnings:

npm WARN postcss-loader@5.0.0 requires a peer of webpack@^5.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN sass-loader@11.0.0 requires a peer of webpack@^5.0.0 but none is installed. You must install peer dependencies yourself.
Enter fullscreen mode Exit fullscreen mode

Installing webpack 5.0.0 made them go away and got the build running correctly.

 npm install --save-dev "webpack@^5.0.0"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
herquiloidehele profile image
Herquiloide Hele

Good post. Thanks

Collapse
 
samtomashi profile image
Sam Tomashi

great stuff!

remember to install webpack globally and use webpack-dev-server too for more convenience using npm install webpack webpack-cli webpack-dev-server -g

Collapse
 
gaurav_soni1 profile image
gaurav soni

Great post , if you guys are interested in a more video based course do checkout my course on Udemy, it covers the basics and goes to the advanced section such as micro frontends
udemy.com/course/webpack-5-ninja-b...

Collapse
 
chrisjskinner profile image
Chris Skinner

Very nice and well documented!

Collapse
 
smallville1998 profile image
John Ifemezuo .A

this tutorial is super amazing, thanks for the help.

Collapse
 
tanyak1601 profile image
tanyak1601

Спасибо, это лучшее что я нашла по webpack для новичков

Collapse
 
raphiree profile image
raphiree

Incredibly helpful Anton, I really appreciate the step-by-step explanation of why we're adding lines.

Collapse
 
chrisachard profile image
Chris Achard

Thanks for the post - Webpack can be super tricky to setup, and this is a great step-by-step tutorial for it. Thanks!

Collapse
 
obrienk10 profile image
Karl O'Brien

This was great - very useful, thanks.

Collapse
 
muratx10 profile image
Murat • Edited

I haven't read the article yet, just title of it....but I guess today it will save my nerves for setting up Webpack 😊 I have troubles with images/fonts in dev/prod modes. Thanks a lot in advance!

Collapse
 
wptechprodigy profile image
Waheed Afolabi

Thanks Anton for the clear and lucid guide. You just saved my day.

Collapse
 
robinnnnnn profile image
Robin

Hey Anton,

I love the explanation, great work. I am having one issue though when I run the
$ npm run build,
the bundle.css file isn't created in my dist folder.

Any ideas?

Collapse
 
consciousness_dev profile image
Ario Setiawan

Love this tutorial! It so easy :D
I hope there is another tutorial Webpack 4 & Bootstrap setup XD

Collapse
 
zugmaschine profile image
Pullmachine

Great Tutorial.
İ use the webpack-dev-server-plugin.
Please, can anyone Show, what I have to write, to config, that the dev-server-plugin serves a
phpfile(index. php) instead of Index. ktml?

Collapse
 
feliperybas profile image
Felipe Rybakovas

This was fabulous!

Collapse
 
elrond25 profile image
Carlos Araya

Single bundle solutions are harder to fit within a performance budget, particularly for large applications

Collapse
 
krzysztofwelc profile image
Krzysztof Welc

cool, but where should I place index.html file in project?

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Right in the root, where webpack.config.js is placed.

Collapse
 
rustfoot profile image
Kyle P

This was really useful in helping me wrap my head around a basic setup for webpack. Thanks so much for putting this article out!

Collapse
 
wordsofdefiance profile image
David Accomazzo

Is there a way to set up webpack with a watcher, so that anytime you edit a scss or js file it automatically runs the sass/babel/postcss tasks?

Collapse
 
antonmelnyk profile image
Anton Melnyk • Edited

Of course there is, for example you can use webpack-dev-server for that. But that is way out of scope of this guide and this is more advanced stuff.

webpack.js.org/concepts/hot-module...

Collapse
 
ding profile image
Ting Ting

How to configure multi-page application with webpack4?

Collapse
 
aminak profile image
Amin Akmali

I wanna use and compile pug to html with webpack 5 . would you help me to config that?