-
Notifications
You must be signed in to change notification settings - Fork 4
/
webpack.config.js
142 lines (135 loc) · 6.71 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
const CONFIG = {
// The tags to include the generated JS and CSS will be automatically injected in the HTML template
// See https://github.com/jantimon/html-webpack-plugin
indexHtmlTemplate: './src/Client/index.html',
fsharpEntry: "./src/Client/output/App.js",
outputDir: "./deploy/public",
assetsDir: './src/Client/public',
devServerPort: 8080,
// When using webpack-dev-server, you may need to redirect some calls
// to a external API server. See https://webpack.js.org/configuration/dev-server/#devserver-proxy
devServerProxy: {
// redirect requests that start with /api/ to the server on port 8085
'/api/**': {
target: 'http://localhost:' + (process.env.SERVER_PROXY_PORT || "8085"),
changeOrigin: true
},
// redirect websocket requests that start with /socket/ to the server on the port 8085
'/socket/**': {
target: 'http://localhost:' + (process.env.SERVER_PROXY_PORT || "8085"),
ws: true
}
}
}
const TEST_CONFIG = {
// The tags to include the generated JS and CSS will be automatically injected in the HTML template
// See https://github.com/jantimon/html-webpack-plugin
indexHtmlTemplate: './tests/Client/index.html',
fsharpEntry: "./tests/Client/output/App.Test.js",
outputDir: "./tests/Client/dist",
assetsDir: "./src/Client/public",
devServerPort: 8080
}
// Webpack configuration guide: https://github.com/fable-compiler/webpack-config-template
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// export a function https://webpack.js.org/configuration/configuration-types/#exporting-a-function
module.exports = function(env, arg) {
// Mode is passed as a flag to npm run, we pass this flag in the package.json scripts. Ex. --mode development
// see the docs for more details on flags https://webpack.js.org/api/cli/#flags
const mode = arg.mode ?? 'development';
// Environment variables can also be defined as args for package.json scripts. Ex. --env test
// docs: https://webpack.js.org/api/cli/#environment-options
const config = env.test ? TEST_CONFIG : CONFIG;
const isProduction = mode === 'production';
console.log(`Bundling for ${env.test ? 'test' : 'run'} - ${mode} ...`);
return {
// required property, either "development" or "production".
mode: mode,
// Webpack uses this file as a starting point for dependency tree walking.
// We use the main file generated by Fable.
entry: config.fsharpEntry,
// integrated in webpack, controls how source maps are generated https://webpack.js.org/configuration/devtool/
devtool: isProduction ? 'source-map' : 'eval-source-map',
// the resulting output
output: {
// An absolute path for the resulting bundle.
path: path.join(__dirname, config.outputDir),
// for production we use a hash so it can be cached unless the hash changes
filename: isProduction ? '[name].[fullhash].js' : '[name].js'
},
devServer: {
static: config.outputDir,
// hot true automatically adds Hot Module Replacement, no longer needed to add the plugin new webpack.HotModuleReplacementPlugin()
hot: true,
port: config.devServerPort,
proxy: config.devServerProxy,
},
plugins: [
// ONLY PRODUCTION
// isProduction && SomePlugin returns false when it's not production and all false elements are filtered with .filter(Boolean)
// MiniCssExtractPlugin: Extracts CSS from bundle to a different file
// To minify CSS, see https://github.com/webpack-contrib/mini-css-extract-plugin#minimizing-for-production
isProduction && new MiniCssExtractPlugin({ filename: 'style.[name].[contenthash].css' }),
// CopyWebpackPlugin: Copies static assets to output directory
isProduction && new CopyWebpackPlugin({ patterns: [{ from: resolve(config.assetsDir) }] }),
// PRODUCTION AND DEVELOPMENT
// HtmlWebpackPlugin allows us to use a template for the index.html page
// and automatically injects <script> or <link> tags for generated bundles.
new HtmlWebpackPlugin({ filename: 'index.html', template: resolve(config.indexHtmlTemplate)})
].filter(Boolean),
optimization: {
splitChunks: {
chunks: 'all'
},
},
resolve: {
// See https://github.com/fable-compiler/Fable/issues/1490
symlinks: false
},
module: {
// Loaders allow webpack to process files other than JS and convert them into valid
// modules that can be consumed by your application and added to the dependency graph
rules: [
// style loaders
{
// The test property identifies which file or files should be transformed.
test: /\.(sass|scss|css)$/,
// The use property indicates which loader should be used to do the transforming.
use: [
// Creates `style` nodes from JS strings
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
// Translates CSS into CommonJS
{
loader: 'css-loader',
options: isProduction ? {} : { sourceMap: true, },
},
// Compiles Sass to CSS
{
loader: 'sass-loader',
options: isProduction ? {} : { sourceMap: true, },
}
]
},
// JS source map loader https://webpack.js.org/loaders/source-map-loader/
// extracts existing source maps from all JavaScript entries and passes them to the specified devtool
{
test: /\.js$/,
enforce: "pre",
use: ['source-map-loader']
},
// https://webpack-v3.jsx.app/loaders/file-loader/
// Moves files referenced in the code (fonts, images) into output folder
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?.*)?$/,
use: ['file-loader']
},
]
}
};
}
function resolve(filePath) {
return path.isAbsolute(filePath) ? filePath : path.join(__dirname, filePath);
}