-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebpack.config.cjs
More file actions
334 lines (287 loc) · 15.1 KB
/
webpack.config.cjs
File metadata and controls
334 lines (287 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/* WEBPACK TEMPLATE SETUP WITH DECAP CMS INTEGRATION
* webpack.config.cjs
* webpack.config.js
* All the steps for getting a new Webpack-based website started via VS Code!
This script itself is a file called webpack.config.cjs and is used to tell Webpack how to build your site.
* Modifications to make this config file Decap CMS-compatible have been added!
https://github.com/nickyonge/decap-cms-quickstart
* If you want to skip to a Webpack-functional website that's ready to go, see the Webpack Template repository:
https://github.com/nickyonge/webpack-template
* If you want to set up your own Webpack project (recommended to do at least once), start with the prerequisites below!
* NOTE: The filename can be webpack.config.cjs or .js at your discretion. Using .cjs is recommended. Details at end of guide.
* --- PREREQUISITES ---
* - Install VS Code, https://code.visualstudio.com
* - Install Node.js, https://www.nodejs.org
Note: During installation, you should generally allow the installer to set up other packages like Chocolatey
If a popup appears installing additional tools, just keep Pressing Any Key until the installation is complete.
Helpful but optional: Node.js tutorial for VS Code: https://code.visualstudio.com/docs/nodejs/nodejs-tutorial
* - Create your directory folder,
"My Cool Website That Is Going To Make The World Better For Everyone",
and place this file in it. Open it up in VS Code
* - Time to get started!
*
*
* --- SHORT SUMMARY ---
*
* Once prereqs are fulfilled, and this file (webpack.config.cjs) is placed in a new directory:
*
* 1: Run the following three terminal commands: (use Ctrl + ` / Cmd + ` to open the terminal)
npm init -y
* (If you get error text saying "The term 'npm' is not recognized", ensure node.js is installed)
npm i webpack webpack-cli webpack-dev-server webpack-remove-empty-scripts css-loader html-webpack-plugin mini-css-extract-plugin postcss-loader copy-webpack-plugin npm-run-all2 --save-dev
npm i typescript jquery --save
* 2: Add the following values to package.json's "scripts":{} array:
"start": "run-p start:byconfig server",
"start:byconfig": "webpack serve --open",
"start:dev": "webpack serve --mode=development --open && npx http-server dist",
"start:prod": "webpack serve --mode=production --open",
"server": "npx decap-server",
"build": "webpack --mode=production",
"preview": "npx http-server dist"
* (package.json will be auto-created in your parent directory. You'll find the scripts array
* inside it with a few values prepopulated - just copy+paste these!)
* 3: Fill out the SITE_TITLE in the Config region of this file, below
SITE_TITLE should be the name of your beautiful new website. You can ignore the other values for now.
PRODUCTION_BUILD should be false while you're in development mode, and true when you're ready to launch
SRC_FOLDER, OUTPUT_FOLDER, and INDEX_FILE should be left "src", "dist", and "./js/index.js", respectively
* 4: Import Decap files
Copy the "cms" folder and its files from https://github.com/nickyonge/decap-cms-quickstart/tree/main/src/cms
and place them into a src/ directory in your project folder
*
* Done! Run command "npm start" to get underway
* Consider starting by making a src/ directory and index.js inside of it (steps 9/10 in the detailed instructions below)
* (Remember to uncomment the "entry" module rule on line 102)
*
* --- DETAILED STEPS ---
* with terminal cmds
*
* 1: Create new folder (project, vscode workspace, github repo, etc), and place this file in it
* 2: install npm
npm init -y
* 3: initialize webpack and its CLI as dev dependencies
npm install webpack webpack-cli --save-dev
* 4: initialize webpack dev server as a dev dependencies, for local testing at url "localhost:8080"
npm install webpack-dev-server --save-dev
* 5: initialize HTML Webpack Plugin as a dev dependency, to auto-generate .html files in ./dist folder upon build
npm install html-webpack-plugin --save-dev
* 6: initialize Decap package and npm-run-all2 as dev depencies, to run a local Decap server
npm install copy-webpack-plugin --save-dev
npm install npm-run-all2 --save-dev
* 6: add the following values to package.json's "scripts": {} array
"start": "run-p start:byconfig server",
"start:byconfig": "webpack serve --open",
"start:dev": "webpack serve --mode=development --open && npx http-server dist",
"start:prod": "webpack serve --mode=production --open",
"server": "npx decap-server",
"build": "webpack --mode=production",
"preview": "npx http-server dist"
* to enable terminal commands "npm run build" and "npm run start", respectively
* 7: Optionally, prep CSS loader, PostCSS loaders and Mini CSS Extract Plugin, all as dev dependencies, to import/export .css files from ./src
npm install css-loader postcss-loader mini-css-extract-plugin --save-dev
* If not doing this step, you can remove CSS / mini plugin references from this file
* Note: We're using mini-css-extract-plugin instead of style-loader to control CSS file output
* Note: Loaders that post-process content, like css-loader, should exclude your src/cms directory, since it gets copied to ./dist
* 8: Optionally, import the JQuery and TypeScript libraries,
npm install jquery typescript
* Note: Omit the --save-dev! These aren't dev-only dependencies.
* If not doing this step, you can remove the JQuery references from this file.
* 9: create a ./src subfolder with a /js subfolder, and inside it, a file called index.js
* 10: Fill out the values in the Config region of this file, below
PRODUCTION_BUILD should be while you're in development mode
SITE_TITLE should be the name of your beautiful new website
SRC_FOLDER and INDEX_FILE should be left "src" and "./js/index.js", respectively
*
*
*
* Done! Now go make a beautiful website.
* Use command "npm start" :)
*
*
*
* A NOTE ON .JS vs .CJS EXTENSION (webpack.config.cjs)
Using .cjs tells the compiler to use the CommonJS module system, the original standard for Node.js.
This means the compiler will NOT spend any time looking for more modern modules, eg ECMAScript (ES).
* This guide is written referencing "webpack.config.cjs", which is the encouraged format to use.
It's suggested both because explicit naming is encouraged, and to bypass VSCode sugugestions.
Using "cjs" simply disables a VSCode Intellisense suggestion on they keyword "require", such as
const path = require('path');
The suggestion encourages you to convert the line to ES syntax, "import { path } from 'path';".
This is all well and good, but it breaks Webpack if it's not configured for ES6+.
This Webpack setup is not configured for it, as the intent was to keep this setup lightweight.
For more info on using ECMAScript, see: https://webpack.js.org/api/module-methods/
For other config file languages, see: https://webpack.js.org/configuration/configuration-languages/
* If you want to dig deeper, here's Webpack's official Getting Started guide:
https://webpack.js.org/guides/getting-started/
* by Nick Yonge
https://gist.github.com/nickyonge/bb9fe46458c16e1cd560bce505e4af39
*/
// tutorial complete ~
// done? consider deleting the above tutorial section, or moving it to the end of this file.
// you may end up modifying webpack config quite a bit! Might as well have the content up top.
// For more on webpack.config.js, see the config docs: https://webpack.js.org/configuration/
// For more on Decap CMS, see its documentation: https://decapcms.org/docs/intro/
// #region Config
/** Export webpack bundle in Production mode, or Development?
* - **Note:** Remember to close & restart Webpack if changed, via `npm start`
* @see {@linkcode environment} for runtime mode detection @type {boolean} */
const PRODUCTION_BUILD = false;
/** Your site title; the text that will appear in the browser tab. @type {string} */
const SITE_TITLE = '💖 Webpack is for Lovers 💖';
/** Name of your source code folder. It should be in the same directory as `webpack.config.js`
* itself. Don't put `webpack.config.js` *in* the source folder. @type {string} */
const SRC_FOLDER = 'src';
/** Name of the folder where build output will be exported. @type {string} */
const OUTPUT_FOLDER = 'dist';
/** Filepath of your index script, relative to
* {@linkcode SRC_FOLDER}. Must begin with `./` or `/`. @type {string} */
const INDEX_FILE = './js/index.js';
/** Name of the folder, in both source and dist output, for the CMS. */
const CMS_FOLDER = 'cms';
// #endregion Config
/** The `node:path` module provides utilities for working with file and directory paths.
* @see https://github.com/nodejs/node/blob/v24.x/lib/path.js */
const path = require('path');
/** The `node:path` module provides utilities for working with file and directory paths.
* @see https://github.com/nodejs/node/blob/v24.x/lib/path.js */
const webpack = require('webpack');
/** Handles creation of HTML files to serve your webpack bundles.
* @see https://webpack.js.org/plugins/html-webpack-plugin/ */
const HtmlWebpackPlugin = require('html-webpack-plugin');
/** Extracts CSS into separate files. We use it to control how CSS files are output for our project.
* @see https://webpack.js.org/plugins/mini-css-extract-plugin/ */
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
/** A Webpack plugin to remove empty JavaScript files generated when using style-only entries.
* @see https://github.com/webdiscus/webpack-remove-empty-scripts */
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
/** A Webpack plugin to copy existing individual files or entire directories into the build directory.
* @see https://webpack.js.org/plugins/copy-webpack-plugin/ */
const CopyWebpackPlugin = require("copy-webpack-plugin");
/** Full path of the CMS subfolder. Ignored in module rules, used by {@linkcode CopyWebpackPlugin. @type {string} */
const CMS_FULL_PATH = path.resolve(__dirname, `${SRC_FOLDER}/${CMS_FOLDER}`);
/**
* Defines the runtime build environment
*
* To determine what the current environment is in your codebase, use:
* `process.env.NODE_ENV`
* which will return a string matching either `"production"` or
* `"development"`, depending on the value of {@linkcode PRODUCTION_BUILD}.
@example
const _env = process.env.NODE_ENV;
const isDevBuild = _env === 'development';
if (isDevBuild) {
// Do secret sneaky dev-only stuff here!
}
*/
const environment = PRODUCTION_BUILD ? 'production' : 'development';
module.exports = () => {
return {
/** The runtime build environment, either `"production"` or `"development"`
* @see {@linkcode PRODUCTION_BUILD} */
mode: environment,
/** Reference to {@linkcode SRC_FOLDER} build path */
context: path.resolve(__dirname, SRC_FOLDER),
/** Entry point to begin generating runtime webpage from */
entry: {
/** Index file, the initially loaded script.
* @see {@linkcode INDEX_FILE} */
index: INDEX_FILE,
},
/** List of all webpack plugins we're using @type {webpack.WebpackPluginInstance[]} */
plugins: [
// define webpack plugins here
new RemoveEmptyScriptsPlugin(),
new HtmlWebpackPlugin({
title: SITE_TITLE,
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].css',
runtime: false,
}),
new CopyWebpackPlugin({
patterns: [
{
from: CMS_FULL_PATH,
to: CMS_FOLDER,
noErrorOnMissing: true,
},
],
}),
],
/** Protocol for source mapping, so we can see lines/error info in browser console output
* @see https://webpack.js.org/guides/development/#using-source-maps @type {string} */
devtool: PRODUCTION_BUILD ? 'source-map' : 'eval-cheap-source-map',
// for prod builds, either use 'source-map' (full sourcemap in separate file, unsecure but easy live debugging) or false (no sourcemap included)
// see: https://webpack.js.org/configuration/devtool/#devtool
/** Enable webpack dev server so we can locally test
* @see https://webpack.js.org/guides/development/#using-webpack-dev-server */
devServer: {
static: [
OUTPUT_FOLDER,
{ directory: CMS_FULL_PATH, publicPath: `"/${CMS_FOLDER}` },
],
watchFiles: [`${SRC_FOLDER}/${CMS_FOLDER}/**/*`],
},
/**
* Defines how the {@link https://webpack.js.org/concepts/modules modules} in this project will be treated.
* @see https://webpack.js.org/configuration/module/ */
module: {
rules: [
// Jquery
{
test: require.resolve("jquery"),
loader: "expose-loader",
options: {
exposes: ["$", "jQuery"],
},
},
// CSS loading
{
test: /\.(sc|c)ss$/i,
exclude: CMS_FULL_PATH,
use: [
MiniCssExtractPlugin.loader, // extract css to subfolder
'css-loader',
'postcss-loader',
// 'sass-loader',
// 'style-loader',
],
},
// Images asset loading
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
// Fonts asset loading
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
/** Output options for builds
* @see https://webpack.js.org/configuration/output/ */
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, OUTPUT_FOLDER),
assetModuleFilename: '[path][name][ext]',
clean: true,
},
/** Build time optimization options
* @see https://webpack.js.org/configuration/optimization */
optimization: {
runtimeChunk: false,
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
type: 'css/mini-extract', // use type, not test
chunks: 'all',
enforce: true,
},
},
},
removeEmptyChunks: true,
},
};
};