Home
Softono
b

brandonkramer

Professional software vendor delivering innovative solutions on the Softono platform. Specialized in both open-source and proprietary software development.

Total Products
2

Software by brandonkramer

wordpress-webpack-workflow
Open Source

wordpress-webpack-workflow

# WordPress Webpack v5 Workflow ![WebPack 5.12.3](https://img.shields.io/badge/WebPack-5.12.3-brightgreen) ![Babel 7.12.10](https://img.shields.io/badge/Babel-7.12.10-brightgreen) ![BrowserSync 2.26.13](https://img.shields.io/badge/BrowserSync-2.26.13-brightgreen) ![PostCSS 8.2.4](https://img.shields.io/badge/PostCSS-8.2.4-brightgreen) ![PurgeCSS 3.1.3](https://img.shields.io/badge/PurgeCSS-3.1.3-brightgreen) <table width='100%' align="center"> <tr> <td align='left' width='100%' colspan='2'> <strong>WebPack workflow to kickstart your WordPress projects</strong><br /> This includes common and modern tools to facilitate front-end development and testing and kick-start a front-end build-workflow for your WordPress plugins and themes. </td> </tr> </table> Includes WebPack v5, BabelJS v7, BrowserSync v2, PostCSS v8, PurgeCSS v3, Autoprefixer, Eslint, Stylelint, SCSS processor, WPPot, an organized config & file structure and more. ## Quickstart ![Image](https://media.giphy.com/media/wpdTw8x0LgphOzSkUb/source.gif) ```bash # 1-- Run the npx script to get the files npx wp-strap webpack # 2-- Edit the BrowserSync settings in `webpack.config.js` if you want to utilise it # 3-- Start your npm build workflow with one of these commands: yarn dev yarn dev:watch yarn prod yarn prod:watch ``` You can also use the npx script with predefined answers to get a quicker start ```bash npx wp-strap webpack "projectName:Your plugin name" "author:The Dev Company" authorEmail:[email protected] url:the-dev-company.com css:Sass+PostCSS "folder:Current folder" ``` <a href="#what-to-configure">Read more about the configuration & build scripts</a> ____ ## Features & benefits **Styling (CSS)** >- **Minification** in production mode handled by Webpack >- [**PostCSS**](http://postcss.org/) for handy tools during post CSS transformation using Webpack's [**PostCSS-loader**](https://webpack.js.org/loaders/postcss-loader/) >- **Auto-prefixing** using PostCSS's [**autoprefixer**](https://github.com/postcss/autoprefixer) to parse CSS and add vendor prefixes to CSS rules using values from [Can I Use](https://caniuse.com/). It is [recommended](https://developers.google.com/web/tools/setup/setup-buildtools#dont_trip_up_with_vendor_prefixes) by Google and used in Twitter and Alibaba. >- [**PurgeCSS**](https://github.com/FullHuman/purgecss) which scans your php (template) files to remove unused selectors from your css when in production mode, resulting in smaller css files. >- **Sourcemaps** generation for debugging purposes with [various styles of source mapping](https://webpack.js.org/configuration/devtool/) handled by WebPack >- [**Stylelint**](https://stylelint.io/) that helps you avoid errors and enforce conventions in your styles. It includes a [linting tool for Sass](https://github.com/kristerkari/stylelint-scss). **Styling when using PostCSS-only** >- Includes [**postcss-import**](https://github.com/postcss/postcss-import) to consume local files, node modules or web_modules with the @import statement >- Includes [**postcss-import-ext-glob**](https://github.com/dimitrinicolas/postcss-import-ext-glob) that extends postcss-import path resolver to allow glob usage as a path >- Includes [**postcss-nested**](https://github.com/postcss/postcss-nested) to unwrap nested rules like how Sass does it. >- Includes [**postcss-nested-ancestors**](https://github.com/toomuchdesign/postcss-nested-ancestors) that introduces ^& selector which let you reference any parent ancestor selector with an easy and customizable interface >- Includes [**postcss-advanced-variables**](https://github.com/jonathantneal/postcss-advanced-variables) that lets you use Sass-like variables, conditionals, and iterators in CSS. **Styling when using Sass+PostCSS** > - **Sass to CSS conversion** using Webpack's [**sass-loader**](https://webpack.js.org/loaders/sass-loader/) >- Includes [**Sass magic importer**](https://github.com/maoberlehner/node-sass-magic-importer) to do lot of fancy things with Sass @import statements **JavaScript** > - [**BabelJS**](https://babeljs.io/) Webpack loader to use next generation Javascript with a **BabelJS Configuration file** >- **Minification** in production mode >- [**Code Splitting**](https://webpack.js.org/guides/code-splitting/), being able to structure JavaScript code into modules & bundles >- **Sourcemaps** generation for debugging purposes with [various styles of source mapping](https://webpack.js.org/configuration/devtool/) handled by WebPack >- [**ESLint**](https://eslint.org/) find and fix problems in your JavaScript code with a **linting configuration** including configurations and custom rules for WordPress development. >- [**Prettier**](https://prettier.io/) for automatic JavaScript / TypeScript code **formatting** **Images** > - [**ImageMinimizerWebpackPlugin**](https://webpack.js.org/plugins/image-minimizer-webpack-plugin/) + [**CopyWebpackPlugin**](https://webpack.js.org/plugins/copy-webpack-plugin/) to optimize (compress) all images using >- _File types: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`_ **Translation** > - [**WP-Pot**](https://github.com/wp-pot/wp-pot-cli) scans all the files and generates `.pot` file automatically for i18n and l10n **BrowserSync, Watcher & WebpackBar** > - [**Watch Mode**](https://webpack.js.org/guides/development/#using-watch-mode), watches for changes in files to recompile >- _File types: `.css`, `.html`, `.php`, `.js`_ >- [**BrowserSync**](https://browsersync.io/), synchronising browsers, URLs, interactions and code changes across devices and automatically refreshes all the browsers on all devices on changes >- [**WebPackBar**](https://github.com/nuxt/webpackbar) so you can get a real progress bar while development which also includes a **profiler** **Configuration** > - All configuration files `.prettierrc.js`, `.eslintrc.js`, `.stylelintrc.js`, `babel.config.js`, `postcss.config.js` are organised in a single folder >- The Webpack configuration is divided into 2 environmental config files for the development and production build/environment ## Requirements - [Node.js](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [Yarn](https://classic.yarnpkg.com/en/docs/install/#mac-stable) ## File structure ```bash β”œβ”€β”€package.json # Node.js dependencies & scripts (NPM functions) β”œβ”€β”€webpack.config.js # Holds all the base Webpack configurations β”œβ”€β”€webpack # Folder that holds all the sub-config files β”‚ β”œβ”€β”€ .prettierrc.js # Configuration for Prettier β”‚ β”œβ”€β”€ .eslintrc.js # Configuration for Eslint β”‚ β”œβ”€β”€ .stylelintrc.js # Configuration for Stylelint β”‚ β”œβ”€β”€ babel.config.js # Configuration for BabelJS β”‚ β”œβ”€β”€ postcss.config.js # Configuration for PostCSS β”‚ β”œβ”€β”€ config.base.js # Base config for Webpack's development & production mode β”‚ β”œβ”€β”€ config.development.js # Configuration for Webpack in development mode β”‚ └── config.production.js # Configuration for Webpack in production mode β”œβ”€β”€languages # WordPress default language map in Plugins & Themes β”‚ β”œβ”€β”€ wordpress-webpack.pot # Boilerplate POT File that gets overwritten by WP-Pot └──assets β”œβ”€β”€ src # Holds all the source files β”‚ β”œβ”€β”€ images # Uncompressed images β”‚ β”œβ”€β”€ scss/pcss # Holds the Sass/PostCSS files β”‚ β”‚ β”œβ”€ frontend.scss/pcss # For front-end styling β”‚ β”‚ └─ backend.scss/pcss # For back-end / wp-admin styling β”‚ └── js # Holds the JS files β”‚ β”œβ”€ frontend.js # For front-end scripting β”‚ └─ backend.js # For back-end / wp-admin scripting β”‚ └── public β”œβ”€β”€ images # Optimized (compressed) images β”œβ”€β”€ css # Compiled CSS files with be generated here └── js # Compiled JS files with be generated here ``` ## What to configure 1. Edit the translate script in package.json with your project data - If you use `npx wp-strap webpack` to get the files then this will be done automatically with you terminal input 2. Edit the BrowserSync settings in `webpack.config.js` which applies to your local/server environment - You can also disable BrowserSync, Eslint & Stylelint in `webpack.config.js` 3. The workflow is ready to start, you may want to configure the files in `/webpack/` and `webpack.config.js` to better suite your needs ### Work with Sass+PostCSS or PostCSS-only In `webpack.config.js` you can choose to work with Sass, and use PostCSS only for the autoprefixer function or go full PostCSS (without sass); In that case `sass` needs to be configured to `postcss`. ```js projectCss: { use: 'sass' // sass || postcss } ``` This gets automatically configured when using the initial setup with `npx wp-strap webpack`. Working with PostCSS-only is beneficial when you work with TailwindCSS for example. You can read more about that here: https://tailwindcss.com/docs/using-with-preprocessors#using-post-css-as-your-preprocessor. Using TailwindCSS as a utility-first css framework is great for tons of reasons, but I do believe there are projects where you're better off using Sass(+Bootstrap), though it's a personal preference; therefore I left the ability to change between `Sass+PostCSS` or `PostCSS-only`. When changing this configuration after the `npx wp-strap webpack` setup, then you also need to change the import rule in `assets/src/js/frontend.js` & `assets/src/js/backend.js` to import a `.css` or `.pcss` file instead of a `.scss` file. ```js // Change import '../sass/frontend.scss'; // To import '../postcss/frontend.pcss'; ``` ## Developing Locally To work on the project locally (with Eslint, Stylelint & Prettier active), run: ```bash yarn dev ``` Or run with watcher & browserSync ```bash yarn dev:watch ``` This will open a browser, watch all files (php, scss, js, etc) and reload the browser when you press save. ## Building for Production To create an optimized production build (purged with PurgeCSS & fully minified CSS & JS files), run: ```bash yarn prod ``` Or run with watcher & browserSync ```bash yarn prod:watch ``` ## More Scripts/Tasks ```bash # To scan for text-domain functions and generate WP POT translation file yarn translate # To find problems in your JavaScript code yarn eslint # To find fix problems in your JavaScript code yarn eslint:fix # To find problems in your sass/css code yarn stylelint # To find fix problems in your sass/css code yarn stylelint:fix # To make sure files in assets/src/js are formatted yarn prettier # To fix and format the js files in assets/src/js yarn prettier:fix ``` ## Package.json dependencies <table> <thead> <tr> <th>Depedency</th> <th>Description</th> <th>Version</th> </tr> </thead> </tbody> <thead> <tr> <th></th> <th>BabelJS</th> <th></th> </tr> </thead> <tbody> <tbody> <tr> <td>babel-loader</td> <td>This package allows transpiling JavaScript files using Babel and webpack.</td> <td>8.2.2</td> </tr> <tr> <td>@babel/core</td> <td>Babel compiler core for the Webpack babel loader</td> <td>7.12.10</td> </tr> <tr> <td>@babel/preset-env</td> <td>A smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms are needed by your target environment(s).</td> <td>7.12.11</td> </tr> </tbody> <thead> <tr> <th></th> <th>Eslint & prettier</th> <th></th> </tr> </thead> <tbody> <tr> <td>eslint</td> <td>Find and fix problems in your JavaScript code with a linting configuration</td> <td>7.17.0</td> </tr> <tr> <td>eslint-webpack-plugin</td> <td>Make eslint work with Webpack during compiling</td> <td>2.4.1</td> </tr> <tr> <td>@babel/eslint-parser</td> <td>Allows you to lint ALL valid Babel code with Eslint</td> <td>7.12.1</td> </tr> <tr> <td>@wordpress/eslint-plugin</td> <td>ESLint plugin including configurations and custom rules for WordPress development.</td> <td>7.4.0</td> </tr> <tr> <td>prettier</td> <td>For automatic JavaScript / TypeScript code formatting</td> <td>2.2.1</td> </tr> <tr> <td>eslint-plugin-prettier</td> <td>Runs Prettier as an ESLint rule and reports differences as individual ESLint issues.</td> <td>3.3.1</td> </tr> </tbody> <thead> <tr> <th></th> <th>CSS & PurgeCSS</th> <th></th> </tr> </thead> <tbody> <tr> <td>css-loader</td> <td>Needed in Webpack to load and process CSS</td> <td>5.0.1</td> </tr> <tr> <td>mini-css-extract-plugin</td> <td>Webpack normally loads CSS from out JavaScript. Since we're working with WordPress we need the CSS files separately. This will make that happen.</td> <td>1.3.3</td> </tr> <tr> <td>purgecss-webpack-plugin</td> <td>Scans your php (template) files to remove unused selectors from your css when in production mode, resulting in smaller css files.</td> <td>3.1.3</td> </tr> </tbody> <thead> <tr> <th></th> <th>PostCSS & Autoprefixer</th> <th></th> </tr> </thead> <tbody> <tr> <td>postcss</td> <td>To make use of great tools during post CSS transformation</td> <td>8.2.4</td> </tr> <tr> <td>postcss-loader</td> <td>Loader to process CSS with PostCSS.for Webpack</td> <td>4.1.0</td> </tr> <tr> <td>autoprefixer</td> <td>To parse CSS and add vendor prefixes to CSS rules using values from Can I Use.</td> <td>10.2.1</td> </tr> </tbody> <thead> <tr> <th></th> <th>If we use Sass+PostCSS</th> <th></th> </tr> </thead> <tbody> <tr> <td>sass</td> <td>To make Sass work with node</td> <td>1.32.2</td> </tr> <tr> <td>sass-loader</td> <td>Sass loader for Webpack to compile to CSS</td> <td>10.1.0</td> </tr> <tr> <td>node-sass-magic-importer</td> <td>To do lot of fancy things with Sass @import statements</td> <td>5.3.2</td> </tr> </tbody> <thead> <tr> <th></th> <th>If we use PostCSS-only</th> <th></th> </tr> </thead> <tbody> <tr> <td>postcss-import</td> <td>To add an import feature like Sass, this can consume local files, node modules or web_modules</td> <td>14.0.0</td> </tr> <tr> <td>postcss-import-ext-glob</td> <td>Extends postcss-import path resolver to allow glob usage as a path</td> <td>2.0.0</td> </tr> <tr> <td>postcss-nested</td> <td>To unwrap nested rules like how Sass does it</td> <td>5.0.3</td> </tr> <tr> <td>postcss-nested-ancestors</td> <td>introduces ^& selector which let you reference any parent ancestor selector with an easy and customizable interface</td> <td>2.0.0</td> </tr> <tr> <td>postcss-advanced-variables</td> <td>Lets you use Sass-like variables, conditionals, and iterators in CSS</td> <td>3.0.1</td> </tr> </tbody> <thead> <tr> <th></th> <th>Stylelint</th> <th></th> </tr> </thead> <tbody> <tr> <td>stylelint</td> <td>Helps you avoid errors and enforce conventions in your styles</td> <td>1.32.2</td> </tr> <tr> <td>stylelint-scss</td> <td>Extra stylelint rules for Sass</td> <td>3.18.0</td> </tr> <tr> <td>stylelint-webpack-plugin</td> <td>Make stylelint work with webpack during compiling</td> <td>2.1.1</td> </tr> </tbody> <thead> <tr> <th></th> <th>BrowserSync</th> <th></th> </tr> </thead> <tbody> <tr> <td>browser-sync</td> <td>Synchronising URLs, interactions and code changes across devices and automatically refreshes all the browsers on al devices</td> <td>2.26.13</td> </tr> <tr> <td>browser-sync-webpack-plugin</td> <td>Makes it possible to use BrowserSync in Webpack</td> <td>2.3.0</td> </tr> </tbody> <thead> <tr> <th></th> <th>Optimize images</th> <th></th> </tr> </thead> <tbody> <tr> <td>image-minimizer-webpack-plugin</td> <td>Uses imagemin to optimize your images.</td> <td>2.2.0</td> </tr> <tr> <td>imagemin-gifsicle</td> <td>Needed for the image optimizer to work with GIF</td> <td>7.0.0</td> </tr> <tr> <td>imagemin-jpegtran</td> <td>Needed for the image optimizer to work with JPEG</td> <td>7.0.0</td> </tr> <tr> <td>imagemin-optipng</td> <td>Needed for the image optimizer to work with PNG</td> <td>8.0.0</td> </tr> <tr> <td>imagemin-svgo</td> <td>Needed for the image optimizer to work with SVG</td> <td>8.0.0</td> </tr> </tbody> <thead> <tr> <th></th> <th>Webpack </th> <th></th> </tr> </thead> <tbody> <tr> <td>webpack</td> <td>The Webpack bundler</td> <td>5.12.3</td> </tr> <tr> <td>webpack-cli</td> <td>Webpack CLI provides a flexible set of commands for developers</td> <td>4.3.1</td> </tr> <tr> <td>webpackbar</td> <td>Get a real progress bar while development which also includes a profiler</td> <td>5.0.0-3</td> </tr> </tbody> <thead> <tr> <th></th> <th>Translation</th> <th></th> </tr> </thead> <tbody> <tr> <td>wp-pot-cli</td> <td>Scans all the files and generates .pot file automatically for i18n and l10n</td> <td>1.5.0</td> </tr> </tbody> <thead> <tr> <th></th> <th>Misc</th> <th></th> </tr> </thead> <tbody> <tr> <td>glob-all</td> <td>Provides a similar API to glob, however instead of a single pattern, you may also use arrays of patterns. Used to glob multiple files in one of the configuration files</td> <td>3.2.1</td> </tr> </tbody> </table> ## Workflow's Changelog Documenting this project's progress... #### January 15, 2021 * refactor: Migrated from NPM to Yarn for speed, `install` went from 183.281s to 65.76s-90.02s. * fix: Added `eslint-plugin-prettier` to make yarn work with eslint * refactor: DRY - added `config.base.js` file to facilitate configurations for both dev/prod #### January 14, 2021 * feat: Be able to choose to work with `Sass+PostCss` or `PostCSS` only * feat: Added npx CLI build script + docs * fix: Make sure eslint & stylelint ignores vendor and testing folders * refactor: Move BrowserSync settings to "projectFiles" constant #### January 13, 2021 * refactor: Make sourcemap customizable from `webpack.config.js` #### January 12, 2021 * feat: [Prettier](https://prettier.io/) & [ImageMinimizerWebpackPlugin](https://webpack.js.org/plugins/image-minimizer-webpack-plugin/) * feat: [BrowserSync](https://browsersync.io/), [WP-Pot](https://github.com/wp-pot/wp-pot-cli) & [WebpackBar](https://github.com/nuxt-contrib/webpackbar) * feat: `README.md` file ___ [__Buy me a coffee! :coffee:__](https://www.buymeacoffee.com/brandonkramer)

