Skip to content
This repository has been archived by the owner on Aug 24, 2021. It is now read-only.

jessedobbelaere/fork-cms-webpack-boilerplate

Repository files navigation

Fork CMS theme boilerplate using Webpack 5

Dependabot Status Dependency Status DevDependency Status PRs Welcome

Simple, opiniated and performance-optimized boilerplate for Fork CMS themes supporting Typescript, React, ESNext, TailwindCSS, PostCSS, Dynamic Imports and Hot Module replacement using Webpack 5.


✨ Opiniated list of features I want webpack to do

  • Code splitting with Dynamic Imports support aka lazy loading. Load only the code/resources needed when they are needed, without render blocking.
  • Development/Production. In local dev I want fast builds via in-memory webpack-dev-server, and for production builds I want every possible optimization. Thus, separate dev and prod config and builds.
  • Hot Module Replacement (HMR) during local dev. As I make changes to my Javascript, CSS or templates I want the webpage to seamlessly refresh. This speeds development tremendously: just say no to the Reload button.
  • Dynamic Code Splitting. I don't want to manually define Javascript chunks in a config file. Webpack needs to sort that out for me.
  • Cache busting via manifest.json. This allows us to set a long expiry date for static assets, while also ensuring that they are automatically cache busted if they change.
  • Image optimization. Images are by far the largest thing on most web­pages, so it makes sense to opti­mize them via auto­mat­ed tools like mozjpeg, optipng, svgo, etc.
  • Typescript support.
  • ES2017/ES2018/.../ESNext support using Babel.
  • React support. jQuery is so 2010. React is my frontend framework of choice. I use it for highly interactive interfaces, while using vanilla JS for standard behaviour.
  • PostCSS. Think of it as the Babel of CSS, to add advanced features to CSS, or use upcoming CSS features now.
  • Tailwind CSS. While I have used BEM/ITCSS for years, I started to love the advantages of utility-css and rapidly building UI's without leaving your html code, without naming things, and without browsing endless files of css to find conflicting rules. Very opiniated though ;-)
  • PurgeCSS scans the theme folder for classnames that are actually used, and removes the unused styles, causing a very small css file to be generated! Perfect for tailwind css.
  • Prettier 💄 to automatically format js/css/html code.
  • ESLint to statically analyze and help find problems in the js/ts code.
  • Jest as a js test runner.
  • Automatic .webp creation. Chrome, Edge, and Fire­fox all are sup­port­ing .webp, a for­mat that is more effi­cient than JPEG.
  • Offline Com­pres­sion of sta­t­ic resources.  We can pre-com­press our sta­t­ic resources into .gz files that our web­serv­er can auto­mat­i­cal­ly serve up to clients that accept them

Todo:

  • Critical CSS. This makes your initial page loads significantly faster.
  • Workbox Service Worker. We can leverage Google's Workbox project to generate a Service Worker that will know about our project's assets.
  • Modern & Legacy JS Bundles. I want to deploy modern ES2015+ JS modules to the 75%+ of browsers that support it, while gracefully providing a fallback legacy bundle for legacy browsers (with transpiled code and polyfills). Not implemented yet.

Why? You need some basic tooling to get started with a current-generation frontend web development project. You may, or may not, be sure if you need all the bells and whistles but you'd much rather have a setup that is easily extensible and does the basics (build a distribution package, bundle JS, transpile ES2019 into ES5) than starting from zero.

🔧 Installation

Just clone or download this repository into your Fork CMS Themes directory and start hacking away!

  1. Copy this boilerplate to your src/Frontend/Themes/MyThemeName folder in your new Fork CMS project.
  2. Install dependencies by running npm install in your theme directory.
  3. Run npm run build and browse to your website.
  4. When doing local development, run npm run start to start a dev server which you can visit on http://localhost:3000. It proxies your local fork cms website (assuming its running on http://localhost:80, but you can change that in webpack.development.js.

📦 Available commands

  • npm run build - create a production-ready build in the dist folder.
  • npm run build:dev - create a development build.
  • npm run start - start the webpack-dev-server with HMR.
  • npm run prettier - Execute Prettier on your JS/CSS files.
  • npm run prettier-check - Check for Prettier on your JS/CSS files.
  • npm run test - Test Javascript code using Jest
  • npm run lint - Lint your code using ESLint
  • npm run test - Run js unit tests with Jest

The build operation will clear the dist folder and compile/transpile and place fresh files in the dist folder.

The npm run start command will use webpack-dev-server to start the dev server at 0.0.0.0:3000. Webpack will use Core/Js/app.ts as the entrypoint and from there it will import the app.css file and other components and dependencies. With the server active, any files you work on and update will trigger a live update using Hot Module Replacement (no refreshing!).

🔨 Fork CMS changes needed

Manifest-based asset versioning in Symfony & Fork CMS

Each file generated by Webpack contains a chunkhash for [long-term caching](https://webpack.js.org/guides/caching/). Webpack generates a `dist/manifest.json` file, mapping all source file names to their corresponding output file. For example:
{
  "app.css": "/src/Frontend/Themes/MyTheme/dist/app.89b2d31313389a466bb524e9051378bc.css",
  "app.js": "/src/Frontend/Themes/MyTheme/dist/app.7532415ade478926494f.js",
  "vendor.js": "/src/Frontend/Themes/MyTheme/dist/vendor.a607ffefbb3865c31743.js"
}

The random-looking part of the paths is called "chunk hash" in Webpack and it's a hash of the file contents. This is the best strategy for long-term asset caching, because the hash, and therefore the asset path, will change as soon as you make any change in the asset file, busting any existing cache. If we do not change our css or vendor code, the hash will stay the same after a rebuild and no cache busting is needed.

To be able to include your .js and .css files in your Head.html.twig regardless of the version, you can use the Asset component of Symfony to manage the assets. Define a new json_manifest_path asset config option:

# app/config/config.yml
framework:
    # ...
    assets:
        json_manifest_path: '%kernel.root_dir%/../src/Frontend/Themes/MyTheme/dist/manifest.json'

Then, use the asset() function in your Twig files:

<link rel="stylesheet" type="text/css" href="{{ asset('app.css') }}">

<script defer src="{{ asset('vendor.js') }}"></script>
<script defer src="{{ asset('app.js') }}"></script>

The new version strategy will turn that link into <link href="/src/Frontend/Themes/MyTheme/dist/app.89b2d31313389a466bb524e9051378bc.css"> and it will update it as soon as you change the original asset file and rebuild using Webpack.

Learn more about Webpack?

About

Fork CMS theme boilerplate with ES2020, PostCSS, Typescript, React, Tailwind and Hot Module replacement using Webpack 5 🚀

Topics

Resources

Stars

Watchers

Forks