canopy-webpack-config 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.yarnrc.yml CHANGED
@@ -1,2 +1,7 @@
1
- yarnPath: .yarn/releases/yarn-3.6.2.cjs
1
+ compressionLevel: mixed
2
+
3
+ enableGlobalCache: false
4
+
2
5
  nodeLinker: node-modules
6
+
7
+ yarnPath: .yarn/releases/yarn-4.10.3.cjs
package/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @CanopyTax/frontend-leads
1
+ * @CanopyTax/frontend-icc
package/package.json CHANGED
@@ -1,23 +1,26 @@
1
1
  {
2
2
  "name": "canopy-webpack-config",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
4
4
  "description": "Some defaults for webpack configs at canopy",
5
5
  "main": "src/canopy-webpack-config.js",
6
+ "exports": {
7
+ ".": "./src/canopy-webpack-config.js",
8
+ "./esm": "./src/canopy-webpack-config-esm.mjs"
9
+ },
6
10
  "repository": "git@github.com:CanopyTax/canopy-webpack-config.git",
7
- "author": "Joel Denning <joel.denning@canopytax.com>",
8
11
  "license": "Apache-2.0",
9
- "devDependencies": {
10
- "prettier": "^2.8.8"
11
- },
12
12
  "peerDependencies": {
13
13
  "@babel/plugin-transform-runtime": ">=7",
14
14
  "@babel/runtime": ">=7"
15
15
  },
16
+ "devDependencies": {
17
+ "prettier": "^3.6.2"
18
+ },
16
19
  "dependencies": {
17
20
  "clean-webpack-plugin": "^4.0.0",
18
21
  "url": "^0.11.0",
19
22
  "webpack-bundle-analyzer": "^4.7.0",
20
23
  "webpack-merge": "^4.2.1"
21
24
  },
22
- "packageManager": "yarn@3.6.2"
25
+ "packageManager": "yarn@4.10.3"
23
26
  }