Developer Tools WordPress Themes & Plugins
103 Github Stars
wp-vite-starter
Open Source

wp-vite-starter

<div align="center"> <a href="https://vitejs.dev/"> <img width="200" height="200" hspace="10" src="https://vitejs.dev/logo.svg" alt="vite logo" /> </a> <h1>WP ViteJS 4 starter kit</h1> <p> Simple lightweight starter kit to make use of Vite's blazing fast and efficient frontend build tool for WordPress plugin and theme development. Comes with packages that provide front-end & back-end (PHP) utilities. The "src" folder includes JS, PostCSS, images, fonts, SVG and a gutenberg block as examples. You can read more about ViteJS on [vitejs.dev](https://vitejs.dev) </p> </div> --- ## πŸ“š Table of contents - [🏁 Quick start](#-quick-start) - [πŸ’» Other commands](#-other-commands) - [πŸ“¦ What's inside](#-whats-inside) - [πŸš€ Setup Vite dev server](#-setup-vite-dev-server) - [πŸŽ’ Other configurations](#-other-configurations) ## 🏁 Quick start Install packages and autoloader. ``` yarn install composer install ``` Build our assets into the 'build' folder. ```shell yarn build ``` ## πŸ’» Other commands Build assets in `development` mode. ```shell yarn build-dev ``` Builds assets in real-time and watches over files. ```shell yarn watch yarn watch-dev ``` Start ViteJS dev server. ```shell yarn start ``` ## πŸ“¦ What's inside The idea is to keep the starter kit simple so additional things can be added for different projects, and so it can be integrated into different theme and plugin structures and maintained through node/composer packages. ### ViteJS Config The config is extending a base config from the `@wp-strap/vite` package through a plugin which is opinionated and configured for WordPress development which can be overwritten. It ensures the following: - Updates/refreshes the dev server (HMR/Hot Module Replacement) when a change is made inside PHP files - Encapsulates JS bundles to prevent mix-up of global variables (with other plugins/themes) after minification - Collects images, SVG and font files from folders and emits them to make them transformable by plugins - Esbuild is configured to make ReactJS code work inside `.js` files instead of the default `.jsx` - Esbuild for minification which is turned off for `development` mode - Esbuild sourcemaps are added for `development` mode - JS entries are automatically included from first-level folders inside the `src` folder using fast-glob (e.g., js/my-script.js, blocks/my-block.js). - CSS entries are also automatically included in the same way, bundled and compiled without importing them into JS files which is more suitable for WordPress projects. - [Vite Plugin Image Optimizer](https://github.com/FatehAK/vite-plugin-image-optimizer) is included that optimizes images and SVG files that we emit ### PostCSS config PostCSS is added through the Vite base config file and is currently configured with the following: - [TailwindCSS](https://tailwindcss.com/docs/installation) to add a utility-first CSS framework that scans all of our files, and only generate styles and classes that we use. - [TailwindCSS nesting](https://tailwindcss.com/docs/using-with-preprocessors#nesting) to unwrap nested rules similar to SASS. - [PostCSS import](https://github.com/postcss/postcss-import) that can consume local files, node modules or web_modules using the `@import` rule. - [Autoprefixer](https://github.com/postcss/autoprefixer) to parse CSS and add vendor prefixes to CSS rules using values from Can I Use. - [PostCSS combine duplicated selectors](https://github.com/ChristianMurphy/postcss-combine-duplicated-selectors) that detects and combines duplicated CSS selectors. ### TailwindCSS config TailwindCSS is added through the PostCSS config file and is currently only configured with the following: - Paths to find TailwindCSS classes for optimization. This will make sure it only generates styles that are needed. - A prefix that will be added to all of Tailwind’s generated utility classes. This can be really useful to prevent naming conflicts with other themes and plugins. [Read here](https://tailwindcss.com/docs/configuration) more about all the cool stuff you can configure with Tailwind. ### PHP / Composer Composer includes the `wp-strap/vite` package that exposes some classes that helps you generate asset URLs from the manifest.json that you can register or enqueue. It also enables you to use HMR (hot module replacement) when the ViteJS dev server is running. The classes follow PSR practices with interfaces, so it can be included trough OOP with dependency injection and IoC containers. It also provides a Facade class that allows you to use static methods anywhere you like if that's your jam. Example with using the facade: ```php use WPStrap\Vite\Assets; // Resolves instance and registers project configurations Assets::register([ 'dir' => plugin_dir_path(__FILE__), // or get_stylesheet_directory() for themes 'url' => plugins_url(\basename(__DIR__)) // or get_stylesheet_directory_uri() for themes 'version' => '1.0.2', // Set a global version (optional) 'deps' => [ 'scripts' => [], 'styles' => [] ] // Set global dependencies (optional) ]); // Listens to ViteJS dev server and makes adjustment to make HMR work Assets::devServer()->start(); // returns: https://your-site.com/wp-content/plugins/your-plugin/build/js/main.oi4h32d.js Assets::get('js/main.js') // Alternatively you can use these as well which will be more targeted to specific folders // and for some of the methods you don't need to write the file extension Assets::js('main') Assets::css('main') Assets::image('bird-on-black.jpg') Assets::svg('instagram') Assets::font('SourceSerif4Variable-Italic.ttf.woff2') // Example of enqueuing the scripts add_action('wp_enqueue_scripts', function () { // You can enqueue & register the tradtional way using global data wp_enqueue_script('my-handle', Assets::js('main'), Assets::deps('scripts'), Assets::version()); wp_enqueue_style('my-handle', Assets::css('main'), Assets::deps('styles'), Assets::version()); // Or use a more simple method that includes the global deps & version Assets::enqueueStyle('my-handle', 'main'); // Which also comes with some handy chained methods Assets::enqueueScript('my-handle', 'main', ['another-dep']) ->useAsync() ->useAttribute('key', 'value') ->localize('object_name', ['data' => 'data']) ->appendInline('<script>console.log("hello");</script>'); }); ``` Example with using instances ```php use WPStrap\Vite\Assets; use WPStrap\Vite\AssetsService; use WPStrap\Vite\DevServer; // Instantiates the Asset service and registers project configurations $assets = new AssetsService(); $assets->register([ 'dir' => plugin_dir_path(__FILE__), // or get_stylesheet_directory() for themes 'url' => plugins_url(\basename(__DIR__)) // or get_stylesheet_directory_uri() for themes ]); // Listens to ViteJS dev server and makes adjustment to make HMR work (new DevServer($assets))->start(); $assets->get('js/main.js'); $assets->js('main') $assets->css('main') $assets->image('bird-on-black.jpg') $assets->svg('instagram') $assets->font('SourceSerif4Variable-Italic.ttf.woff2') // Traditional wp_enqueue_script('my-handle', $this->assets->js('main'), $this->assets->deps('scripts'), $this->assets->version()); wp_enqueue_style('my-handle', $this->assets->css('main'), $this->assets->deps('styles'), $this->assets->version()); // Custom methods $this->assets->enqueueStyle('my-handle', 'main'); $this->assets->enqueueScript('my-handle', 'main', ['another-dep']) ->useAsync() ->useAttribute('key', 'value') ->localize('object_name', ['data' => 'data']) ->appendInline('<script>console.log("hello");</script>'); // You can also use the facade based on this instance. Assets::setFacade($assets); Assets::get('css/main.css'); ``` Example with using instances wih functions ```php use WPStrap\Vite\AssetsInterface; use WPStrap\Vite\AssetsService; use WPStrap\Vite\DevServer; function assets(): AssetsInterface { static $assets; if(!isset($assets)) { $assets = (new AssetsService())->register([ 'dir' => plugin_dir_path(__FILE__), 'url' => plugins_url(\basename(__DIR__)), 'version' => '1.0.0' ]); } return $assets; } (new DevServer(assets()))->start(); add_action('wp_enqueue_scripts', function () { // Traditional wp_enqueue_script('my-handle', assets()->js('main'), assets()->deps('scripts'), assets()->version()); wp_enqueue_style('my-handle', assets()->css('main'), assets()->deps('styles'), assets()->version()); // Using custom methods assets()->enqueueStyle('my-handle', 'main'); assets()->enqueueScript('my-handle', ['Main', 'main'], ['another-dep']) ->useAsync() ->useAttribute('key', 'value') ->localize('object_name', ['data' => 'data']) ->appendInline('<script>console.log("hello");</script>'); }); ``` Example with using the League Container ```php use League\Container\Container; use WPStrap\Vite\Assets; use WPStrap\Vite\AssetsInterface; use WPStrap\Vite\AssetsService; use WPStrap\Vite\DevServer; use WPStrap\Vite\DevServerInterface; $container = new Container(); $container->add(AssetsInterface::class)->setConcrete(AssetsService::class)->addMethodCall('register', [ 'dir' => plugin_dir_path(__FILE__), 'url' => plugins_url(\basename(__DIR__)) ]); $container->add(DevServerInterface::class)->setConcrete(DevServer::class)->addArgument(AssetsInterface::class); $assets = $container->get(AssetsInterface::class); $devServer = $container->get(DevServerInterface::class); $devServer->start(); $assets->get('main/main.css'); // You can also set a PSR container as a facade accessor Assets::setFacadeAccessor($container); Assets::get('main/main.css') ``` ### DevServer `Assets::devServer()->start(3000');` OR `(new DevServer($assets))->start('3000');` The dev server class is responsible for listening to the ViteJS dev server using CURL, checking if it's running locally on port 3000 which you can adjust using the optional param from the start() method as seen above. If it can validate the dev server is running, it will inject viteJS scripts provided from the dev server, filter all asset urls and load source files instead (from the assets::get(), assets:css(), assets::js() etc. methods), and alter the script tags to make sure the source files can be loaded as modules for HMR. **This should only be run on local/dev environments.** As it's using CURL on each request, so you don't want to run this on production. ## πŸš€ Setup vite dev server ### Setting it up with DDEV Within DDEV you need to make sure the port we'll use is being exposed and routed accordingly. We will be using port 3000 which is set by default in the ViteJS config. This can be done with this simple add-on: https://github.com/wp-strap/ddev-vite Let's assume you've done the following: - Git clone `wp-vite-starter` into `wordpress/wp-content/plugins` with the folder name `wp-vite-starter` - Run the `yarn install`, `composer install` and `yarn build` commands to install all the packages and build + compile the example files from the repo - Created a plugin file called wp-vite-starter.php in the plugin folder with the following basic contents: (and activated the plugin) ```php <?php /* Plugin Name: WP Vite Starter Description: Playground Version: 1.0.0 */ use WPStrap\Vite\Assets; /** * Require composer autoloader. */ require 'vendor/autoload.php'; Assets::register([ 'dir' => plugin_dir_path(__FILE__), 'url' => plugins_url(\basename(__DIR__)) ]); Assets::devServer()->start(); \add_action('wp_enqueue_scripts', function () { wp_enqueue_script('main', Assets::js('main')); wp_enqueue_style('main', Assets::css('main')); }); ``` You now need to spin up the Vite dev server using SSH so it runs on the local/docker environment using `ddev ssh`: ```shell ddev ssh cd wordpress/wp-content/plugins/wp-vite-starter yarn install yarn start ``` Refresh the browser while you're on wp-vite-playground.ddev.site and you should be able to see a script on https://wp-vite-playground.ddev.site:3000/@vite/client The `Assets::devServer()->start()` function will listen to this page and inject the scripts into the site. The dev server + HMR should be working now: If you make a change in src/css/main.pcss it should automatically inject the changes into the page without refreshing the page: ![hmr-gif](https://wpstrap.com/docs/git-vite-js-hmr.gif) ## πŸŽ’ Other configurations The following things can also be configured: ### Change rules for asset files that are copied With the `userOptions.assets.rules` param you're able to add additional asset folders by adding additional test rules aside to images/svg/fonts, and you can customize the default ones as well: ```js viteWPConfig({ assets: { rules: { images: /png|jpe?g|svg|gif|tiff|bmp|ico/i, svg: /png|jpe?g|svg|gif|tiff|bmp|ico/i, fonts: /ttf|woff|woff2/i } } }) ``` ### Customize header & footer of bundle encapsulation You can customize the way it encapsulates bundles by using the `userOptions.bundles` param: ```js viteWPConfig({ bundles: { banner: '/*My Custom Project*/(function(){', // Adds a comment before each bundle footer: '})();' } }) ``` ### Change src and build folders With the `root` and `outDir` params you're able to change the source and build folders, name them differently or change the paths. ```js viteWPConfig({ root: 'assets', outDir: 'dist', }) ``` You will need to change these in the PHP register method as well. ```php $assets->register([ /* .... */ 'root' => 'assets', 'outDir' =>> 'dist' ]); ``` ### Use an entry point and setup domain folder structure Aside to `root` and `outDir` you can define and set an `entry` which will try to find asset files from this entry point inside the `root` folder. ```js viteWPConfig({ root: 'src', outDir: 'build', entry: 'Static', // <----- }) ``` For example if you set `root` to "src" and `entry` to "Static" like the above, you're able to maintain different bundles within different domain folders and mix it up with PHP files: ``` my-custom-plugin/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ Blocks/ β”‚ β”‚ β”œβ”€β”€ Blocks.php β”‚ β”‚ └── Static/ β”‚ β”‚ β”œβ”€β”€ css/ β”‚ β”‚ β”œβ”€β”€ js/ β”‚ β”‚ └── images/ β”‚ β”œβ”€β”€ Admin/ β”‚ β”‚ β”œβ”€β”€ Admin.php β”‚ β”‚ └── Static/ β”‚ β”‚ β”œβ”€β”€ css/ β”‚ β”‚ β”œβ”€β”€ js/ β”‚ β”‚ └── images/ β”‚ β”œβ”€β”€ Main/ β”‚ β”‚ β”œβ”€β”€ Main.php β”‚ β”‚ └── Static/ β”‚ β”‚ β”œβ”€β”€ css/ β”‚ β”‚ β”œβ”€β”€ js/ β”‚ β”‚ └── images/ β”œβ”€β”€ build/ β”‚ β”œβ”€β”€ css/ β”‚ β”œβ”€β”€ js/ β”‚ β”œβ”€β”€ images/ ``` when using this approach you can use the PHP asset functions a bit differently: ```php // When you use the get method you need to call the whole path Assets::get('Main/Static/js/main.js') // When using these methods you are able to use the first param to point to the domain and second param to point to the file. Assets::js('Blocks', 'example-block') Assets::css('Main', 'main') Assets::image('Admin', 'bird-on-black.jpg') Assets::svg('Main', 'instagram') Assets:enqueueScript('my-handle', ['Admin', 'admin-page']) Assets:enqueueStyle('my-handle', ['Blocks', 'example-block']) $assets->js('Blocks', 'example-block') $assets->css('Main', 'main') $assets->image('Admin', 'bird-on-black.jpg') $assets->svg('Main', 'instagram') $assets->enqueueScript('my-handle', ['Admin', 'admin-page']) $assets->enqueueStyle('my-handle', ['Blocks', 'example-block']) ``` The entry is set to "Static" by default inside the php register method, when you want to name this differently, you need to configure it here as well. ```php $assets->register([ /* .... */ 'entry' =>> 'Assets' ]); ``` ### External Dependencies This is inspired by [kucrut](https://github.com/kucrut); If you have a JavaScript package that relies on WordPress modules, such as `@wordpress/i18n`, you have the option to define them as externals using the `rollup-plugin-external-globals` plugin and the `wpGlobals()` function ```shell yarn add -D rollup-plugin-external-globals ``` ```js import wpGlobals from '@wp-strap/vite'; import externalGlobals from 'rollup-plugin-external-globals'; export default defineConfig({ /* ViteJS plugins */ plugins: [ /* External globals */ externalGlobals({ ...wpGlobals(), ...{'some-registered-script-handle': 'GlobalVar'} }) ], }); ```

WordPress Themes & Plugins
32 Github Stars