-
Notifications
You must be signed in to change notification settings - Fork 54
/
webpack.config.js
216 lines (205 loc) · 8.21 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
/**
* Webpack configuration file for the MHA project.
*
* This configuration file sets up various plugins and settings for building the project,
* including handling TypeScript files, CSS extraction, HTML template generation, and more.
*
* Plugins used:
* - FileManagerPlugin: Manages file operations like copying resources.
* - ForkTsCheckerWebpackPlugin: Runs TypeScript type checking in a separate process.
* - HtmlWebpackPlugin: Generates HTML files for each page.
* - MiniCssExtractPlugin: Extracts CSS into separate files.
* - webpack.DefinePlugin: Defines global constants.
*
* Functions:
* - getHttpsOptions: Asynchronously retrieves HTTPS options for the development server.
* - getHash: Generates a short hash from a given string.
* - generateEntry: Generates an entry object for webpack configuration.
* - generateHtmlWebpackPlugins: Generates an array of HtmlWebpackPlugin instances for each page.
*
* Environment Variables:
* - SCM_COMMIT_ID: The commit ID used to generate a version hash.
* - APPINSIGHTS_INSTRUMENTATIONKEY: Application Insights instrumentation key.
* - npm_package_config_dev_server_port: Port for the development server.
*
* @param {Object} env - Environment variables passed to the webpack configuration.
* @param {Object} options - Options passed to the webpack configuration.
* @returns {Promise<Object>} The webpack configuration object.
*/
/* eslint-disable @typescript-eslint/no-require-imports */
const path = require("path");
const FileManagerPlugin = require("filemanager-webpack-plugin"); // eslint-disable-line @typescript-eslint/naming-convention
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); // eslint-disable-line @typescript-eslint/naming-convention
const HtmlWebpackPlugin = require("html-webpack-plugin"); // eslint-disable-line @typescript-eslint/naming-convention
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // eslint-disable-line @typescript-eslint/naming-convention
const devCerts = require("office-addin-dev-certs");
const webpack = require("webpack");
/**
* Asynchronously retrieves HTTPS server options.
*
* This function attempts to get HTTPS server options using the `devCerts` library.
* If successful, it returns an object containing the certificate authority (CA),
* key, and certificate. If an error occurs, it logs the error and returns an empty object.
*
* @returns {Promise<{ca: string, key: string, cert: string} | {}>} A promise that resolves to an object with HTTPS options or an empty object if an error occurs.
*/
async function getHttpsOptions() {
try {
const httpsOptions = await devCerts.getHttpsServerOptions();
return { ca: httpsOptions.ca, key: httpsOptions.key, cert: httpsOptions.cert };
} catch (error) {
console.error("Error getting HTTPS options:", error);
return {};
}
}
/**
* Generates a hash for a given string.
* Used to reduce commit ID to something short.
*
* @param {string} str - The input string to hash.
* @returns {string} The hexadecimal representation of the hash.
*/
const getHash = (str) => {
let hash = 42;
if (str.length) {
for (let i = 0; i < str.length; i++) {
hash = Math.abs((hash << 5) - hash + str.charCodeAt(i));
}
}
return hash.toString(16);
};
const commitID = process.env.SCM_COMMIT_ID || "test";
const version = getHash(commitID);
console.log("commitID:", commitID);
console.log("version:", version);
const aikey = process.env.APPINSIGHTS_INSTRUMENTATIONKEY || "unknown";
console.log("aikey:", aikey);
const buildTime = new Date().toUTCString();
console.log("buildTime:", buildTime);
const pages = [
{ name: "mha", script: "mha" },
{ name: "uitoggle", script: "uiToggle" },
{ name: "newDesktopFrame", script: "newDesktopFrame" },
{ name: "classicDesktopFrame", script: "classicDesktopFrame" },
{ name: "newMobilePaneIosFrame", script: "newMobilePaneIosFrame" },
{ name: "privacy", script: "privacy" },
// Redirection/static pages
{ name: "Default" }, // uitoggle.html?default=classic
{ name: "DefaultPhone" }, // uitoggle.html?default=classic
{ name: "DefaultTablet" }, // uitoggle.html?default=classic
{ name: "DesktopPane" }, // uitoggle.html?default=new
{ name: "MobilePane" }, // uitoggle.html?default=new-mobile
{ name: "Functions" },
];
/**
* Generates an entry object for webpack configuration.
*
* This function iterates over a list of pages and constructs an entry object
* where each key is the name of a script and the value is the path to the
* corresponding TypeScript file.
* Entry object looks like this:
* {
* 'mha': './src/Scripts/ui/mha.ts',
* 'uiToggle': './src/Scripts/ui/uiToggle.ts',
* ...
* }
*
* @returns {Object} An object representing the entry points for webpack.
*/
function generateEntry() {
return pages.reduce((config, page) => {
if (page.script) {
config[page.script] = `./src/Scripts/ui/${page.script}.ts`;
}
return config;
}, {});
}
/**
* Generates an array of HtmlWebpackPlugin instances for each page.
* One looks like this:
* new HtmlWebpackPlugin ({
* inject: true,
* template: './src/Pages/mha.html',
* filename: 'mha.html',
* chunks: [ 'mha' ]
* })
*
* This is how our actual html files are generated, with includes for the appropriate scripts and CSS.
*
* @returns {HtmlWebpackPlugin[]} An array of HtmlWebpackPlugin instances.
*/
function generateHtmlWebpackPlugins() {
return pages.map((page) => new HtmlWebpackPlugin({
inject: true,
template: `./src/Pages/${page.name}.html`,
filename: `${page.name}.html`,
chunks: [page.script],
}));
}
module.exports = async (env, options) => {
const config = {
entry: generateEntry(),
plugins: [
new MiniCssExtractPlugin({ filename: `${version}/[name].css` }),
new webpack.DefinePlugin({
__VERSION__: JSON.stringify(version), // eslint-disable-line @typescript-eslint/naming-convention
__AIKEY__: JSON.stringify(aikey), // eslint-disable-line @typescript-eslint/naming-convention
__BUILDTIME__: JSON.stringify(buildTime), // eslint-disable-line @typescript-eslint/naming-convention
}),
new FileManagerPlugin({
events: {
onEnd: {
copy: [
{ source: "./src/Resources/*.gif", destination: "./Resources/" },
{ source: "./src/Resources/*.jpg", destination: "./Resources/" },
],
},
},
}),
new ForkTsCheckerWebpackPlugin(),
...generateHtmlWebpackPlugins(),
],
mode: "development",
devtool: "source-map",
target: ["web", "es5"],
module: {
rules: [
{ test: /fabric(\.min)?\.js$/, use: "exports-loader?exports=fabric" },
{
test: /\.tsx?$/,
use: [{ loader: "ts-loader", options: { logLevel: "info" } }],
exclude: /node_modules/,
},
{ test: /\.css$/i, use: [MiniCssExtractPlugin.loader, "css-loader"] },
{ test: /\.js$/, enforce: "pre", use: ["source-map-loader"] },
],
},
optimization: {
runtimeChunk: "single",
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
},
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: `${version}/[name].js`,
path: path.resolve(__dirname, "Pages"),
publicPath: "/Pages/",
clean: true,
},
devServer: {
headers: { "Access-Control-Allow-Origin": "*" }, // eslint-disable-line @typescript-eslint/naming-convention
static: __dirname,
server: {
type: "https",
options: env.WEBPACK_BUILD || options.https !== undefined ? options.https : await getHttpsOptions(),
},
port: process.env.npm_package_config_dev_server_port || 44336,
},
};
return config;
};