Topic: MDB + Webpack guide
Arnt Oddvar Pedersen pro asked 7 years ago
Edit: Steps removed. See next post for a complete installation guide and boilerplate project.
Arnt Oddvar Pedersen pro answered 7 years ago
Material Design Bootstrap + Webpack
Updated: 09/05/2018
In this guide we'll walk go through how to quickly set-up a Webpack4 project with MDB jQuery Free and Pro
If you don't want to follow the guide you can also get this entire project directly from GitHub.
1. Getting Started
Go into the folder you want to start your new MDB Webpack project in and initialize it:
npm init
Just hit enter through the questions, you can change them later. Once the initialization is done, we're going to setup Babel with the ENV and Stage-0 environments so you can use all the latest stuff in JavaScript and transpile them gracefully to ES5. We are also going to setup ESLint with the Airbnb javascript style guide and add SASS support.
Copy and paste this command into your command line:
npm i --save-dev babel-core babel-eslint babel-loader babel-polyfill babel-preset-env babel-preset-stage-0 clean-webpack-plugin css-loader eslint eslint-config-airbnb eslint-config-airbnb-base eslint-loader eslint-plugin-import exports-loader extract-text-webpack-plugin file-loader html-loader html-webpack-plugin node-sass sass-loader webpack webpack-cli webpack-dev-server
As a pro user, you also want to install the following plugin:
npm i --save-dev copy-webpack-plugin
2. Installing MDB Dependencies
Once the above command(s) are done processing, we're going to install some libraries that are required by MDB. MDB ships with some these already, however Webpack won't be able to find the references for WavesJs and HammerJs so we're installing these as dependencies as well for now. They won't actually be included in the finished product. (No double references)
npm i --save jquery bootstrap popper.js hammerjs node-waves font-awesome
3. Setting up the project
In your project folder, you should now have the following files and folders:
- package.json
- node_modules
- package-lock.json (if using Visual Studio Code)
We're now going to create a few configuration files to tell node, Webpack and ESLint how to function. Create the following files:
- webpack.config.js
- .eslintrc
- .jshintrc (Optional: Only if you use both JSHint and ESLint regularily through Visual Studio Code)
Let's also separate our sources, the files we will be actively working on, from the rest of the configuration files. Create this folder:
- src
You should now have a folder structure that looks something like this image.
3.1. Enable ESLint
Open up the ".jshintrc" file and paste the following into it:
{ "esversion": 6 }
Then open your ".eslintrc" and add the following code to it:
{ "extends": "airbnb-base", "parser": "babel-eslint", "env": { "browser": true, "jquery": true } }
This tells JSHint to not handle error checking in the project and configures ESLint to use the Airbnb javascript style guide as a reference. We also set the environment to "browser" and "jquery" to allow the usage of window and $ commands globally without producing false-positive errors.
3.2 Everyone needs a main page
Finally, inside our sources folder, create an index.html file then paste the following into it:
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"> <title>Material Design for Bootstrap</title> </head> <body> <div style="height: 100vh"> <div class="flex-center flex-column"> <h1 class="animated fadeIn mb-4">Material Design for Bootstrap</h1> <h5 class="animated fadeIn mb-3">Thank you for using our product. We're glad you're with us.</h5> <p class="animated fadeIn text-muted">MDB Team</p> </div> </div> </body> </html>
4. Setting up Webpack
Open up webpack.config.js and paste the following into it:
const path = require('path'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const extractPlugin = new ExtractTextPlugin({ filename: 'main.css', }); module.exports = { entry: [ 'babel-polyfill', './src/js/index.js', './src/scss/main.scss', './src/vendors/mdb/scss/mdb.scss' ], output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, module: { rules: [ { enforce: 'pre', test: /.js?$/, exclude: [/node_modules/, /vendors/], // Don't lint MDB loader: 'eslint-loader', options: { fix: true, }, }, { test: /.js?$/, exclude: [/node_modules/, /vendors/], use: [ { loader: 'babel-loader', options: { presets: ['env', 'stage-0'], }, }, ], }, { test: /.scss?$/, use: extractPlugin.extract({ use: ['css-loader', 'sass-loader'], }), }, { test: /.html$/, use: ['html-loader'], }, // Font-awesome 4.7.X { test: /.(ttf|otf|eot|svg|woff(2)?)(?[a-z0-9]+)?$/, exclude: [/vendors/, /img/], loader: 'file-loader?name=fonts/[name].[ext]', }, // MDB Roboto font { test: /.(ttf|otf|eot|svg|woff(2)?)(?[a-z0-9]+)?$/, exclude: [/node_modules/, /img/], loader: 'file-loader?name=font/roboto/[name].[ext]', }, { test: /.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]', useRelativePath: true, }, }, ], }, plugins: [ extractPlugin, new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.$': 'jquery', 'window.jQuery': 'jquery', Waves: 'node-waves', }), new HtmlWebpackPlugin({ template: 'src/index.html', }), new CleanWebpackPlugin(['dist']), ], devtool: 'source-map', target: 'web', };
What's important to notice here is that we're setting the path and name of our compiled (bundles) css file near the very top before we export the settings for Webpack.
We are also telling our entry point where to find the different files; Namely the MDB SCSS file, our main SCSS file, our Javascript entry point and telling Webpack to polyfill ES6 functions where applicable before bundling it all together.
In the "output" entry we are telling Webpack to create a "dist" folder in the same folder as the configuration file and what to name the bundled JS.
Unfortunately, Webpack doesn't understand everything so in the rules section; We're telling Webpack what to do when it encounters the different filetypes. At the very top we're telling Webpack to run all encountered JavaScript files not contained within the excluded folders (node_modules and vendors) through ESLint and attempt to auto fix any errors it can before bundling. We're also telling Webpack to transpile any "new" JavaScript (ES6) to ES5 so we can support older browsers.
The next few rules tells Webpack what to do with SASS files, images, fonts and HTML documents and where to place them.
Since MDB expects a few global variables, like window.$ and Waves, we're "shimming" a few variables to the global scope through webpack.ProvidePlugin().
With the HTML-Webpack-Plugin, we're defining the main HTML file to use as a template. This tells Webpack to automatically inject the Style and Script tags of our bundled scss and javascript without needing to edit anything ourselves. This is the goal with Webpack.
This plugin is also useful if you end up using a templating engine such as Handlebars as you can dynamically create new pages based on the given template document.
With the last plugin, we are telling Webpack to delete the "dist" folder every time you run Webpack in production mode. (npm run webpack --mode production)
4.1 Pro users
If you're a PRO user, there are 2 additional things you need to add to your webpack.config.js file. Remember that plugin you installed earlier? Include in in the configuration file:
const CopyWebpackPlugin = require('copy-webpack-plugin');
This is because MDB Pro has an additional "mdb-addons" folder. We need to copy it to the "dist" to avoid getting issues with some Pro functionality.
In the plugins section of the Webpack configuration, copy/paste this:
new CopyWebpackPlugin([{ from: 'src/vendors/mdb/mdb-addons', to: 'mdb-addons' }]),
5. Adding the entry points.
In the Webpack configuration file, we added 2 entry points we haven't created yet. The index.js and main.scss file. Let's create them now.
In the source folder, add a new folder called JS and create a new file inside called index.js (or whatever you ended up calling your entry point). This file brings all your modules together, but for now lets import the libraries needed for MDB. Copy/Paste the following code into index.js
// jQuery import 'jquery'; // PopperJS import 'popper.js'; // Bootstrap 4 import 'bootstrap'; // Material Design Bootstrap import '../vendors/mdb/js/mdb';
The order of things is just as important as when you manually add these scripts in the body of your HTML. You'll notice that we're not importing Node-Waves and HammerJS. Webpack only need these libraries to create references for MDB. Lastly we're importing the non-minified version of MDB to avoid any potential problems.
Now, go back to the roof of the source folder and create a new folder called "scss". Inside here, create a new file called "main.scss" and copy/paste this into it:
// FontAwesome 4.7.x $fa-font-path: '~font-awesome/fonts'; @import '~font-awesome/scss/font-awesome.scss'; // Bootstrap 4 @import '~bootstrap/scss/bootstrap';
MDB needs FontAwesome 4 so at the top of our stylesheet we're setting the font path of FA and importing its stylesheet before importing the Bootstrap stylesheet.
6. Final Steps
Lastly, let's create some commands. Open up your package.json and remove the already existing "scripts" section, then cop/paste the following into its place:
"scripts": { "build": "webpack --mode production", "dev": "webpack-dev-server --mode development --open --hot" },
Open a command promt or terminal and point it to the root folder of your project, then run this command:
npm run dev
If you've followed this guide thoroughly, a browser window should automatically open for you with hot-reloading enabled.
Happy coding!
Arnt Oddvar Pedersen pro answered 7 years ago
KES commented 3 years ago
May you please provide the link to repository so I will be able to clone it?
Marcin Luczak staff commented 3 years ago
@KES,
Link to the repository can be found in the tutorial made by @Arnt Oddvar Pedersen https://mdbootstrap.com/articles/jquery/md-bootstrap-webpack-tutorial/
Keep coding, Marcin
Michal Szymanski staff pro premium priority answered 7 years ago
Thank you very much for this contribution Arnt!
If you write more comprehensive guide we could attach it to official MDB documentation with your credits.
Best
Arnt Oddvar Pedersen pro commented 7 years ago
Thank you for the nice comment! I'll publish a more in-depth guide on how to setup the entire webpack environment.Ibrahim Dembele answered 5 years ago
Hi, I'm using symfony 4 for my projet, I would like to use mdbootstrap for this projet after installing the mdb and all dependencies, i got this error in my console "" TypeError: "exports" is read-only "" i don't access the javascript functionality. Please I want the help
Grzegorz Bujański staff commented 5 years ago
Hi. check this topic: https://mdbootstrap.com/support/jquery/latest-version-of-mdb-not-compatible-with-webpack/ Here is the configuration for laravel, but maybe it will help you to configure the symfon.
Michal Szymanski staff pro premium priority answered 7 years ago
Rafał Morawiec answered 7 years ago
Arnt Oddvar Pedersen pro commented 7 years ago
I'm actually using Webpack4 right now! Make sure that you use 4.0.0-beta.0 of extract-text-webpack-plugin as it's compatible with Webpack4. There's also currently a bug I was notified about with the way CSS is currently loaded. Importing the MDB.css file with the extension makes node-sass treat it as a url import and "downloads" it, which makes it load the CSS at the top of the file instead of under Bootstrap's CSS. I'm working on fixing this now.manchuwook pro answered 6 years ago
Bartłomiej Malanowski staff pro premium commented 6 years ago
you should see "mdb-addons" directory. I can see it using the latest versionlondoh pro answered 6 years ago
Bartłomiej Malanowski staff pro premium commented 6 years ago
If you're using MDB Pro with webpack, you need to copymdb-addons
from your MDB Pro package. Here it's an official tutorial of integrating MDB with Webpack: https://mdbootstrap.com/mdbootstrap-webpack-tutorial/
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Pro
- Premium support: No
- Technology: MDB jQuery
- MDB Version: -
- Device: -
- Browser: -
- OS: -
- Provided sample code: No
- Provided link: No
rhodes bird commented 4 years ago
I appreciate your quality stuff and I would love to read more informative posts like this one. Waves Plugins