{"id":1891,"date":"2020-11-29T00:37:44","date_gmt":"2020-11-28T17:37:44","guid":{"rendered":"https:\/\/wptips.dev\/?p=1891"},"modified":"2022-07-11T00:06:53","modified_gmt":"2022-07-10T17:06:53","slug":"webpack-in-wordpress","status":"publish","type":"post","link":"https:\/\/pixelstudio.id\/blog\/webpack-in-wordpress\/","title":{"rendered":"How to Use Webpack in WordPress"},"content":{"rendered":"\n<p>Does a WordPress developer need to know Webpack?<\/p>\n\n\n\n<p>You might think it is unnecessary and too complex. So I will show you how useful it is for developing a theme.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><strong>TABLE OF CONTENTS<br><\/strong>1. <a href=\"#what-is-webpack\">What is Webpack<\/a><br>2. <a href=\"#install\">How to Install \/ Setup Webpack?<\/a><br>3. <a href=\"#css\">Compiling CSS \/ Sass<\/a><br>4. <a href=\"#live-reload\">CSS Live Reload<\/a><br>5. <a href=\"#npm-library\">Getting JS Library from NPM<\/a><\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-webpack\">1. What is Webpack?<\/h2>\n\n\n\n<p>Webpack is a command-line tool to <strong>allow the use of JavaScript modules<\/strong>. This is a feature that is quite a pain to do without Webpack.<\/p>\n\n\n\n<p>For example, we have <code>app.js<\/code> that needs 2 libraries: <code>js-datepicker.js<\/code> and <code>swiper.js<\/code>. In the old way, you would enqueue them separately resulting in this output:<\/p>\n\n\n\n<pre class=\"wp-block-code is-style-wrong\"><code lang=\"html\" class=\"language-html\">&lt;script src=\"\/wp-content\/themes\/mytheme\/js\/js-datepicker.js\"&gt;\n&lt;script src=\"\/wp-content\/themes\/mytheme\/js\/swiper.js\"&gt;\n&lt;script src=\"\/wp-content\/themes\/mytheme\/js\/app.js\"&gt;<\/code><\/pre>\n\n\n\n<p>With Webpack, we can use <code>import<\/code> to embed the libraries inside <code>app.js<\/code>. All the codes are now combined into one file:<\/p>\n\n\n\n<pre title=\"js\/app.js\" class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">import datepicker from '.\/js-datepicker.js';\nimport swiper from '.\/swiper.js';\n\n\/\/ do something<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code is-style-correct\"><code lang=\"html\" class=\"language-html\">&lt;!-- Now only need to enqueue 1 file --&gt;\n\n&lt;script src=\"\/wp-content\/themes\/mytheme\/dist\/app.js\"&gt;<\/code><\/pre>\n\n\n\n<p>This seems like a <strong>minor benefit<\/strong> but it will become more apparent when you have a lot of files. Moreover, Webpack has many other utilities such as:<\/p>\n\n\n\n<ul><li>Minify your code<\/li><li>Compiling Sass into CSS<\/li><li>Auto reload your CSS as you save<\/li><li>Allow use of advanced syntaxes for your Vue or React code.<\/li><li>etc<\/li><\/ul>\n\n\n\n<p>In this tutorial, we will learn to do the first three of that list.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"install\">2. How to Install \/ Setup Webpack?<\/h2>\n\n\n\n<ol><li>Download and install <a rel=\"noreferrer noopener\" href=\"https:\/\/nodejs.org\/en\/\" target=\"_blank\">Node JS<\/a>. Pick the recommended version.<\/li><li>Create <code>package.json<\/code> and <code>webpack.config.js<\/code> files in your theme and paste in the code below:<\/li><\/ol>\n\n\n\n<pre title=\"wp-content\/my-theme\/package.json\" class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n  \"name\": \"my-theme\",\n  \"private\": true,\n  \"dependencies\": {},\n  \"devDependencies\": {\n    \"browser-sync\": \"^2.26.12\",\n    \"browser-sync-webpack-plugin\": \"^2.2.2\",\n    \"css-loader\": \"^4.3.0\",\n    \"file-loader\": \"^6.1.0\",\n    \"mini-css-extract-plugin\": \"^0.11.2\",\n    \"sass\": \"^1.53.0\",\n    \"sass-loader\": \"^10.0.2\",\n    \"url-loader\": \"^4.1.0\",\n    \"webpack\": \"^4.44.1\",\n    \"webpack-cli\": \"^3.3.12\"\n  },\n  \"scripts\": {\n    \"build\": \"webpack --mode production\",\n    \"dev\": \"webpack --mode development --watch\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<pre title=\"wp-content\/my-theme\/webpack.config.js\" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">const MiniCssExtractPlugin = require('mini-css-extract-plugin');\nconst BrowserSyncPlugin = require('browser-sync-webpack-plugin');\nvar path = require('path');\n\n\/\/ change these variables to fit your project\nconst jsPath= '.\/js';\nconst cssPath = '.\/css';\nconst outputPath = 'dist';\nconst localDomain = 'http:\/\/mysite.local';\nconst entryPoints = {\n  \/\/ 'app' is the output name, people commonly use 'bundle'\n  \/\/ you can have more than 1 entry point\n  'app': jsPath + '\/app.js',\n};\n\nmodule.exports = {\n  entry: entryPoints,\n  output: {\n    path: path.resolve(__dirname, outputPath),\n    filename: '[name].js',\n  },\n  plugins: [\n    new MiniCssExtractPlugin({\n      filename: '[name].css',\n    }),\n\n    \/\/ Uncomment this if you want to use CSS Live reload\n    \/*\n    new BrowserSyncPlugin({\n      proxy: localDomain,\n      files: [ outputPath + '\/*.css' ],\n      injectCss: true,\n    }, { reload: false, }),\n    *\/\n  ],\n  module: {\n    rules: [\n      {\r\n        test: \/\\.s?[c]ss$\/i,\r\n        use: [\r\n          MiniCssExtractPlugin.loader,\r\n          'css-loader',\r\n          'sass-loader',\r\n        ],\r\n      },\r\n      {\r\n        test: \/\\.sass$\/i,\r\n        use: [\r\n          MiniCssExtractPlugin.loader,\r\n          'css-loader',\r\n          {\r\n            loader: 'sass-loader',\r\n            options: {\r\n              sassOptions: { indentedSyntax: true },\r\n            },\r\n          },\r\n        ],\r\n      },\n      {\r\n        test: \/\\.(jpg|jpeg|png|gif|woff|woff2|eot|ttf|svg)$\/i,\r\n        use: 'url-loader?limit=1024',\r\n      },\n    ]\n  },\n};<\/code><\/pre>\n\n\n\n<p>The code above assumes your theme&#8217;s structure looks like below. If it&#8217;s different, change the variables in Line 5 accordingly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">\/\n\u251c\u2500\u2500 css\/\n\u2502   \u251c\u2500\u2500 app.css\n\u251c\u2500\u2500 js\/\n\u2502   \u251c\u2500\u2500 app.js\n\u251c\u2500\u2500 dist\/\n\u251c\u2500\u2500 index.php\n\u251c\u2500\u2500 page.php\n\u251c\u2500\u2500 ...<\/code><\/pre>\n\n\n\n<ol start=\"3\"><li>Open command-prompt \/ terminal in your theme and <strong>run the command below<\/strong>. For Windows users, you might see an error saying unable to remove the directory. Simply rerun the command to solve that.<\/li><\/ol>\n\n\n\n<pre title=\"\" class=\"wp-block-code\"><code class=\"\">npm install<\/code><\/pre>\n\n\n\n<ol start=\"4\"><li>To start compiling, run the command below. Every time you save your JS, it will automatically re-compile.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">npm run dev<\/code><\/pre>\n\n\n\n<ol start=\"5\"><li>Before launching, you need to <strong>minify the code<\/strong>. To do this, you need to quit the <code>dev<\/code> command, then run:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">npm run build<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"css\">3. Compiling CSS or Sass<\/h2>\n\n\n\n<p>By default, Webpack only supports JS files. But if you followed our setup above, it has extra packages to handle CSS or Sass.<\/p>\n\n\n\n<p>There are 2 ways of compiling them. The <strong>first way<\/strong> is to directly import them in your JS:<\/p>\n\n\n\n<pre title=\"js\/app.js\" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">import '..\/css\/style.sass'\n\n\/\/ ...\n<\/code><\/pre>\n\n\n\n<p>The <strong>second way<\/strong> is to add a new entry point in your config:<\/p>\n\n\n\n<pre title=\"webpack.config.js\" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ ...\n\nconst entryPoints = {\n  'app': jsPath + '\/app.js',\n  'style': cssPath + '\/style.sass',\n};\n\n\/\/ ...<\/code><\/pre>\n\n\n\n<p>The first way makes more sense if the CSS is related to the script.<\/p>\n\n\n\n<p class=\"has-light-yellow-background-color has-background has-small-font-size\"><strong>Note<\/strong>: If you get this error: <code>ENOENT no such file or directory, scandir<\/code>, you can fix it by running the command <code>npm rebuild node-sass<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"live-reload\">4. CSS Live Reload<\/h2>\n\n\n\n<p>Whenever you save your CSS, Webpack will <strong>automatically reloads it<\/strong>.<\/p>\n\n\n\n<p>You are probably using other tools to do this, but it&#8217;s nice to have everything in one place.<\/p>\n\n\n\n<p>We have included the packages to handle this in our current setup. Simply do these 2 steps in your <code>webpack.config.js<\/code> to enable it:<\/p>\n\n\n\n<ul><li>Update <code>localDomain<\/code> variable to be the local domain you use for your project.<\/li><li>Uncomment the <code>new BrowserSyncPlugin<\/code> block.<\/li><\/ul>\n\n\n\n<p>To launch it, use the same command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">npm run dev<\/code><\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"462\" height=\"244\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2020\/11\/webpack-browsersync.jpg\" alt=\"\" class=\"wp-image-1912\"\/><figcaption>Command Line of Browser Sync<\/figcaption><\/figure><\/div>\n\n\n\n<p>If you open your site in <code>localhost:3000<\/code>, any updated CSS will be reloaded.<\/p>\n\n\n\n<p>Also, do you notice the <strong>External URL<\/strong>? You can open that <strong>on your mobile phone<\/strong> to view your local site! As long as both your computer and phone are under the same Wi-Fi.<\/p>\n\n\n\n<p class=\"has-light-yellow-background-color has-background has-small-font-size\"><strong>Note<\/strong>: Depending on your router setup, the External URL might not work. I&#8217;m not familiar with networking stuff, so I don&#8217;t know the fix. Let me know in the comment if you found one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"npm-library\">5. Getting JS Library from NPM<\/h2>\n\n\n\n<p>Most popular JS libraries are available in NPM. So you don&#8217;t need to save a local copy in your theme.<\/p>\n\n\n\n<p>Simply <strong>Google it<\/strong> to know whether it&#8217;s available as NPM or not.<\/p>\n\n\n\n<p>In our example, <code>js-datepicker<\/code> and <code>swiper<\/code> is available as NPM. So we can install them by running these 2 commands (in your theme directory):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">npm install --save js-datepicker\n\nnpm install --save swiper<\/code><\/pre>\n\n\n\n<p>Now, we update their import references from this:<\/p>\n\n\n\n<pre title=\"js\/app.js (old)\" class=\"wp-block-code is-style-wrong\"><code lang=\"javascript\" class=\"language-javascript\">import datepicker from '.\/js-datepicker.js';\nimport swiper from '.\/swiper.js';<\/code><\/pre>\n\n\n\n<p>Into directly using the package&#8217;s name:<\/p>\n\n\n\n<pre title=\"js\/app.js (new)\" class=\"wp-block-code is-style-correct\"><code lang=\"javascript\" class=\"language-javascript\">import datepicker from 'js-datepicker';\nimport swiper from 'swiper';\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>I hope this convinces you to start using Webpack in your project. Unless you&#8217;re doing minimal customization to a theme, this will serve you well.<\/p>\n\n\n\n<p>There are limitless possibilities with what you can do with Webpack. I believe this tutorial is good enough for you to be able to experiment further.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Leave a comment below if you have any question regarding Webpack. I&#8217;m not a pro at it, but will try my best in answering yours.<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Does a WordPress developer need to know Webpack? You might think it is unnecessary and too complex. So I will show you how useful it is for developing a theme.<\/p>\n","protected":false},"author":1,"featured_media":1920,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[32,50],"class_list":["post-1891","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend","tag-javascript","tag-webpack"],"blocksy_meta":"","_links":{"self":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1891","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/comments?post=1891"}],"version-history":[{"count":15,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1891\/revisions"}],"predecessor-version":[{"id":2171,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1891\/revisions\/2171"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media\/1920"}],"wp:attachment":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media?parent=1891"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/categories?post=1891"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/tags?post=1891"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}