Hacker Noon: Webpack 3 quickstarter: Configure webpack from scratch

  • Tuesday, 13 February 2018 14:17
Why another webpack tutorial? Because, almost everything about it is confusing and I’ve suffered a lot like you. That’s why I’ve decided to write this step-by-step procedure to make a better webpack configuration with a good understanding of how webpack works. I hope that you won’t get confused and leave again in the middle of configuring webpack again.WEBPACK! Simply, it’s a module bundler, means — you can create as many modules(not only JS, but also HTML & CSS too!) while developing an app. Webpack handles the responsibility to bundle your application and give you the customized simplest version of your app (which contains only HTML, CSS & JS), even for customized output settings too.I’ve realized that it’s a habit that you have to develop through understanding the core concepts of how webpack works and then applying it on different projects/demos.After reading/following this guide, you can easily configure webpack in just 5 minutes for any kind of projects. No Headaches anymore! In the end of this article, I’m going to give you the simplest cheat-sheet to get ready for any project . Follow along with me. This blog is going to be a bigger one, so I suggest you to get some coffee around and stay with me patiently :)Or, just go to this repo and clone it to use it in your project: webpack-boilerplateBefore starting, let’s see what’s inside this write upProject Setup1.1. Create project folder and land on the project root (via terminal)1.2. Initialize a project via npm1.3. Create project directories1.4. Populating our project directories1.5. Installing webpackConfiguring package.jsonLand on the webpack config file3.1. Exporting our config object3.2. Define entry point(s)3.3. Define output point3.4. Define ContextSetting up webpack-dev-server4.1. Installing webpack-dev-server4.2. Adding command to package.json4.3. Configuring webpack-dev-serverDevtool ConfigurationLoaders and plugins6.1. Loaders6.2. PluginsSome loaders and plugins in action7.1. clean-webpack-plugin (PLUGIN)7.2. babel-loader (LOADER)7.3. html-loader (LOADER) & html-webpack-plugin (PLUGIN)7.4. css-loader (LOADER), style-loader (LOADER), sass-loader (LOADER), extract-text-webpack-plugin (PLUGIN)7.5. file-loader (LOADER)NOTE: I’m using linux in my pc. If you’re using windows, I recommend to look for the respective commands on windows. Mac users should have the same commands as mine.==========1. PROJECT SETUP==========Follow along with me to create a basic project. App architecture is important.1.1. Create project folder and land on the project root (via terminal)> mkdir project_name && cd project_name1.2. Initialize a project via npm> npm init1.3. Create project directories> mkdir src dist src/assets src/assets/media src/assets/js src/assets/scss1.4. Populating our project directories> touch webpack.config.js README.md .babelrc src/index.html src/app.js src/assets/scss/app.scssNOTE:.babelrc file is for configuring babel (which is going to transpile our ES6/ES2015 code to ES5)webpack.config.js for configuring our webpack’s responsibilitiesREADME.md for introductory text on project information1.5. Installing webpackInstall webpack locally as a dev-dependency in your project. You can install webpack globally if you want> npm i -D webpacknpm i -D webpack is just the shortcut of npm install — save-dev webpackAn awesome article about some npm tricks that is so useful for meProject hierarchy for our setup:project_architecture==================2. CONFIGURING PACKAGE.JSON==================Let’s get some extra headaches out of our brain. We need to build our project for development and for production. And, we don’t want to refresh our browser again and again while modifying our code every time. So why don’t we put some thing to watch our code? 😉If webpack is already installed globally in your machine, simply write these commands into your package.json scripts:"scripts": { "build": "webpack", "build:prod": "webpack -p", "watch": "webpack --watch"}I think, the better approach is to install updated webpack locally for every project, which will give you a complete freedom in development process.If you’re following the steps already and installed webpack locally, then, changes in package.json would be:"scripts": { "build": "./node_modules/.bin/webpack", "build:prod": "./node_modules/.bin/webpack -p", "watch": "./node_modules/.bin/webpack --watch"}You can get the idea of the directory for those script commands below. Webpack executable binary file stays in this directorywebpack_destinationNOTE: If you’re interested to know the details of webpack-cli: https://webpack.js.org/api/cliYes! You can run those commands instantly, but you’ll get some errors since ignorant webpack still doesn’t know where to start from, where to finish at and what to do 😐Let’s make some configurations into webpack.config.js to make webpack a li’l bit educated 😃======================3. LAND ON THE WEBPACK CONFIG FILE======================First thing first -Webpack simply needs to have it’s 4 core things to execute properly. 1. Entry 2. Output 3. Loaders 4. PluginsWe’re going to define entry and output for webpack in this section and watch our first bundled output.3.1. Exporting our config objectSince, we’re using node.js and webpack uses the modular pattern, we first need to export the configuration object from our webpack.config.jsmodule.exports = { // configurations here}OR, this approach:const config = { // configurations here};module.exports = config;3.2. Define entry point(s)Single entry point:The app starts executing from this point if your app is SPA(Single Page Application). We’ll define a path relative to our project rootconst config = { entry: './src/app.js',};Multiple entry points:If your app has multiple entry points (like: multi-page application), then, you have to define your entry points inside entry object with identical names. Multiple entry points are called chunks and the properties (individual entry point) of this entry object are called entryChunkName. So, let’s create it:const config = { entry: { app: './src/app.js', vendors: './src/vendors.js' }}Look carefully, our entry property is not a string anymore, it’s now a pure javascript object with different entries being the properties of it.This is so helpful when we want to separate our app entry and vendor (like: jQuery/lodash) entry into different bundles.3.3. Define output pointWebpack needs to know where to write the compiled files in the disk. That’s why we need to define output point for webpack.NOTE: while there can be multiple entry points, only ONE output configuration is specified.We define our output point as an object. This object must include these two following things at least: 1. filename (to use our output files) 2. path (an absolute path to preferred output directory)We can define path of the output point manually. But that won’t be a wise choice, since our project root’s name and location may change later. Besides, you or your collaborator may clone your projects on different pc in which case the custom absolute path won’t work there too.So, to solve this, we use node.js path module which gives us the absolute path for our project root in a more convenient way.To use node.js path module we need to import it in our config file and then use it in our output objectconst config = { output: { filename: 'bundle.js', // Output path using nodeJs path module path: path.resolve(__dirname, 'dist') }};You can use path.join or path.resolve, though both working kinda same. To not to make this article bigger and distracting, I’m going to skip the process of how node.js path.join and path.resolve works, but giving you the resources:path.resolve resource : herepath.join resource : hereNOTE: when creating multiple bundles for multiple entry points, you should use one of the following substitutions to give each bundle a unique nameUsing entry name:filename: "[name].bundle.js"Using hashes based on each chunks’ content:filename: "[chunkhash].bundle.js"For more naming options: https://webpack.js.org/configuration/output/#output-filenameBesides, you may want to give a relative path to your output file in the output.filename3.4. Define ContextContext is the base directory, an absolute path, for resolving entry points and loaders from configuration. By default the current directory is used, but it’s recommended to pass a value in your configuration. This makes your configuration independent from CWD (current working directory).const config = { context: path.resolve(__dirname, "src")};Until now, our basic setup:https://medium.com/media/280dccae782e2a8ff049c0ddd7617009/hrefNow, fire this command into your terminal to watch your first bundle:> npm run buildFor production ready bundle:> npm run build:prodFor developing with watch mode ON:> npm run watchVoila! 😎 We’ve just landed on the ground of awesomeness!Now, we’re going to add some loaders and plugins to make our actual configuration object after finishing two more setup. We’re going to use some automation that is provided by webpack.=====================4. SETTING UP WEBPACK-DEV-SERVER=====================Hey! Wasn’t that an easy setup to get our first bundle? Now we’re going to get some amazing things that’s gonna boost-up our development process and save us a lot of time. We’re going to get a real server! Yeah, webpack provides us a built-in server for development purpose, so that we’re going to see what’s going to happen while our application is ready for deployment into a real server. But we need to install this server setup first.NOTE: This should be used for development only.4.1. Installing webpack-dev-serverInstall webpack-dev-server via terminal> npm i -D webpack-dev-server4.2. Adding command to package.jsonAdd this command to scripts in package.json"dev": "./node_modules/.bin/webpack-dev-server"4.3. Configuring webpack-dev-serverThere are so many configuration options for webpack-dev-server. We’re going to look for some important ones.In your config object let’s create a new property named devServer (syntax is important)devServer: {}This object is ready to get some configuration options such as:#1 devServer.contentBaseTell the server where to serve content from. This is only necessary if you want to serve static files.NOTE: it is recommended to use an absolute path. It is also possible to serve contents from multiple directoriesFor our project architecture, we want all our static images to be stored in dist/assets/media directorycontentBase: path.resolve(__dirname, "dist/assets/media")#2 devServer.statsThis option lets you precisely control what bundle information to be displayed. To show only errors in your bundle:stats: 'errors-only'for other stats options : https://webpack.js.org/configuration/stats#3 devServer.openIf you want dev-server to open the app at the first time in our browser and just refresh afterwards while we change our codeopen: true#4 devServer.portMention which port number you want your application to be deployed in your webpack-dev-serverport: 12000#5 devServer.compressEnable gzip compression for everything servedcompress: trueFinally our devServer configuration looks like:devServer: { contentBase: path.resolve(__dirname, "./dist/assets/media"), compress: true, port: 12000, stats: 'errors-only', open: true}=================5. DEVTOOL CONFIGURATION=================This option controls if and how source maps are generated. With this feature, we know exactly where to look in order to fix/debug issues in our application. Very very useful for development purpose, but should NOT use in production.devtool: 'inline-source-map'There are much more options for devtool hereWe’ve setup most of the things that’s required for the first moment to configure webpack. Here’s the updated snippet of what we’ve done so far..https://medium.com/media/7197c1dbe63bafe46652cf63a7af1879/hrefAnd our package.json looks like:https://medium.com/media/c75ec28c41472a2548472d4f273fe574/hrefNOTE: It’s worth to mention that at the time of writing this article I was on webpack 3.6.0 and webpack-dev-server 2.9.1 version. Your version number may differ than that of mine.===============6. LOADERS AND PLUGINS===============We’ve come so far. Now the fun part begins. We’re actually going to explore what webpack can do by itself through some configurations.6.1. LoadersWebpack enables use of loaders to pre-process files. This allows you to bundle any static resource way beyond JavaScript. Since webpack still doesn’t know what to do with these loaders, webpack config object use module property to know what loader to work and how to execute them.module property of config object itself is an object. It works with some extra options mentioned below:# module.noParsePrevent webpack from parsing any files matching the given RegExp. Ignored files should not have calls to import, require, define or any other importing mechanism. This can boost build performance when ignoring large libraries.module: { noParse: /jquery|lodash/}# module.rulesIt takes every loaders as a set of rules inside an array. Whereas every element of that array is an object containing individual loaders and their respective configurations.From Webpack’s documentationA Rule can be separated into three parts — Conditions, Results and Nested Rules.1. Conditions: There are two input values for the conditions a. The resource: An absolute path to the file requested. b. The issuer: The location of the import.In a Rule the properties test, include, exclude and resource are matched with the resource and the property issuer is matched with the issuer.2. Results: Rule results are used only when the Rule condition matches. There are two output values of a rule: a. Applied loaders: An array of loaders applied to the resource. b. Parser options: An options object which should be used to create the parser for this module.3. Nested Rules: Nested rules can be specified under the properties rules and oneOf. These rules are evaluated when the Rule condition matches.Okay! Let’s simplify them, since webpack doc always confuses us 😖😓A loader needs some additional information to work correctly and efficiently in a module. We mention them in module.rules with some configuration parameters stated below:test:(required) A loader needs to know which file extension it’s going to work with. We give the name with the help of RegExptest: /\.js$/include: (optional) A loader needs a directory to locate where it’s working files are stored.include: /src/exclude: (optional) We can save a lot of unwanted process like — we don’t want to parse modules inside node_modules directory and can save a lot of memory and execution timeexclude: /node_modules/use: (required) A rule must have a loader property being a string. Mention the loaders you want to use in for that particular task. Loaders can be chained by passing multiple loaders, which will be applied from right to left (last to first configured).It can have a options property being a string or object. This value is passed to the loader, which should interpret it as loader options. For compatibility a query property is also possible, which is an alias for the options property. Use the options property instead.use: { loader: "babel-loader", options: { presets: ['env'] }}Detail configuration setup for module.rules: https://webpack.js.org/configuration/module/#module-rules6.2. PluginsThe plugins option is used to customize the webpack build process in a variety of ways. webpack comes with a variety of built-in plugins available under webpack.[plugin-name]Webpack has a plugin configuration setup in it’s config object with plugins property.NOTE: Every plugin needs to create an instance to be used into config object.We’re going to see them in action now!=========================7. SOME LOADERS AND PLUGINS IN ACTION=========================7.1. clean-webpack-plugin (PLUGIN)Every time we want to see our production ready dist folder, we need to delete the previous one. Such a pain! clean-webpack-plugin is to remove/clean your build folder(s) before building. It’s very easy to setup:Install via npm> npm i -D clean-webpack-pluginImport into your webpack.config.js fileconst CleanWebpackPlugin = require('clean-webpack-plugin');Now, we’re going to use a plugin for the first time. Webpack has a plugin configuration setup in it’s config object. Every plugin needs to create an instance to be used into config object. So, in our plugins property:plugins: [ new CleanWebpackPlugin(['dist'])]Here, in the instance of clean-webpack-plugin we mention dist as an array element. Webpack now knows that we want to clean/remove dist folder every time before building our bundle. This instance can have multiple directory/path as array elements and multiple options as object.Syntax for clean-webpack-plugin usage:plugins: [ new CleanWebpackPlugin(paths [, {options}])]You should watch the process of removing and creating your dist folder live in your directory and in your IDE too..Reference doc: GitHub DocUntil now our webpack.config.js looks like:https://medium.com/media/2fe8ec5a3acade2a2beb95eefc109e6f/href7.2. babel-loader (LOADER)We all want to write some ES2015/ES6 code, right? But until now our browser is not fully adopted to ES6 syntax, so we need to at first transpile our ES6 code to ES5 and then we can use it in our production bundle. Babel is taking that responsibility for us. We just need to include babel-loader into our configuration through some easy steps.Install babel-loader> npm i -D babel-loader babel-coreCreate .babelrc file in our project root to enable some babel-presets (We’ve already done it in project setup section. If you follow along with me, you’ll find a .babelrc file in your project root directory already)Install babel-preset-env to use for environment dependent compilation> npm i -D babel-preset-envIn order to enable the preset you have to define it in your .babelrc file, like this:{ "presets": ["env"]}NOTE: If we add this into our package.json > “scripts”, then the .babelrc file is not needed anymore."scripts": { "babel": { "presets": ["env"] }}Include rule into the config file modulemodule: { rules: [ { test: /\.js$/, include: /src/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['env'] } } } ]}From our loader section we know that:test : to let the loader know which file format it’s going to work oninclude : to let the loader know which directory it should work intoexclude : to let the loader know which directory should it avoid while parsinguse : to let the loader know which specific loader it’s using with use.loader and what’s it’s configuration options with use.optionsbabel-loader_confighttps://medium.com/media/febe050a1b8664fcf9b19519b1c36852/hrefhttps://medium.com/media/14a38bc6b1a5c69da689912f1673f2e4/href7.3. html-loader (LOADER) & html-webpack-plugin (PLUGIN)Since we want to edit our index.html in src directory and want to see the changes in the output dist folder, we need to create and update index.html into dist every time webpack compile our project. Well, we should remove that painful job!We need to use a loader and a plugin together to solve our problem. Because -html-loader : Exports HTML as string. HTML is minimized when the compiler demands.html-webpack-plugin : Simplifies creation of HTML files to serve your webpack bundles.Install dependencies> npm i -D html-loader html-webpack-pluginConfiguring html-loader{ test: /\.html$/, use: ['html-loader']Importing html-webpack-pluginconst HtmlWebpackPlugin = require('html-webpack-plugin');Using our pluginplugins: [ new HtmlWebpackPlugin({ template: 'index.html' })]https://medium.com/media/d8b34c435f90430e5b8580fc66d9551f/hrefNow, we’ve setup every thing. In your src/index.html write something and then run some build commandsnpm run dev : You’ll see our app now works and you can see the html element in the browser. The bundled js file has been injected into the html before the end of body tagnpm run build:prod : Watch yourself the process of building the output index.html and the changes applied in the dist/index.htmlResources:html-loader : webpack-doc , github-dochtml-webpack-plugin : webpack-doc , github-doc7.4. css-loader (LOADER), style-loader (LOADER), sass-loader (LOADER), extract-text-webpack-plugin (PLUGIN)Using CSS and SASS with webpack may look like some extra headaches with some extra steps. Webpack compiles css and pushes the code into the bundled js. But we need to extract it from the bundle, and then create a identical .css file, and then push it into our dist/index.html and then add the css to DOM. A lot of work, right? Not literally..I’ve combined 3 loaders and 1 plugin to see them work together for our required output:style-loader : Adds CSS to the DOM by injecting a <style> tagcss-loader : Interprets @import and url() like import/require() and will resolve them (stay on the article, don’t go to twitter’s “@ import”. medium’s mistake, not mine 😒)sass-loader : Loads a SASS/SCSS file and compiles it to CSSnode-sass : Provides binding for Node.js to LibSass. The sass-loader requires node-sass and webpack as peerDependency. Thus you are able to control the versions accurately.extract-text-webpack-plugin : Extract text from a bundle, or bundles, into a separate fileNow install the dependencies> npm i -D sass-loader node-sass css-loader style-loader extract-text-webpack-pluginWe need to import our app.scss into our app.js to work to let webpack know about dependencies. So in our app.js we’re going to write:import './assets/scss/app.scss';Additionally to check that our sass modules work fine, add one more .scss file in our src/assets/scss directory via terminal> touch src/assets/scss/_colors.scssImport the newly created _color.scss file into app.scss and add some styling with:@import '_colors';body { background: $bgcolor;}And define $bgcolor into _color.scss file:$bgcolor : #e2e2e2;Import extract-text-webpack-plugin into config fileconst ExtractTextPlugin = require('extract-text-webpack-plugin');It’s a good and safe practice to import webpack itself into our webpack.config.js to use the webpack’s built-in plugins into our projectconst webpack = require('webpack');Now our workflow splits into two ways for two type of requirements.(1) We want to have just a single .css file into our output(2) We want more than one .css files as outputFor a single stylesheet (we’re working on this):First, we need to create an instance of ExtractTextPlugin into which we’ll define our output filename:const extractPlugin = new ExtractTextPlugin({ filename: './assets/css/app.css'});Secondly, while configuring our css/sass loaders we need to use the previously created instance with it’s extract() method (i.e. extractPlugin.extract()) and inside the method we pass the required loaders as an argument and in a form of an objectSo our configuration of these loaders is going to be:{ test: /\.scss$/, include: [path.resolve(__dirname, 'src', 'assets', 'scss')], use: extractPlugin.extract({ use: ['css-loader', 'sass-loader'], fallback: 'style-loader' })}And now add the instance of ExtractTextPlugin (which is extractPlugin) into the plugins section:plugins: [ extractPlugin]NOTE: If you are not using any html-loader then, include a index.html file in the dist folder and link the output stylesheet and js urls into that file like:<link rel="stylesheet" href="/./assets/app.css"><script src="/./assets/main.bundle.js"></script>For multiple stylesheets (just for giving you example):If you’re following the previous direction for creating a single extracted stylesheet, then there’s nothing new for creating multiple stylesheets.Just create as much instances of ExtractTextPlugin as you want your stylesheets to have. We’re creating here two instances, one for just css and one for sass compiledconst extractCSS = new ExtractTextPlugin('./assets/css/[name]-one.css');const extractSASS = new ExtractTextPlugin('./assets/css/[name]-two.css');NOTE: ExtractTextPlugin generates a file per entry, so you must use [name], [id] or [contenthash] when using multiple entries.Now our loaders configuration looks like:{ test: /\.css$/, use: extractCSS.extract([ 'css-loader', 'style-loader' ]) },{ test: /\.scss$/, use: extractSASS.extract([ 'css-loader', 'sass-loader' ], fallback: 'style-loader') }Now add the instances into the plugins:plugins: [ extractCSS, extractSASS]Now run the npm run dev to see it action in your browser.If you’re working for single stylesheet like mine, you should see that the background changes to #e2e2e2 😂If you see the view-source from the output app, you can see the stylesheet injected into the head of our html and app.bundle.js file injected to before the end of the body tagNow What?? Well, we need to debug things from our browser, right? We just need a source map to see the actual line number from the source code rather than being lost into the minified stylesheets!In the options property for loader, you can switch ON the source map with sourceMap: true{ test: /\.scss$/, include: [path.resolve(__dirname, 'src', 'assets', 'scss')], use: extractPlugin.extract({ use: [ { loader: 'css-loader', options: { sourceMap: true } }, { loader: 'sass-loader', options: { sourceMap: true } } ], fallback: 'style-loader' })}Check your styling changes and inspect it in your browser with inspect element. You’ll find the actual line number showing where you made your changes!Here’s my configuration:https://medium.com/media/83100f59774c51b66074ac745f68f84f/hrefReferences:extract-text-webpack-plugin : webpack , githubcss-loader : webpack , githubsass-loader : webpack , githubstyle-loader : webpack , github7.5. file-loader (LOADER)Well, we’ve setup configuration for every thing except static files like images, fonts. Now, we’re going to setup for static files with very useful loader file-loaderInstall file-loader> npm i -D file-loaderConfiguring file-loader{ test: /\.(jpg|png|gif|svg)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/media/', publicPath: './assets/media/' } } ]}NOTE: BE VERY VERY CAREFUL ABOUT outputPath and publicPath in the file-loader configuration. You need to add a ‘/’ at the end of the outputPath, so that it will get the directory address rather than concatenating the specified string with the file name. VERY CAREFUL! And we don’t need to add publicPath(I guess), since we’ve already defined it in our output path//file-loader(for images){ test: /\.(jpg|png|gif|svg)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/media/' } } ]},//file-loader(for fonts){ test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['file-loader']}With the loader configured and fonts in place, you can import them via an @font-face declaration. The local url(…) directive will be picked up by webpack just as it was with the imageAdding font-face to stylesheet@font-face { font-family: 'MyFont'; src: url('./my-font.woff2') format('woff2'), url('./my-font.woff') format('woff'); font-weight: 600; font-style: normal;}Now add a sample image in your src/assets/media directory and create an img element into your src/index.html to see it workshttps://medium.com/media/feb830fb8c92040216ea93c90c36311b/hrefRun npm run dev and npm run build:prod to see everything’s working fine and clear.That’s it! Now you should find everything in place and working just fine. :)We have come to the end of this guide, that’s not everything about webpack though. But it’s the starting point that you have to understand deeply and correctly to get the the working procedure of webpack philosophy. In the upcoming blogs, I’ll try to simplify the actual powers/features of webpack like - Hot Module Replacement, Tree-shaking, Output management for development and production environment, Code splitting, Lazy loading and other stuffs.And I highly recommend to follow this awesome article rajaraodv wrote to save our lives : https://medium.com/@rajaraodv/webpack-the-confusing-parts-58712f8fcad9Since I promised you to give you the simplest cheat-sheet for you. Here it is:You can simply clone this repo in your project root to get everything in place or follow the next steps to setup your project in just 5 minuteshttps://github.com/postNirjhor/webpack-boilerplateDon’t hesitate to fork on this repo. I’d love to see others contributing on this boilerplate to make this configuration more robust and usable for everyone who has suffered a lot like me..Cheat-sheet1. Run these commands one after another in the terminal to create project folders and install all dependencies> mkdir project_name && cd project_name> npm init> mkdir src dist src/assets src/assets/media src/assets/js src/assets/scss> touch webpack.config.js README.md .babelrc src/index.html src/app.js src/assets/scss/app.scss> npm i -D webpack> npm i -D webpack-dev-server clean-webpack-plugin babel-loader babel-core babel-preset-env html-loader html-webpack-plugin sass-loader node-sass css-loader style-loader extract-text-webpack-plugin file-loader2. Add this snippet into .babelrc{ "presets": ["env"]}3. Configure package.json > scripts with this snippet"scripts": { "build": "./node_modules/.bin/webpack", "build:prod": "./node_modules/.bin/webpack -p", "watch": "./node_modules/.bin/webpack --watch", "dev": "./node_modules/.bin/webpack-dev-server"}4. Import app.scss into your app.jsimport './assets/scss/app.scss';5. Populate your src/index.html (with an image too) and src/assets/scss/app.scss and add the image into src/assets/media6. Copy and paste this configuration file into your webpack.config.js (make sure that project folders hierarchy to be same)https://medium.com/media/7c3b573c4497284e0974f94d27b8f415/href7. Run npm scripts to see your application in action in browser and in production format. Don’t forget to inspect element in the browser console to make sure everything’s working great without any error.🎉🎉🎉🎉 End of this long exhaustive guide 🎉🎉🎉🎉If you find something that’s not right in this guide, mention it into the comment section. I’d love to get your feedback on this write up.If you like it, give some 👏 💓 and share it on medium and twitter.Thank You for your patience 🙇Webpack 3 quickstarter: Configure webpack from scratch was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.

Additional Info

Leave a comment

Make sure you enter all the required information, indicated by an asterisk (*). HTML code is not allowed.

Disclaimer: As a news and information platform, also aggregate headlines from other sites, and republish small text snippets and images. We always link to original content on other sites, and thus follow a 'Fair Use' policy. For further content, we take great care to only publish original material, but since part of the content is user generated, we cannot guarantee this 100%. If you believe we violate this policy in any particular case, please contact us and we'll take appropriate action immediately.

Our main goal is to make crypto grow by making news and information more accessible for the masses.