forked from dfinity/internet-identity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.js
155 lines (143 loc) · 4.6 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
const path = require("path");
const webpack = require("webpack");
const CopyPlugin = require("copy-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
require("dotenv").config();
/** Read the II canister ID from dfx's local state */
function readCanisterId() {
const canisterIdsJson = "./.dfx/local/canister_ids.json";
let canisterId;
try {
canisterId = require(canisterIdsJson).internet_identity.local;
} catch (e) {
throw Error(`Could get canister ID from ${canisterIdsJson}: ${e}`);
}
console.log("Read canister ID:", canisterId);
return canisterId;
}
// This plugin emulates the behaviour of http.rs while using webpack dev server locally
// so we don't need to proxy to the backend canister for the index.html file.
// This overcomes some issues with Safari and the CSP headers set in http.rs.
class InjectCanisterIdPlugin {
apply(compiler) {
compiler.hooks.compilation.tap("InjectCanisterIdPlugin", (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
"InjectCanisterIdPlugin",
(data, cb) => {
data.html = data.html.replace(
'<script id="setupJs"></script>',
`<script data-canister-id="${readCanisterId()}" id="setupJs"></script>`
);
cb(null, data);
}
);
});
}
}
const isProduction = process.env.NODE_ENV === "production";
const devtool = isProduction ? undefined : "source-map";
/* Default configuration */
const defaults = {
mode: isProduction ? "production" : "development",
devtool,
optimization: {
minimize: isProduction,
minimizer: [new CssMinimizerPlugin(), "..."],
},
output: { clean: true },
resolve: {
extensions: [".js", ".ts"],
fallback: {
stream: require.resolve("stream-browserify/"),
},
},
module: {
rules: [
{ test: /\.(ts)$/, loader: "ts-loader" },
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : "style-loader",
"css-loader",
],
},
{
test: /\.(png|jpg|gif)$/i,
type: "asset/resource",
},
],
},
plugins: [
...(isProduction ? [new MiniCssExtractPlugin()] : []),
new webpack.ProvidePlugin({
Buffer: [require.resolve("buffer/"), "Buffer"],
process: require.resolve("process/browser"),
}),
new webpack.EnvironmentPlugin({
II_FETCH_ROOT_KEY: "0",
II_DUMMY_AUTH: "0",
II_DUMMY_CAPTCHA: "0",
}),
new CompressionPlugin({
test: /\.js(\?.*)?$/i,
}),
new webpack.IgnorePlugin(/^\.\/wordlists\/(?!english)/, /bip39\/src$/),
new CopyPlugin({
patterns: [
{
from: path.join(__dirname, "src", "frontend", "assets"),
to: path.join(__dirname, "dist"),
// We want the html file from HtmlWebpackPlugin, not the original one
filter: (resourcePath) => {
return !resourcePath.endsWith("index.html");
},
},
],
}),
new HtmlWebpackPlugin({
template: "src/frontend/assets/index.html",
// Don't inject the index.js in production, because the canister actually injects it (see http.rs for more details)
// When true, injects (a hot-reloading version of) the built javascript, which in turn inserts the CSS (through "style-loader").
// This value is read by the template; see index.html for more details.
inject: !isProduction,
}),
],
};
module.exports = [
{
...defaults,
name: "app",
entry: {
index: path.join(__dirname, "src", "frontend", "src", "index"),
},
devServer: {
// Set up a proxy that redirects API calls to the replica.
port: 8080,
proxy: {
// Make sure /api calls land on the replica (and not on webpack)
"/api": "http://localhost:8000",
},
allowedHosts: [".localhost", ".local", ".ngrok.io"],
},
plugins: [
...defaults.plugins,
// Inject canister ID when using the dev server, so that the local file can be used
// (instead of the HTML served by the canister)
...(isProduction ? [] : [new InjectCanisterIdPlugin()]),
],
},
{
...defaults,
name: "showcase",
entry: {
showcase: path.join(__dirname, "src", "frontend", "src", "showcase"),
},
devServer: {
port: 8080,
historyApiFallback: true, // serves the app on all routes, which we use because the app itself does the routing
},
},
];