@@ -0,0 +1,200 @@
1
+ import path from "path";
2
+ import { CleanWebpackPlugin } from "clean-webpack-plugin";
3
+ import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
4
+ import merge from "webpack-merge";
5
+ import fs from "fs";
6
+ import { homedir } from "os";
7
+
8
+ let isDevServer = false;
9
+ if (process.argv.some((arg) => arg.includes("serve"))) {
10
+ isDevServer = true;
11
+ }
12
+
13
+ const hostIndex = process.argv.findIndex((arg) => arg === "--host");
14
+ const host =
15
+ hostIndex >= 0 && process.argv[hostIndex + 1]
16
+ ? process.argv[hostIndex + 1]
17
+ : "0.0.0.0";
18
+
19
+ const portIndex = process.argv.findIndex((arg) => arg === "--port");
20
+ const port =
21
+ portIndex >= 0 && process.argv[portIndex + 1]
22
+ ? process.argv[portIndex + 1]
23
+ : "8080";
24
+
25
+ // --- Externals matching helpers ---
26
+ const externalPatterns = [
27
+ /^lodash$/,
28
+ /^moment$/,
29
+ /^luxon$/,
30
+ /^prop-types$/,
31
+ /^react-dom$/,
32
+ /^react-dom\/client$/,
33
+ /^react-dom\/server$/,
34
+ /^react\/lib.*/,
35
+ /^react$/,
36
+ /^rxjs\/?.*$/,
37
+ /^single-spa-canopy$/,
38
+ /^single-spa$/,
39
+ /^@canopytax\/[^\/]+$/,
40
+ /^react-hook-form$/,
41
+ /^react-router-dom-v6$/,
42
+ ];
43
+
44
+ export default function (name, overridesConfig = {}, options = {}) {
45
+ const { externals: hasExternals } = options;
46
+
47
+ if (typeof name !== "string") {
48
+ throw new Error(
49
+ "canopy-webpack-config-esm expects a string name as the first argument",
50
+ );
51
+ }
52
+ if (
53
+ typeof overridesConfig !== "object" &&
54
+ typeof overridesConfig !== "function"
55
+ ) {
56
+ throw new Error(
57
+ "canopy-webpack-config-esm expects an object as overrides. Received " +
58
+ typeof overridesConfig,
59
+ );
60
+ }
61
+
62
+ return function (env = {}) {
63
+ const defaultCanopyConfig = {
64
+ mode: env.dev || isDevServer ? "development" : "production",
65
+ context: process.cwd(),
66
+
67
+ // Modern ESM-friendly output
68
+ target: ["web", "es2020"],
69
+
70
+ entry: {
71
+ [name]: `./src/${name}.ts`,
72
+ ...(hasExternals && {
73
+ [`${name}-externals`]: `./src/externals.ts`,
74
+ }),
75
+ },
76
+
77
+ // ESM output configuration
78
+ output: {
79
+ filename: (pathData) =>
80
+ pathData.chunk.name === `${name}-externals`
81
+ ? `${name}-externals.js`
82
+ : `${pathData.chunk.name}.js`,
83
+ chunkFilename: "[name].js", // predictable ESM chunk names
84
+ chunkLoading: "import", // load chunks via `import()`
85
+ path: path.resolve(process.cwd(), "build"),
86
+ publicPath: "auto", // resolve chunks relative to the loaded entry URL
87
+ library: { type: "module" }, // emit as native ESM
88
+ environment: { module: true },
89
+ chunkFormat: "module",
90
+ },
91
+
92
+ experiments: {
93
+ outputModule: true,
94
+ },
95
+
96
+ optimization: {
97
+ runtimeChunk: false,
98
+ splitChunks: { chunks: "async" },
99
+ minimize: false,
100
+ },
101
+
102
+ externalsType: "module",
103
+ externals: [
104
+ function (data, callback) {
105
+ const { request } = data;
106
+ if (externalPatterns.some((re) => re.test(request))) {
107
+ return callback(null, `module ${request}`);
108
+ }
109
+ return callback();
110
+ },
111
+ ],
112
+
113
+ resolve: {
114
+ fullySpecified: false,
115
+ extensions: [".tsx", ".ts", ".js", ".jsx", ".json"],
116
+ modules: [process.cwd(), "node_modules"],
117
+ },
118
+
119
+ module: {
120
+ rules: [
121
+ {
122
+ test: /\.(js|jsx|ts|tsx)$/,
123
+ exclude: /node_modules/,
124
+ use: {
125
+ loader: "babel-loader",
126
+ options: {
127
+ presets: [
128
+ [
129
+ "@babel/preset-env",
130
+ { targets: "defaults", modules: false },
131
+ ],
132
+ ["@babel/preset-react", { runtime: "automatic" }],
133
+ "@babel/preset-typescript",
134
+ ],
135
+ plugins: ["@babel/plugin-transform-runtime"],
136
+ },
137
+ },
138
+ },
139
+ ],
140
+ },
141
+
142
+ plugins: [
143
+ new CleanWebpackPlugin({
144
+ cleanOnceBeforeBuildPatterns: ["**/*", "!.gitkeep"],
145
+ }),
146
+ env.analyze === "server" &&
147
+ new BundleAnalyzerPlugin({ analyzerMode: "server" }),
148
+ env.analyze === "static" &&
149
+ new BundleAnalyzerPlugin({
150
+ analyzerMode: "static",
151
+ openAnalyzer: false,
152
+ }),
153
+ ].filter(Boolean),
154
+
155
+ devtool: "source-map",
156
+
157
+ devServer: isDevServer
158
+ ? {
159
+ host,
160
+ port,
161
+ server: (() => {
162
+ const sslPath = path.join(homedir(), ".canopy-ssl");
163
+ const keyPath = path.join(sslPath, "key.pem");
164
+ const certPath = path.join(sslPath, "public.pem");
165
+
166
+ if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
167
+ return {
168
+ type: "https",
169
+ options: {
170
+ key: fs.readFileSync(keyPath),
171
+ cert: fs.readFileSync(certPath),
172
+ // http2: true, // optional
173
+ },
174
+ };
175
+ }
176
+ return { type: "http" };
177
+ })(),
178
+ headers: {
179
+ "Access-Control-Allow-Origin": "*",
180
+ "Access-Control-Allow-Methods":
181
+ "GET, POST, PUT, DELETE, PATCH, OPTIONS",
182
+ "Access-Control-Allow-Headers":
183
+ "X-Requested-With, content-type, Authorization",
184
+ "Access-Control-Allow-Private-Network": "true",
185
+ },
186
+ allowedHosts: "all",
187
+ hot: false,
188
+ liveReload: false,
189
+ client: false,
190
+ }
191
+ : undefined,
192
+ };
193
+
194
+ if (typeof overridesConfig === "function") {
195
+ return overridesConfig(defaultCanopyConfig, env);
196
+ } else {
197
+ return merge(defaultCanopyConfig, overridesConfig);
198
+ }
199
+ };
200
+ }
@@ -122,6 +122,7 @@ module.exports = function (name, overridesConfig = {}, options = {}) {
122
122
  /^@canopytax\/[^\/]+$/,
123
123
  /^cp-analytics$/,
124
124
  /^react-hook-form$/,
125
+ /^react-router-dom-v6$/,
125
126
  ],
126
127
 
127
128
  devServer: isDevServer