Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
Author: Vedees | Youtube guide (ru)
- separated configs for
dev
andprod
typescript / javascript
full supportsass / css
full support- full babel & postcss setup
- 0 dependencies
- the best optimization for your production
- easy webpack and babel customization
Everybody knows that developing runs on coffee! Thanks for your support!
# Download repository:
git clone https://github.com/vedees/webpack-template webpack-template
# Go to the app:
cd webpack-template
# Install dependencies:
# npm install
# or:
yarn
# Server with hot reload at http://localhost:8084/
# npm run start
# or:
yarn start
# Output will be at dist/ folder
# npm run build
# or:
yarn build
public/*.html
- HTML filessrc/app
- core appsrc/shared
- shared filessrc/shared/img
- images folder (! for html calls use correct path:static/img/some.jpg
)src/shared/misc
- misc files (i.g. favicon, sitemap, etc.)src/index.ts
- main app entity
Configs:
/babel-defines.js
- config for babel/webpack/webpack-pages.js
- config for html pages/webpack/webpack-defines.js
- config for entire webpack
Main entry point:
src/app/index.ts
- core entry point
Core webpack config from /webpack/webpack-defines.js
:
const PATHS = {
// path to the src dir
src: path.join(__dirname, '../src'),
// path to the output dir
dist: path.join(__dirname, '../dist'),
// path to the public files (html files)
public: path.join(__dirname, '../public'),
// path to output sub dir (js, css, fonts, etc.)
assets: 'assets/',
// path to output sub dir (img, icons, etc.)
static: 'static/'
}
Pages config from /webpack/webpack-pages.js
:
const pages = [
{
// page title
title: 'Home page',
// template name `public/index.html`
template: 'index.html',
// output filename `dist/index.html`
filename: 'index.html',
// other options can be here
},
{
title: 'About page',
template: 'about.html',
filename: 'about.html',
}
]
You can pass a hash of configuration options to html-webpack-plugin.
Allowed values are as follows: https://github.com/jantimon/html-webpack-plugin#options
In case if you don't want to use Pages config:
- Create another html file in
./public
- Go to
./webpack/webpack.common.js
- Add new page to the config:
// index page:
new HtmlWebpackPlugin({
title: 'Home page',
favicon: defines.src + '/shared/misc/favicon.ico',
template: defines.public + '/index.html', // public/index.html page
filename: 'index.html' // output file
}),
// about page:
new HtmlWebpackPlugin({
title: 'About page',
favicon: defines.src + '/shared/misc/favicon.ico',
template: defines.public + '/about.html', // public/about.html page
filename: 'about.html' // output file
}),
Install it:
yarn add bootstrap react react-dom
Import libs to src/app/index.ts
:
// React example
import React from 'react'
// Bootstrap example (with custom js imports)
import Bootstrap from 'bootstrap/dist/js/bootstrap.min.js'
import 'bootstrap/dist/js/bootstrap.min.js'
Import libs to src/app/index.scss
:
// sass lib import example:
@import '../../node_modules/spinners/stylesheets/spinners';
// css lib import example:
@import '../../node_modules/flickity/dist/flickity.css';
Here's an example with React + i18n Provider.
Install react:
yarn add react react-dom
Create div with id app
in public/index.html
:
<div id="app"></div>
Init the app in src/app/index.ts
:
import React from 'react'
import { createRoot } from 'react-dom/client'
// app styles
import './index.scss'
// local providers:
import { I18nProvider } from './providers/I18nProvider'
const container = document.getElementById('app') as HTMLElement
const root = createRoot(container)
root.render(
<React.StrictMode>
<I18nProvider>...</I18nProvider>
</React.StrictMode>
)
File src/app/providers/I18nProvider.tsx
:
import React, { FC, PropsWithChildren } from 'react'
export const I18nProvider: FC<PropsWithChildren> = ({ children }) => {
// ...
return <I18n locale={detectedLocale}>{children}</I18n>
}
Install vue:
yarn add vue
Init the app in src/app/index.ts
:
// vue example (react one is above):
const app = new Vue({
el: '#app'
})
Create div with id app
in public/index.html
:
<div id="app"></div>
Create your component in src/app/components/
.
HTML Usage (in *.html
files):
Init component in src/app/index.ts
:
Vue.component('example-component', require('./components/Example.vue').default)
In any html files:
<example-component />
VUE Usage (in *.vue
files):
Import component:
import ExampleComponent from '@/components/Example.vue'
Init component (template):
<Example />
Register component (script):
components: {
Example: ExampleComponent
}
Connect fonts to public/index.html
:
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500&display=swap" rel="stylesheet" />
Change the font in src/app/styles/body.scss
:
html {
font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol' !important;
}
In case if you don't want to use Google Fonts:
- Download fonts
- Add fonts to the (i.g.
/src/shared/fonts/OpenSans/...
).
Then add @font-face
in some .scss
file (i.g. /src/app/styles/font.scss
):
// Open Sans example:
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-stretch: 100%;
font-display: swap;
src: url('/static/fonts/OpenSans/Open-Sans.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
The last step is to copy these fonts into the /dist
folder every time you build the project.
Add another config for CopyWebpackPlugin
to /webpack/webpack.common.js
:
new CopyWebpackPlugin({
// ...
// `shared/fonts` to `dist/static/fonts`
{
from: `${defines.src}/shared/fonts`,
to: `${defines.dist}/${defines.static}/fonts`
},
})
Change the font in src/app/styles/body.scss
:
html {
font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol' !important;
}
Copyright (c) 2018-present, Evgenii Vedegis