"webpack": "^5.53.0"
- How to launch
- What is this?
- Out of the box
- Pre-commit
- Conventional Changelog
- Differences between
dev
andprod
- How to modify
- Storybook, huh?
- Dependencies
- License
git clone
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
to update the origin remote with your own repository /git remote rm origin
to remove the origin remotenpm i
npm start
/npm run dev
to run a regular webpack environment;npm run sb
to run Storybook- Navigate to http://localhost:3000/ or to http://localhost:4000/, if you run Storybook
npm run build
to createdist
for production;npm run build:sb
to create a Storybook build
P.S. Don't forget to remove extra info like keywords, repository, packages you won't be using etc. from package.json
.
Webpack Modules or WM is an easy and robust webpack config to handle anything you can imagine, using the best practices. Now with optional Storybook.
It was created as a clean, versatile, modern and "fresh" frontend environment. You and only you are in control of which techonologies to use here and how, however, WM provides an initial setup, which will be described further.
If you work with JS frameworks like React, Next.js, Vue.js etc., consider using their dedicated environments, provided by their developers.
I extended such environment for Next.js with a few useful things, while using and updating the original dependencies. You can find it here:
Here what's included in the initial Webpack Modules setup:
-
Separated webpack config files
webpack.common.js
has configuration, used in bothdev
andprod
config fileswebpack.dev.js
is responsible for development environmentwebpack.prod.js
is responsible for production environment
npm start
andnpm run dev
run thedev
config.npm run build
runs theprod
config. -
Separated JS files (entries) for every page
Stored in
src/entries
.Responsible for providing content and JS code to webpack. These files represent pages.
They should have the same name as the templates of the pages in
src/pages
, e.g.,contact.pug
insrc/pages
andcontact.js
insrc/entries
.If you want to use the same JS file for different pages, you have to use paired names in
src/pages
, e.g.,contact+about.pug
means that "Contact" page will be usingabout.js
file, which was originally created for "About" page. -
TypeScript support
If you see a JS file, it can be a TS file. Yes, that simple.
Make sure to set up a
tsconfig.json
to your liking. -
Pug template engine
Used in
src/components
andsrc/pages
.Responsible for rendering HTML content and creating pages.
It can require JSON files to use their data inside of its templates. It is the main usage concept in Webpack Modules. We use
data/index.json
inside of a component to provide content and automatically generated Sass/SCSS modules insidestyles/index.json
to render the right CSS classnames.Here you may find out more about Pug.
-
Sass/SCSS and PostCSS
Used in
src/components
andsrc/styles
. PostCSS has a dedicated config file:postcss.config.js
.Responsible for adding included (in
src/entries
JS files), optimized and processed styles to a page.Features used: Autoprefixer, Sass/SCSS modules.
Features work automatically. Autoprefixer uses
.browserslistrc
. For Sass/SCSS modules dedicatedindex.json
files are created inside of the components'styles
folders, which you then need to use inside of the components' Pug templates. If you want some of the classnames to stay global, you can use:global
flag in a stylesheet, e.g.,:global .container { display: flex; }
or you can put a stylesheet inside thesrc/styles/global
folder and/or import it insidesrc/styles/global/index.scss
. You can control, which Sass/SCSS files webpack is using insidesrc/entries
JS files. -
Bulma and base/global styles
Used in
src/styles
.Responsible for resetting browser styles, providing functions, variables, mixins and other helpers for flexible, yet generic, layout creation.
Bulma modules used: Container, Columns, Section.
You can go through all files inside
src/styles
to have an idea of what they are and what they for. You can control, which Sass/SCSS files webpack is using insidesrc/entries
JS files. -
Separated CSS files for every page
Every JS file in
src/entries
represents a different page. Include needed styles in each one of these files and webpack will create different CSS stylesheets for every page automatically. -
Assets
Used in
src/components
andsrc/assets
.You should have your assets scoped inside a module, however, there are some cases, where it is not possible. In these cases you should make use of
src/assets
folder.Use
require()
in Pug to import scoped assets and where it is not possible — use a regular string, while having needed assets insidesrc/assets
directory.Sass/SCSS has no problems with either scoped or global assets.
-
WebP
PNG and JPG/JPEG images are automatically converted into WebP format on
npm run build
.File extension does not change, so you will see regular
.png
,.jpg
,.jpeg
indist
folder, which, in fact, will be.webp
.It can be disabled and switched to a regular image minification in
webpack.prod.js
. -
SVG sprites
Automatically generated from the files in
src/assets/icons
and stored insrc/assets/images
.A CLI tool is responsible for it, which is configured in
package.json
sprite
script. It can be run manually withnpm run sprite
command or automatically, every time you run any other script. -
Storybook (🆕 in 2.0.0)
The best UI non-framework is here! Integrated and configured, while still being optional and flexible just as you always wanted. All the info you need is located right here. And here is what you need to know about Storybook in Webpack Modules.
npm run sb
to run it.npm run build:sb
to build it.
Webpack Modules has a pre-commit feature, based on Husky and lint-staged. It looks like this:
lint-staged in package.json
:
"lint-staged": {
"src/**/*.{css,sass,scss}": [
"pretty-quick --pattern './src/**/*.{css,sass,scss}'",
"stylelint './src/**/*.{css,sass,scss}' --fix"
],
"src/**/*.{js,jsx}": [
"pretty-quick --pattern './src/**/*.{js,jsx}'",
"eslint './src/**/*.{js,jsx}' --fix"
],
"src/**/*.pug": [
"pretty-quick --pattern './src/**/*.pug'"
]
}
pre-commit in .husky/pre-commit
:
npm run lint
And it can be configured in any preferrable way. Enjoy!
I recommend using the Conventional Commits approach for committing your work to Git. If you use it, your commits will be very descriptive and themselves could tell the story of your project to anyone.
On top of this Conventional Changelog was built. I included the CLI version of it here, in the version
npm script. It generates a nice CHANGELOG.md
for your nice commits.
The recommended commit approach for using this would be:
- Make changes
- Commit those changes
- Run the
npm version [patch|minor|major]
command (more about it here) - Push
The npm version
script will automatically bump the project's version in package.json
and commit it, together with our newly generated CHANGELOG.md
.
- Automatically cleans
dist
folder. Does not move it to the trash - Uses
webpack-dev-server
= Hosts a server and watches for changes - Webpack optimization features disabled
- Runs ESLint and Stylelint webpack plugins
- JS source maps are inlined. No source maps for CSS
- Does not minimize or optimize JS and CSS
- Does not minimize or optimize images, including SVG sprites or any other SVG
- Automatically cleans
dist
folder. Moves it to the trash - Does not use any server = Runs one time and stops
- Webpack optimization features enabled
- Does not run ESLint and Stylelint webpack plugins
- JS and CSS source maps have separated files
- Minimizes and optimizes JS and CSS
- Minimizes and optimizes all images, including SVG sprites or any other SVG. By default converts all PNG and JPG/JPEG images into WebP format without changing their extensions. Can be disabled and switched to a regular image minification in
webpack.prod.js
- Splits JS into functional, optimized and cached pieces, using
cacheGroups
- Creates a Service Worker
In order to be able to understand and modify webpack config files, you have to be acquainted with webpack principles. You can do it by accessing "Guides" or "Configuration" sections of webpack documentation.
To change loaders, plugins or their options you have to search for their analogues or documentation on the internet. Webpack Modules does not use any custom logic (only a few helper functions) in webpack config, so you should be able to easily change it to your needs, having option to completely override the whole functionality and concept.
Yes, Storybook! In order to make it work I had to rack my brain a bit, but the result was definitely worth it. What we have is two almost absolutely separated environments being Webpack Modules with its webpack configs and Storybook with its webpack configs (hidden in its packages, but available through its config files in the .storybook
folder). The reason we need two of them is that Storybook never was about building websites, it is about showing them, while Webpack Modules being able to show websites is everything about building them.
In order to deliver the best experience possible to our clients and to our non-frontend colleagues we have to make an effort to help them feel welcomed and Storybook does exactly that.
To make it work with WM I made use of the storypug addon. While being quite simple, it is powerful and is the base of this integration, so make sure to check out how to work with it.
For the presentation purposes I've extended the basic page/components example. Now we also have the 04-pages
folder in components
. This folder exists exclusively for Storybook. This way we have a place to display components inside pages. To check out how to work with WM and Storybook together you can and should browse the example components I've created. You can run WM instance and Storybook instance simultaneously to test the things out. I have also added Swiper with the slider
component to show a way to work with packages and dependencies.
Have in mind, that the way I work with Storybook and WM in the example is only an example. It is something you can use as a starting point, but I'm sure there is plenty space to make it better and that's what I will be doing in the future. Different projects have different requirements and that's where WM flexibility will come in handy.
You can use either WM or Storybook and even delete one of them, if you want, at all, if you don't need it. Just make sure you know what you are doing and it is exactly what you need 😉
As a final note I want to remind, that it is quite important, nice and useful to have a UI for display purposes, but it is much more important to have a working environment, which gets things done. And it is exactly the purpose of this integration, so while working on the website, don't forget to deliver some stories with it and while working on stories, don't forget, that the website won't build itself.
"devDependencies": {
"@babel/core": "^7.15.5",
"@prettier/plugin-pug": "^1.16.6",
"@storybook/addon-actions": "^6.4.0-alpha.34",
"@storybook/addon-essentials": "^6.4.0-alpha.34",
"@storybook/addon-links": "^6.4.0-alpha.34",
"@storybook/builder-webpack5": "^6.4.0-alpha.34",
"@storybook/html": "^6.4.0-alpha.34",
"@storybook/manager-webpack5": "^6.4.0-alpha.34",
"autoprefixer": "^10.3.5",
"babel-loader": "^8.2.2",
"conventional-changelog-cli": "^2.1.1",
"css-loader": "^6.3.0",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-prettier": "^4.0.0",
"eslint-webpack-plugin": "^3.0.1",
"fs": "^0.0.1-security",
"html-webpack-plugin": "^5.3.2",
"husky": "^7.0.2",
"image-minimizer-webpack-plugin": "^2.2.0",
"imagemin-gifsicle": "^7.0.0",
"imagemin-mozjpeg": "^9.0.0",
"imagemin-pngquant": "^9.0.2",
"imagemin-svgo": "^9.0.0",
"imagemin-webp": "^6.0.0",
"lint-staged": "^11.1.2",
"mini-css-extract-plugin": "^2.3.0",
"postcss": "^8.3.7",
"postcss-loader": "^6.1.1",
"postcss-modules": "^4.2.2",
"prettier": "^2.4.1",
"pretty-quick": "^3.1.1",
"pug": "^3.0.2",
"pug-runtime": "^3.0.1",
"pug3-loader": "^2.4.3",
"sass": "^1.42.1",
"sass-loader": "^12.1.0",
"storypug": "^1.0.0-rc.8",
"style-loader": "^3.3.0",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0",
"stylelint-order": "^4.1.0",
"stylelint-webpack-plugin": "^3.0.1",
"svgo": "^2.6.1",
"svgstore-cli": "^2.0.0",
"trash-cli": "^4.0.0",
"ts-loader": "^9.2.6",
"typescript": "^4.4.3",
"webpack": "^5.53.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.2.1",
"webpack-merge": "^5.8.0",
"workbox-webpack-plugin": "^6.3.0"
},
"dependencies": {
"bulma": "^0.9.3",
"normalize.css": "^8.0.1",
"swiper": "^7.0.6"
}
Copyright © 2021 Vlad Gerasimovich [email protected]
Licensed under the ISC license.