UNPKG

12.6 kBMarkdownView Raw
1<div align="right">
2 <h1 align="right">
3 <img height=75 src="./docs/assets/readme-header.png" alt="webpack base">
4 </h1>
5
6 <!-- prettier-ignore-start -->
7 <a href="https://www.npmjs.com/package/@crystal-ball/webpack-base">
8 <img src="https://img.shields.io/npm/v/@crystal-ball/webpack-base" alt="Package version" valign="text-top"/>
9 </a>
10 <a href="https://www.npmjs.com/package/@crystal-ball/webpack-base">
11 <img src="https://img.shields.io/npm/dt/@crystal-ball/webpack-base?color=blue" alt="NPM downloads" valign="text-top" />
12 </a>
13 <a href="https://github.com/crystal-ball/webpack-base/actions?workflow=CI%2FCD">
14 <img src="https://github.com/crystal-ball/webpack-base/workflows/CI%2FCD/badge.svg" alt="Build status" valign="text-top" />
15 </a>
16 <a href="https://snyk.io/test/github/crystal-ball/webpack-base?targetFile=package.json">
17 <img src="https://snyk.io/test/github/crystal-ball/webpack-base/badge.svg?targetFile=package.json" alt="Known vulnerabilities" valign="text-top" />
18 </a>
19 <a href="https://codeclimate.com/github/crystal-ball/webpack-base/test_coverage">
20 <img src="https://api.codeclimate.com/v1/badges/b96df9f9f2fb844ee580/test_coverage" alt="Test coverage" valign="text-top" />
21 </a>
22 <a href="https://codeclimate.com/github/crystal-ball/webpack-base/maintainability">
23 <img src="https://api.codeclimate.com/v1/badges/b96df9f9f2fb844ee580/maintainability" alt="Maintainability" valign="text-top" />
24 </a>
25 <code>:status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>
26
27 <br />
28 <a href="https://renovatebot.com/">
29 <img src="https://img.shields.io/badge/Renovate-enabled-32c3c2.svg" alt="Renovate" valign="text-top" />
30 </a>
31 <a href="https://commitizen.github.io/cz-cli/">
32 <img src="https://img.shields.io/badge/Commitizen-%E2%9C%93%20friendly-10e67b" alt="Commitizen friendly" valign="text-top" />
33 </a>
34 <a href="https://github.com/crystal-ball/webpack-base#workspaces/-projects-5b88b5c9af3c0a2186966767/board?repos=136812233">
35 <img src="https://img.shields.io/badge/ZenHub-managed-5e60ba.svg" alt="ZenHub" valign="text-top" />
36 </a>
37 <a href="https://semantic-release.gitbook.io/semantic-release/">
38 <img src="https://img.shields.io/badge/%F0%9F%93%A6%F0%9F%9A%80-semantic_release-e10079.svg" alt="Semantic Release" valign="text-top"/>
39 </a>
40 <a href="./CODE_OF_CONDUCT.md">
41 <img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0-de8cf2.svg" alt="Contributor Covenant" valign="text-top" />
42 </a>
43 <code>:integrations</code>
44
45 <br />
46 <a href="https://github.com/crystal-ball">
47 <img src="https://img.shields.io/badge/%F0%9F%94%AE%E2%9C%A8-contains_magic-D831D7.svg" alt="Contains magic" valign="text-top" />
48 </a>
49 <a href="https://github.com/crystal-ball/crystal-ball.github.io">
50 <img src="https://img.shields.io/badge/%F0%9F%92%96%F0%9F%8C%88-full_of_love-F5499E.svg" alt="Full of love" valign="text-top" />
51 </a>
52 <code>:flair&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>
53 <!-- prettier-ignore-end -->
54
55 <h1></h1>
56 <br />
57 <p align="center">
58 <em>This package generates a base webpack configuration and dependencies for
59 React web and Electron applications. Users can customize the generated base
60 configurations to meet the specific needs of any project.</em>
61 </p>
62 <br />
63</div>
64
65- [Setup](#-setup) - Installation and file setup instructions
66- [Project defaults](#=project-defaults) - Documentation on default project
67 structure used
68- [Configuration API](#-configuration-api) - Documentation on customizing
69 generated configurations
70- [Featureset](#-featureset) - Overview of the supported magic
71- [Electron support](#-electron-support) - Using within an Electron project
72- [Docker support](#-docker-support) - Using within a Docker workflow
73- [Components access](#-components-access) - Accessing loaders and plugins
74 directly
75- [Developing](#-developing) - How to develop the project
76- [Testing](#-testing) - How to test the project
77- [Roadmap](#-roadmap) - TODO items and contributing suggestions
78- [Contributing](#-contributing) - Yes please! 😍
79
80---
81
82## ⚙️ Setup
83
84**1. Install**
85
86```bash
87npm i -D @crystal-ball/webpack-base
88```
89
90**2. Add `package.json` commands**
91
92```json
93{
94 "scripts": {
95 "build": "NODE_ENV=production webpack --mode=production",
96 "start": "NODE_ENV=development webpack-dev-server --mode=development"
97 }
98}
99```
100
101**3. Add configuration files**
102
103Add configuration files for webpack and Babel to the project root. The
104[@crystal-ball/react-application-prototype][] is a complete working reference
105application using this package. Projects require a:
106
107- `.browserslistrc`
108- `.eslintrc.js`
109- `babel.config.js`
110- `webpack.config.js`
111
112## 📦 Project defaults
113
114Out of the box all of the webpack-base loaders and plugins will work with
115projects that use the default project directory structure:
116
117```
118project
119├─ / src
120│ └─ / api
121│ └─ / components
122│ └─ / dux
123│ └─ / media
124│ │ └─ / icons
125│ └─ / styles
126│ └─ / utils
127│ ├─ index.html
128│ ├─ index.js
129│ └─ index.scss
130├─ / static
131│ └─ favicon.ico
132├─ .browserslistrc
133├─ .eslintrc.js
134├─ babel.config.js
135└─ webpack.config.js
136```
137
138### Directories
139
140- **src** - Project source code root directory.
141- **src/media/icons** - The SVG symbol sprite loader will sprite any SVG icons
142 imported from this directory.
143- **src/styles** - SCSS files in this directory can be imported with the `@`
144 alias from anywhere in the project.
145- **src/api**, **src/components**, **src/dux** and **src/utils** - Suggested but
146 not required directory structure for organizing application code by domain
147- **static** - The static folder can be used as an escape hatch for including
148 assets that are not directly imported in the project code. The contents are
149 copied to the output directory during builds.
150
151## 📝 Configuration API
152
153The project `webpack.config.js` should call the webpack-base package to generate
154a base configuration. The base configuration can then be modified in any way to
155support specific project needs.
156
157```javascript
158// webpack.config.js
159const webpackBase = require('@crystal-ball/webpack-base')
160
161module.exports = () => {
162 const { configs } = webpackBase(/* options */)
163
164 /*
165 * Handle non-standard, advanced project customization by directly updating
166 * the generated base configs.
167 */
168 configs.rules.push({
169 /* some custom loader */
170 })
171
172 return configs
173}
174```
175
176### Options
177
178The base configurations generated by the package can be customized by passing an
179options object:
180
181```javascript
182const { configs } = webpackBase{
183 devServer,
184 envVars
185 paths,
186 target,
187})
188```
189
190### Available path configs
191
192```javascript
193const paths = {
194 /**
195 * Project root directory that is used by webpack (eg to handle resolutions).
196 * webpack base attempts to automatically set the project context, but it
197 * can help fix resolution errors to specify it.
198 * @default /
199 */
200 context,
201 /**
202 * SVG files imported from these directories will be loaded+sprited using the
203 * `SVGSymbolSprite` package.
204 * @default ['/src/media/icons']
205 */
206 iconSpriteIncludes,
207 /**
208 * JS files imported from these directories will be loaded using the JS loader.
209 * @default ['/src']
210 */
211 jsLoaderIncludes,
212 /**
213 * Build assets are emitted to this directory.
214 * @default /public
215 */
216 output,
217 /**
218 * SCSS files in these directories can be imported in other SCSS files using
219 * relative imports. (Useful for importing shared variables or mixins inside
220 * component style files)
221 * @default ['/src/styles', '/src/styles/[dev|prod]]
222 */
223 sassIncludes,
224 /**
225 * Application source files directory. This directory is used as a base for
226 * the icon includes path.
227 * @default /src
228 */
229 src,
230 /**
231 * Application public static files directory. This directory is copied to the
232 * build without manipulation by the `CopyWebpackPlugin` and provides an
233 * escape hatch to include assets in a build without importing them in the
234 * application source.
235 * @default /static
236 */
237 static,
238}
239```
240
241## 😍 Featureset
242
243- JS loader setup to transpile all source in the `babelLoaderInclude` with the
244 `babel-loader`
245- Appropriate sourcemaps for dev vs prod builds
246- Handles adding scripts to `index.html`
247- Friendly errors
248- Dev server with hot reloading
249- Progress indicators
250- Production optimizations including uglify and module concatenation
251- Output directory cleaning
252- Injected `PUBLIC_PATH` for routing
253- `DEVTOOL` environment variable will override source maps
254- Import paths case is verified to ensure Linux and MacOS compatability
255- Production CSS+JS assets are minified
256- Application logo is used to generate and inject favicon resources in build
257
258### Environment variable injection
259
260The following environment variables are injected by the build:
261
262| Constant | Usage |
263| ------------- | ----------------------------------------------------------------------------- |
264| `NODE_ENV` | Defaults to match NODE_ENV, used by Babili to strip code in prod builds |
265| `DEBUG` | Defaults to false, can be used for adding detailed logging in dev environment |
266| `PUBLIC_PATH` | Defaults to '/', useful for importing media and configuring CDN paths |
267
268Additional environment variables can be passed in an `envVars` option and they
269will be injected into the build
270
271```js
272webpackBase({
273 envVars: { TRACKING_ID: 'x-123456' },
274})
275```
276
277## ⚛️ Electron support
278
279Electron renderer processes can be bundled by passing a `target` flag in
280options:
281
282```javascript
283// webpack.config.js
284const webpackBase = require('@crystal-ball/webpack-base')
285
286module.exports = () => {
287 return webpackBase({ target: 'electron-renderer' }).configs
288}
289```
290
291By default `webpack-base` will look for project source files in `/src/renderer`
292instead of `/src` and builds are output to `/src/build` instead of `/dist`. This
293is for working with Electron build systems.
294
295## 🐳 Docker support
296
297When working within a Docker setup, the dev server port (default `3000`) must be
298exposed and the host set to `0.0.0.0`. Including a start command for Docker is
299recommended:
300
301```json
302{
303 "start:docker": "NODE_ENV=development webpack-dev-server --host=0.0.0.0 --mode=development"
304}
305```
306
307## 🎛 Loader and plugins access
308
309The configured loaders and plugins can be accessed directly in the return value,
310this is useful when setting up Storybook to pass additional loaders and plugins.
311
312```javascript
313// webpack.config.js
314const webpackBase = require('@crystal-ball/webpack-base')
315
316module.exports = () => {
317 const { loaders, plugins } = webpackBase(/* options */)
318}
319```
320
321#### Returned loaders
322
323```js
324config.loaders = {
325 jsLoader,
326 sassLoader,
327 svgSpriteLoader,
328 svgComponentLoader,
329 fileLoader,
330 rawLoader,
331}
332```
333
334#### Returned plugins
335
336```js
337config.plugins = {
338 progressBarPlugin,
339 environmentPlugin,
340 htmlPlugin,
341 svgSymbolSpritePlugin,
342 copyPlugin,
343 hotModuleReplacementPlugin,
344 friendlyErrorsPlugin,
345}
346```
347
348This can be useful for adding loaders to projects like Storybook.
349
350## 👷‍♀️ Developing
351
352Development and testing of the repository use a Docker workflow to ensure that
353the generated configs work with the packages required and the minimum version of
354Node supported:
355
356```sh
357# Build the image and start the container
358npm run container
359
360# Start the webpack-dev-server 🎉
361npm run start:docker
362```
363
364## ✅ Testing
365
366Unit tests are run with Jest and use snapshots to validate the generated configs
367for development and production environments.
368
369## 🗺 Roadmap
370
371_Interested in contributing? Start here 😍_
372
373- [ ] Investigate usage of [profile][] in builds
374- [ ] Investigate including [Bundle Buddy][bundle] plugin
375
376## 👍 Contributing
377
378All contributions are greatly appreciated 👍🎉. To contribute please:
379
380- Review the repo [Code of Conduct](./CODE_OF_CONDUCT.md), it is not just for
381 show!
382- Review the [Contributing Guide](./CONTRIBUTING.md) for a helpful code overview
383 and repository pull request process details.
384
385### Node version support
386
387Node version running inside Atom's Electron instance is support target to ensure
388users of ESLint import plugin are able to parse these webpack configs.
389
390<!-- Links -->
391<!-- prettier-ignore-start -->
392[bundle]: https://github.com/samccone/bundle-buddy
393[@crystal-ball/react-application-prototype]: https://github.com/crystal-ball/react-application-prototype
394[profile]: https://webpack.js.org/configuration/other-options/#profile
395<!-- prettier-ignore-end -->