UNPKG

12.4 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/eee860e3bd1519dacf5e/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/eee860e3bd1519dacf5e/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- [Accessing resources](#-accessing-resources) - 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 sassOptions,
187 target,
188})
189```
190
191### Available path configs
192
193```javascript
194const paths = {
195 /**
196 * Project root directory that is used by webpack (eg to handle resolutions).
197 * webpack base attempts to automatically set the project context, but it
198 * can help fix resolution errors to specify it.
199 * @default /
200 */
201 context,
202 /**
203 * SVG files imported from these directories will be loaded+sprited using the
204 * `SVGSymbolSprite` package.
205 * @default ['/src/media/icons']
206 */
207 iconSpriteIncludes,
208 /**
209 * JS files imported from these directories will be loaded using the JS loader.
210 * @default ['/src']
211 */
212 jsLoaderIncludes,
213 /**
214 * Build assets are emitted to this directory.
215 * @default /public
216 */
217 output,
218 /**
219 * Application source files directory. This directory is used as a base for
220 * the icon includes path.
221 * @default /src
222 */
223 src,
224 /**
225 * Application public static files directory. This directory is copied to the
226 * build without manipulation by the `CopyWebpackPlugin` and provides an
227 * escape hatch to include assets in a build without importing them in the
228 * application source.
229 * @default /static
230 */
231 static,
232}
233```
234
235## 😍 Featureset
236
237- JS loader setup to transpile all source in the `jsLoaderIncludes` with the
238 `babel-loader`
239- Sourcemaps for dev and prod environments
240- Handles adding scripts to `index.html`
241- Friendly errors
242- Dev server with hot reloading
243- Progress indicators
244- Production optimizations including uglify and module concatenation
245- Output directory cleaning
246- Injected `PUBLIC_PATH` for routing
247- `DEVTOOL` environment variable will override source maps
248- Import paths case is verified to ensure Linux and MacOS compatability
249- Production CSS+JS assets are minified
250- Application logo is used to generate and inject favicon resources in build
251
252### Environment variable injection
253
254The following environment variables are injected by the build:
255
256| Constant | Usage |
257| ------------- | ----------------------------------------------------------------------------- |
258| `NODE_ENV` | Defaults to match NODE_ENV, used by Babili to strip code in prod builds |
259| `DEBUG` | Defaults to false, can be used for adding detailed logging in dev environment |
260| `PUBLIC_PATH` | Defaults to '/', useful for importing media and configuring CDN paths |
261
262Additional environment variables can be passed in an `envVars` option and they
263will be injected into the build
264
265```js
266webpackBase({
267 envVars: { TRACKING_ID: 'x-123456' },
268})
269```
270
271## ⚛️ Electron support
272
273Electron renderer processes can be bundled by passing a `target` flag in
274options:
275
276```javascript
277// webpack.config.js
278const webpackBase = require('@crystal-ball/webpack-base')
279
280module.exports = () => {
281 return webpackBase({ target: 'electron-renderer' }).configs
282}
283```
284
285By default `webpack-base` will look for project source files in `/src/renderer`
286instead of `/src` and builds are output to `/src/build` instead of `/dist`. This
287is for working with Electron build systems.
288
289## 🐳 Docker support
290
291When working within a Docker setup, the dev server port (default `3000`) must be
292exposed and the host set to `0.0.0.0`. Including a start command for Docker is
293recommended:
294
295```json
296{
297 "start:docker": "NODE_ENV=development webpack-dev-server --host=0.0.0.0 --mode=development"
298}
299```
300
301## 🎛 Accessing resources
302
303The configured loaders and plugins can be accessed directly in the return value,
304this is useful when setting up Storybook to pass additional loaders and plugins.
305
306```javascript
307// webpack.config.js
308const webpackBase = require('@crystal-ball/webpack-base')
309
310module.exports = () => {
311 const { loaders, plugins } = webpackBase(/* options */)
312}
313```
314
315#### Returned loaders
316
317```js
318config.loaders = {
319 jsLoader,
320 sassLoader,
321 svgSpriteLoader,
322 svgComponentLoader,
323 fileLoader,
324 rawLoader,
325}
326```
327
328#### Returned plugins
329
330```js
331config.plugins = {
332 progressBarPlugin,
333 environmentPlugin,
334 htmlPlugin,
335 svgSymbolSpritePlugin,
336 copyPlugin,
337 hotModuleReplacementPlugin,
338 friendlyErrorsPlugin,
339}
340```
341
342This can be useful for adding loaders to projects like Storybook.
343
344## 👷‍♀️ Developing
345
346Development and testing of the repository use a Docker workflow to ensure that
347the generated configs work with the packages required and the minimum version of
348Node supported:
349
350```sh
351# Build the image and start the container
352npm run container
353
354# Start the webpack-dev-server 🎉
355npm run start:docker
356```
357
358## ✅ Testing
359
360Unit tests are run with Jest and use snapshots to validate the generated configs
361for development and production environments.
362
363## 🗺 Roadmap
364
365_Interested in contributing? Start here 😍_
366
367- [ ] Investigate usage of [profile][] in builds
368- [ ] Investigate including [Bundle Buddy][bundle] plugin
369
370## 👍 Contributing
371
372All contributions are greatly appreciated 👍🎉. To contribute please:
373
374- Review the repo [Code of Conduct](./CODE_OF_CONDUCT.md), it is not just for
375 show!
376- Review the [Contributing Guide](./CONTRIBUTING.md) for a helpful code overview
377 and repository pull request process details.
378
379### Node version support
380
381Node version running inside Atom's Electron instance is support target to ensure
382users of ESLint import plugin are able to parse these webpack configs.
383
384<!-- Links -->
385<!-- prettier-ignore-start -->
386[bundle]: https://github.com/samccone/bundle-buddy
387[@crystal-ball/react-application-prototype]: https://github.com/crystal-ball/react-application-prototype
388[profile]: https://webpack.js.org/configuration/other-options/#profile
389<!-- prettier-ignore-end -->