laravel-mix is a tool developed by Laravel team to use it specifically with Laravel and it’s developed with webpack. And it provides many helpful things with just one configuration file.
Like, dividing app.js and vendor.js file, minimizing, combining files, compiling scss, import node modules (eg. bootstrap, jquery). you can check its documentation here.
After using it with Laravel, I thought its great if we can use it with some server-side templating, then it would be the great starter kit for developing HTML bootstrap theme.
My first choice for server-side templating was ejs due to its easiness. Anyhow, we will just require include feature of it, so that we can cut down header footer and keep it in include/header.ejs and include/footer.ejs. So that we don’t have to copy/paste that part in each page we develop.
Then I started searching for ejs loader which we can use with webpack, after lots of research I found ejs-compiled-loader. It works way better for our requirement.
At the time of development its necessary that we can easily include other pages in our main page. Live reload is also a most useful thing for our speed and avoiding manual refresh in the browser.
So now let’s dive into webpack.mix.js file.
let mix = require("laravel-mix");
let HtmlWebpackPlugin = require("html-webpack-plugin");
mix.js("src/js/app.js", "dist/js");
mix.combine([
"src/vendor/dataTables/datatables.min.js",
"src/vendor/jqueryui/jquery-ui.min.js",
"src/vendor/sweetalert/sweetalert.min.js",
"src/vendor/validate/jquery.validate.min.js"
], "dist/js/vendor.js");
mix.combine([
"src/vendor/animate/animate.css",
"src/vendor/dataTables/datatables.min.css",
"src/vendor/font-awesome/css/font-awesome.min.css",
"src/vendor/jqueryui/jquery-ui.min.css",
], "dist/css/vendor.css");
mix.sass("src/sass/app.scss", "dist/css");
mix.copyDirectory("src/vendor/font-awesome/fonts", "dist/fonts");
// mix.sourceMaps();
mix.setPublicPath("dist");
mix.copyDirectory("src/img", "dist/img");
mix.disableNotifications();
mix.webpackConfig({
output: {
// path: path.join(__dirname, 'dist'),
publicPath: ""
},
plugins: [
new HtmlWebpackPlugin({
template: "ejs-compiled-loader!./src/index.ejs",
filename: "index.html",
inject: false
})
],
devServer: {
//hot: true,
//inline: true,
//contentBase: __dirname
disableHostCheck: false,
watchContentBase: true,
host: "0.0.0.0",
open: true
}
});
Below screen shot is suggested directory structure I have used for this blog post demo.
index.ejs file content
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="img/favicon.ico">
<title>Bootstrap - Button Demo</title>
<% include /src/include/styles.ejs %>
</head>
<body>
<% include /src/include/header.ejs %>
<main id="lms-page-index">
your content goes here
</main>
<% include /src/include/footer.ejs %>
<% include /src/include/scripts.ejs %>
</body>
</html>
Here you can see that I have included 4 files in the index file. You can see full demo in GitHub
Few parts to note down here.
mix.webpackConfig({ output: { publicPath: "" }, plugins: [ new HtmlWebpackPlugin({ template: "ejs-compiled-loader!./src/index.ejs", filename: "index.html", inject: false }) ], devServer: { disableHostCheck: false, watchContentBase: true, host: "0.0.0.0", open: true } });
with this it will be able to live reload on ip and on local host also.
eg http://localhost:8080 or http://192.168.0.2:8080
For every HTML file we create we need to add this block and while linking we need to use index.html as it will generate index.html in dist folder.
new HtmlWebpackPlugin({ template: "ejs-compiled-loader!./src/index.ejs", filename: "index.html", inject: false })
How to run this
While using it for first time
npm install
And then every-time
npm run hot
It will open up browser with this url http://0.0.0.0:8080/ and you are ready to start with your theme development.
For final build generation use
npm run prod
it will generate dist folder which you can use directly for upload to server
Again GitHub link for this working demo is here