-
Notifications
You must be signed in to change notification settings - Fork 3
/
webpack.common.js
159 lines (141 loc) · 5.24 KB
/
webpack.common.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
const path = require('path');
const postcssPresetEnv = require('postcss-preset-env');
const HtmlPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
// exports an anonymous function
// params are:
// 1. isDev: boolean - is it the development build that needs to be returned
// 2. moduleRules: array - all the module rules specific to the dev/prod build
// 3. plugins: array - all the plugins specific to the dev/prod build
// returns: webpack common configuration for the build
module.exports = (isDev, moduleRules, plugins) => ({
// the source map type
// for dev it will be a line by line source map
// for prod it will be a generic source map that may not be as accurate as the former
devtool: isDev ? 'cheap-module-eval-source-map' : 'source-map',
// the starting point of webpack bundling
entry: {
index: path.join(__dirname, '../src/index.tsx')
},
// the mode is what notifies webpack how the build should be made
mode: isDev ? 'development' : 'production',
// the module loaders for webpack
// these loaders help webpack to identify and process different file formats for bundling
module: {
rules: [
// babel-loader is used for typescript as it has good tree shaking support compared to tsc
{
test: /.tsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
// this will create source maps for the typescript code
{
test: /.js$/,
exclude: /node_modules/,
loader: 'source-map-loader',
enforce: 'pre'
},
// the loaders for styling
// there are two sets of them: for global and component styles
// a scss file will first be loaded via sass loader and transpiled
// afterwards it will be processed by postcss loader to make the css cross-browser compatible
// add the processed css into the html document during runtime for dev
// and extract the css for prod and minify it as external stylesheets
{
test: /.scss$/,
include: /src\/ensembl\/src(?!\/styles)/,
use: [
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: {
localIdentName: '[local]__[name]__[hash:base64:5]'
},
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [postcssPresetEnv()]
}
},
'sass-loader'
]
},
{
test: /.scss$/,
include: /src\/ensembl\/src\/styles/,
use: [
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [postcssPresetEnv()]
}
},
'sass-loader'
]
},
// use file-loader on svg's (to be able to require them as a path to the image),
// but also use @svgr/webpack to be able to require svg's directly as React components
{
test: /\.svg$/,
use: ['@svgr/webpack', 'file-loader'],
},
// loaders specific to dev/prod
...moduleRules
]
},
// prevent webpack from searching fs (node API) to load the web assembly files
node: {
fs: 'empty'
},
// this is the config to define how the output files needs to be
output: {
// dev will take the default file names as no physical files are emitted
// prod will have emitted files and will include the content hash, which will change every time the contents of the js file changes.
filename: isDev ? undefined : '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist/static'),
// stop webpack from adding additional comments/info to generated bundles as it is a performance hit (slows down build times)
pathinfo: false,
// prepend the public path as the root path to all the files that are inserted into the index file
publicPath: isDev ? '/' : '/static/'
},
// the plugins that extends the webpack configuration
plugins: [
// checks typescript types
new ForkTsCheckerPlugin(),
// generates the index file using the provided html template
new HtmlPlugin({
// in prod, path for saving static assets is dist/static/, and index.html has to be saved top-level in the dist folder
filename: isDev ? 'index.html' : '../index.html',
template: path.join(__dirname, '../static/html/template.html'),
publicPath: '/'
}),
// plugins specific to dev/prod
...plugins
],
// configuration that allows us to not to use file extensions and shorten import paths (using aliases)
resolve: {
extensions: ['.tsx', '.ts', '.js', '.scss'],
alias: {
config: path.resolve(__dirname, '../config.ts'),
src: path.join(__dirname, '../src'),
tests: path.join(__dirname, '../tests'),
static: path.join(__dirname, '../static')
}
}
});