-
Notifications
You must be signed in to change notification settings - Fork 5
/
webpack.config.js
232 lines (208 loc) · 6.54 KB
/
webpack.config.js
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
/*
* Webpack is used to compile and minify/uglify JS and Sass.
* Since this will nuke some of the directories inside the public directory,
* you should no longer manually add images etc. to the public folder.
* We have setup a configuration that will automatically copy any image
* from the images folder here to public/images/{moduleName}.
*
* so please, DO NOT MANUALLY ADD ASSETS TO THE PUBLIC DIRECTORY!
*/
"use strict";
// Every module that publishes assets should
// be registered below
const appModules = [{
name: 'app',
assets_path: './App/assets',
styles: true,
js: true,
images: true,
fonts: true
}];
// These paths will be completely
// rebuilt before every commit.
// DO NOT MANUALLY ADD ANYTHING
// TO THESE DIRECTORIES
const pathsToNuke = [
'./public/js',
'./public/css',
'./public/fonts',
'./public/images'
];
/*
*
* Do not touch anything below here,
* unless you know what you are doing.
*
* The only configuration you should
* need to touch will be above this comment.
*
*/
// Include npm modules
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require('terser-webpack-plugin');
// dynamically build webpack entries based on registered app modules
let entries = {};
let copyImages = [];
let rules = generateBaseRules();
/*
* Run the setup to prepare
* each module for asset transfer.
*
*/
appModules.forEach(function (appModule) {
entries[appModule.name] = [];
if (appModule.js === true) {
entries[appModule.name].push(appModule.assets_path + '/js/index.js')
}
if (appModule.styles === true) {
entries[appModule.name].push(appModule.assets_path + '/scss/index.scss')
}
if (appModule.images === true) {
copyImages.push({from: appModule.assets_path + '/images', to: './images/' + appModule.name});
rules.push({
test: /\.(png|svg|jpg|gif)$/,
include: [
path.resolve(__dirname, './src/' + appModule.assets_path)
],
use: [
{loader: 'file-loader'}
]
})
}
if (appModule.fonts === true) {
copyImages.push({from: appModule.assets_path + '/fonts', to: './fonts/' + appModule.name});
rules.push({
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
include: [
path.resolve(__dirname, './src/' + appModule.assets_path)
],
exclude: [/images?|img/],
use: [
{loader: 'file-loader'}
]
})
}
});
/*
* Lastly, export the final module
* and the assets
*/
module.exports = {
// This is the basepath for Webpack to look for source files
// if you need to include modules outside of the App module,
// move the "/App/assets" portion of the context onto the two
// strings below, so it becomes "./App/assets/js/app.js" etc.
context: path.resolve(__dirname, './src'),
// These are our entry files, this is the files Webpack will use
// when looking for Sass and Javascript to compile.
// The format is "DESTINATION": "SOURCE", and each path is
// relative to the output path and the context respectively.
entry: entries,
// The Output is where Webpack will export our files to
// the filename will be resolved to the key in the entry object above.
// The publicPath is what it'll rewrite css relative urls to use.
// The path is where it'll save files too
output: {
filename: './js/[name].js',
publicPath: '/', // URL root
path: path.resolve(__dirname, './public/') // Save-file root
},
// This is all the available file-loaders, feel free to append your own.
// IMPORTANT NOTE: loaders are evaluated in REVERSE-ARRAY ORDER,
// that means that they move from the end and towards the start.
module: {
rules: rules,
},
stats: {
children: false
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/[name].css'
}),
// Nuke the assets folder
// This will only be run on production
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: pathsToNuke,
verbose: process.env.NODE_ENV !== "development",
dry: process.env.NODE_ENV === "development"
}),
// Copy images from the source folder to the
// destination folder
new CopyWebpackPlugin({
patterns: copyImages
}),
],
optimization: {
minimizer: [new TerserPlugin({
extractComments: false,
})],
},
};
/*
* Generate base rule-set to be manipulated
* in the forEach loop
*/
function generateBaseRules()
{
return [
{
test: /\.js$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
}],
},
{
test: /\.tsx?$/,
exclude: [/node_modules/],
use: [{
loader: 'ts-loader',
options: {
sourceMap: process.env.NODE_ENV === "development",
}
}]
},
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: true,
sourceMap: process.env.NODE_ENV === "development"
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|jpg|gif)$/,
include: [
path.resolve(__dirname, 'node_modules')
],
use: [
'file-loader?name=images/[name].[ext]'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
exclude: [/images?|img/],
use: [
// As SVG may count as both font or image
// we will not treat any file in a folder
// with the name image(s) or img as a font
'file-loader?name=fonts/[name].[ext]'
]
}
];
}