@pinnacle0/webpack-util 0.3.25 → 0.3.26

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.
Files changed (139) hide show
  1. package/config/jest.config.ts +35 -0
  2. package/config/tsconfig.script.json +10 -0
  3. package/config/tsconfig.src.json +12 -0
  4. package/config/tsconfig.test.json +11 -0
  5. package/package.json +2 -2
  6. package/script/build.ts +65 -0
  7. package/script/format.ts +7 -0
  8. package/src/CanadyarnRunner.ts +35 -0
  9. package/src/CodeStyleChecker.ts +44 -0
  10. package/src/{Constant.js → Constant.ts} +1 -5
  11. package/src/CoreUtil.ts +24 -0
  12. package/src/ProjectStructureChecker.ts +119 -0
  13. package/src/TestRunner.ts +28 -0
  14. package/src/TypescriptTypeChecker.ts +29 -0
  15. package/src/{WebpackBuilder.js → WebpackBuilder.ts} +71 -51
  16. package/src/WebpackConfigGenerator/{ConfigEntryDescriptorsFactory.js → ConfigEntryDescriptorsFactory.ts} +36 -29
  17. package/src/WebpackConfigGenerator/HTMLWebpackPluginsFactory.ts +24 -0
  18. package/src/WebpackConfigGenerator/Plugin/css.plugin.ts +31 -0
  19. package/src/WebpackConfigGenerator/Plugin/html.plugin.ts +47 -0
  20. package/src/WebpackConfigGenerator/Plugin/index.ts +33 -0
  21. package/src/WebpackConfigGenerator/Plugin/{moment.plugin.js → moment.plugin.ts} +5 -12
  22. package/src/WebpackConfigGenerator/Plugin/script-tag-crossorigin-plugin.ts +22 -0
  23. package/src/WebpackConfigGenerator/Plugin/ts.plugin.ts +29 -0
  24. package/src/WebpackConfigGenerator/Plugin/webpack.plugin.ts +21 -0
  25. package/src/WebpackConfigGenerator/Rule/{RegExpUtil.js → RegExpUtil.ts} +8 -14
  26. package/src/WebpackConfigGenerator/Rule/{core-fe-hmr-babel-plugin.js → core-fe-hmr-babel-plugin.ts} +43 -9
  27. package/src/WebpackConfigGenerator/Rule/{image.rule.js → image.rule.ts} +5 -8
  28. package/src/WebpackConfigGenerator/Rule/index.ts +17 -0
  29. package/src/WebpackConfigGenerator/Rule/other.rule.ts +23 -0
  30. package/src/WebpackConfigGenerator/Rule/{stylesheet.rule.js → stylesheet.rule.ts} +34 -30
  31. package/src/WebpackConfigGenerator/Rule/{ts.rule.js → ts.rule.ts} +18 -16
  32. package/src/WebpackConfigGenerator/{WebpackConfigSerializationUtil.js → WebpackConfigSerializationUtil.ts} +23 -22
  33. package/src/WebpackConfigGenerator/WebpackEntryFactory.ts +22 -0
  34. package/src/WebpackConfigGenerator/WebpackOutputPublicURLFactory.ts +22 -0
  35. package/src/WebpackConfigGenerator/{WebpackResolveAliasFactory.js → WebpackResolveAliasFactory.ts} +16 -13
  36. package/src/WebpackConfigGenerator/WebpackResolveExtensionsFactory.ts +19 -0
  37. package/src/WebpackConfigGenerator/{WebpackResolveModulesFactory.js → WebpackResolveModulesFactory.ts} +9 -7
  38. package/src/WebpackConfigGenerator/index.ts +213 -0
  39. package/src/WebpackServerStarter.ts +138 -0
  40. package/src/index.ts +9 -0
  41. package/src/{type.d.ts → type.ts} +8 -4
  42. package/test/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin/__snapshots__/shouldIgnore.test.ts.snap +21 -0
  43. package/test/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin/__snapshots__/shouldTransform.test.ts.snap +53 -0
  44. package/test/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin/shouldIgnore.test.ts +36 -0
  45. package/test/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin/shouldTransform.test.ts +72 -0
  46. package/test/WebpackConfigGenerator/plugin/fixture/script.js +2 -0
  47. package/test/WebpackConfigGenerator/plugin/fixture/script1.js +1 -0
  48. package/test/WebpackConfigGenerator/plugin/script-tag-crossorigin-plugin.test.ts +58 -0
  49. package/test/test-project/package.json +5 -0
  50. package/tsconfig.json +15 -0
  51. package/src/CanadyarnRunner.d.ts +0 -14
  52. package/src/CanadyarnRunner.js +0 -38
  53. package/src/CanadyarnRunner.js.map +0 -1
  54. package/src/CodeStyleChecker.d.ts +0 -10
  55. package/src/CodeStyleChecker.js +0 -44
  56. package/src/CodeStyleChecker.js.map +0 -1
  57. package/src/Constant.d.ts +0 -21
  58. package/src/Constant.js.map +0 -1
  59. package/src/CoreUtil.d.ts +0 -11
  60. package/src/CoreUtil.js +0 -26
  61. package/src/CoreUtil.js.map +0 -1
  62. package/src/ProjectStructureChecker.d.ts +0 -18
  63. package/src/ProjectStructureChecker.js +0 -113
  64. package/src/ProjectStructureChecker.js.map +0 -1
  65. package/src/TestRunner.d.ts +0 -8
  66. package/src/TestRunner.js +0 -30
  67. package/src/TestRunner.js.map +0 -1
  68. package/src/TypescriptTypeChecker.d.ts +0 -11
  69. package/src/TypescriptTypeChecker.js +0 -32
  70. package/src/TypescriptTypeChecker.js.map +0 -1
  71. package/src/WebpackBuilder.d.ts +0 -38
  72. package/src/WebpackBuilder.js.map +0 -1
  73. package/src/WebpackConfigGenerator/ConfigEntryDescriptorsFactory.d.ts +0 -13
  74. package/src/WebpackConfigGenerator/ConfigEntryDescriptorsFactory.js.map +0 -1
  75. package/src/WebpackConfigGenerator/HTMLWebpackPluginsFactory.d.ts +0 -9
  76. package/src/WebpackConfigGenerator/HTMLWebpackPluginsFactory.js +0 -20
  77. package/src/WebpackConfigGenerator/HTMLWebpackPluginsFactory.js.map +0 -1
  78. package/src/WebpackConfigGenerator/Plugin/css.plugin.d.ts +0 -16
  79. package/src/WebpackConfigGenerator/Plugin/css.plugin.js +0 -33
  80. package/src/WebpackConfigGenerator/Plugin/css.plugin.js.map +0 -1
  81. package/src/WebpackConfigGenerator/Plugin/html.plugin.d.ts +0 -16
  82. package/src/WebpackConfigGenerator/Plugin/html.plugin.js +0 -48
  83. package/src/WebpackConfigGenerator/Plugin/html.plugin.js.map +0 -1
  84. package/src/WebpackConfigGenerator/Plugin/index.d.ts +0 -27
  85. package/src/WebpackConfigGenerator/Plugin/index.js +0 -32
  86. package/src/WebpackConfigGenerator/Plugin/index.js.map +0 -1
  87. package/src/WebpackConfigGenerator/Plugin/moment.plugin.d.ts +0 -10
  88. package/src/WebpackConfigGenerator/Plugin/moment.plugin.js.map +0 -1
  89. package/src/WebpackConfigGenerator/Plugin/script-tag-crossorigin-plugin.d.ts +0 -4
  90. package/src/WebpackConfigGenerator/Plugin/script-tag-crossorigin-plugin.js +0 -28
  91. package/src/WebpackConfigGenerator/Plugin/script-tag-crossorigin-plugin.js.map +0 -1
  92. package/src/WebpackConfigGenerator/Plugin/ts.plugin.d.ts +0 -16
  93. package/src/WebpackConfigGenerator/Plugin/ts.plugin.js +0 -31
  94. package/src/WebpackConfigGenerator/Plugin/ts.plugin.js.map +0 -1
  95. package/src/WebpackConfigGenerator/Plugin/webpack.plugin.d.ts +0 -14
  96. package/src/WebpackConfigGenerator/Plugin/webpack.plugin.js +0 -24
  97. package/src/WebpackConfigGenerator/Plugin/webpack.plugin.js.map +0 -1
  98. package/src/WebpackConfigGenerator/Rule/RegExpUtil.d.ts +0 -4
  99. package/src/WebpackConfigGenerator/Rule/RegExpUtil.js.map +0 -1
  100. package/src/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin.d.ts +0 -13
  101. package/src/WebpackConfigGenerator/Rule/core-fe-hmr-babel-plugin.js.map +0 -1
  102. package/src/WebpackConfigGenerator/Rule/image.rule.d.ts +0 -9
  103. package/src/WebpackConfigGenerator/Rule/image.rule.js.map +0 -1
  104. package/src/WebpackConfigGenerator/Rule/index.d.ts +0 -13
  105. package/src/WebpackConfigGenerator/Rule/index.js +0 -18
  106. package/src/WebpackConfigGenerator/Rule/index.js.map +0 -1
  107. package/src/WebpackConfigGenerator/Rule/other.rule.d.ts +0 -12
  108. package/src/WebpackConfigGenerator/Rule/other.rule.js +0 -22
  109. package/src/WebpackConfigGenerator/Rule/other.rule.js.map +0 -1
  110. package/src/WebpackConfigGenerator/Rule/stylesheet.rule.d.ts +0 -17
  111. package/src/WebpackConfigGenerator/Rule/stylesheet.rule.js.map +0 -1
  112. package/src/WebpackConfigGenerator/Rule/ts.rule.d.ts +0 -18
  113. package/src/WebpackConfigGenerator/Rule/ts.rule.js.map +0 -1
  114. package/src/WebpackConfigGenerator/WebpackConfigSerializationUtil.d.ts +0 -10
  115. package/src/WebpackConfigGenerator/WebpackConfigSerializationUtil.js.map +0 -1
  116. package/src/WebpackConfigGenerator/WebpackEntryFactory.d.ts +0 -9
  117. package/src/WebpackConfigGenerator/WebpackEntryFactory.js +0 -14
  118. package/src/WebpackConfigGenerator/WebpackEntryFactory.js.map +0 -1
  119. package/src/WebpackConfigGenerator/WebpackOutputPublicURLFactory.d.ts +0 -11
  120. package/src/WebpackConfigGenerator/WebpackOutputPublicURLFactory.js +0 -16
  121. package/src/WebpackConfigGenerator/WebpackOutputPublicURLFactory.js.map +0 -1
  122. package/src/WebpackConfigGenerator/WebpackResolveAliasFactory.d.ts +0 -11
  123. package/src/WebpackConfigGenerator/WebpackResolveAliasFactory.js.map +0 -1
  124. package/src/WebpackConfigGenerator/WebpackResolveExtensionsFactory.d.ts +0 -7
  125. package/src/WebpackConfigGenerator/WebpackResolveExtensionsFactory.js +0 -16
  126. package/src/WebpackConfigGenerator/WebpackResolveExtensionsFactory.js.map +0 -1
  127. package/src/WebpackConfigGenerator/WebpackResolveModulesFactory.d.ts +0 -7
  128. package/src/WebpackConfigGenerator/WebpackResolveModulesFactory.js.map +0 -1
  129. package/src/WebpackConfigGenerator/index.d.ts +0 -31
  130. package/src/WebpackConfigGenerator/index.js +0 -191
  131. package/src/WebpackConfigGenerator/index.js.map +0 -1
  132. package/src/WebpackServerStarter.d.ts +0 -28
  133. package/src/WebpackServerStarter.js +0 -111
  134. package/src/WebpackServerStarter.js.map +0 -1
  135. package/src/index.d.ts +0 -10
  136. package/src/index.js +0 -8
  137. package/src/index.js.map +0 -1
  138. package/src/type.js +0 -3
  139. package/src/type.js.map +0 -1
@@ -1,12 +1,12 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.stylesheetRule = void 0;
7
- const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
8
- const RegExpUtil_1 = require("./RegExpUtil");
9
- function cssLoader(importLoaders) {
1
+ import MiniCssExtractPlugin from "mini-css-extract-plugin";
2
+ import type webpack from "webpack";
3
+ import {RegExpUtil} from "./RegExpUtil";
4
+
5
+ interface StylesheetRuleDeps {
6
+ minimize: boolean;
7
+ }
8
+
9
+ function cssLoader(importLoaders: number): webpack.RuleSetUseItem {
10
10
  return {
11
11
  loader: require.resolve("css-loader"),
12
12
  options: {
@@ -14,7 +14,8 @@ function cssLoader(importLoaders) {
14
14
  },
15
15
  };
16
16
  }
17
- function lessLoader() {
17
+
18
+ function lessLoader(): webpack.RuleSetUseItem {
18
19
  return {
19
20
  loader: require.resolve("less-loader"),
20
21
  options: {
@@ -24,12 +25,14 @@ function lessLoader() {
24
25
  },
25
26
  };
26
27
  }
27
- function miniCssExtractPluginLoader() {
28
+
29
+ function miniCssExtractPluginLoader(): webpack.RuleSetUseItem {
28
30
  return {
29
- loader: require.resolve(mini_css_extract_plugin_1.default.loader),
31
+ loader: require.resolve(MiniCssExtractPlugin.loader),
30
32
  };
31
33
  }
32
- function postcssLoader() {
34
+
35
+ function postcssLoader(): webpack.RuleSetUseItem {
33
36
  return {
34
37
  loader: require.resolve("postcss-loader"),
35
38
  options: {
@@ -42,11 +45,13 @@ function postcssLoader() {
42
45
  },
43
46
  };
44
47
  }
45
- function styleLoader() {
48
+
49
+ function styleLoader(): webpack.RuleSetUseItem {
46
50
  return {
47
51
  loader: require.resolve("style-loader"),
48
52
  };
49
53
  }
54
+
50
55
  /**
51
56
  * Handles dependency requests to stylesheet assets (".css", ".less")
52
57
  * with `minimize: true` by `lessc` -> transform to js module -> inject to DOM as <style> tag,
@@ -58,23 +63,24 @@ function styleLoader() {
58
63
  * @see https://webpack.js.org/loaders/postcss-loader/
59
64
  * @see https://webpack.js.org/loaders/style-loader/
60
65
  */
61
- function stylesheetRule({ minimize }) {
62
- const use = minimize
66
+ export function stylesheetRule({minimize}: StylesheetRuleDeps): webpack.RuleSetRule {
67
+ const use: webpack.RuleSetUseItem[] = minimize
63
68
  ? [
64
- miniCssExtractPluginLoader(),
65
- cssLoader(2),
66
- postcssLoader(),
67
- lessLoader(),
68
- // prettier-format-preserve
69
- ]
69
+ miniCssExtractPluginLoader(),
70
+ cssLoader(2),
71
+ postcssLoader(),
72
+ lessLoader(),
73
+ // prettier-format-preserve
74
+ ]
70
75
  : [
71
- styleLoader(),
72
- cssLoader(1),
73
- lessLoader(),
74
- // prettier-format-preserve
75
- ];
76
+ styleLoader(),
77
+ cssLoader(1),
78
+ lessLoader(),
79
+ // prettier-format-preserve
80
+ ];
81
+
76
82
  return {
77
- test: RegExpUtil_1.RegExpUtil.fileExtension(".css", ".less"),
83
+ test: RegExpUtil.fileExtension(".css", ".less"),
78
84
  use,
79
85
  // Declare all css/less imports as side effects (not to be considered
80
86
  // as dead code), regardless of the containing package claims to be
@@ -84,5 +90,3 @@ function stylesheetRule({ minimize }) {
84
90
  sideEffects: true,
85
91
  };
86
92
  }
87
- exports.stylesheetRule = stylesheetRule;
88
- //# sourceMappingURL=stylesheet.rule.js.map
@@ -1,11 +1,12 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.tsRule = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const RegExpUtil_1 = require("./RegExpUtil");
1
+ import path from "path";
2
+ import type webpack from "webpack";
3
+ import {RegExpUtil} from "./RegExpUtil";
4
+
5
+ interface Deps {
6
+ tsconfigFilepath: string;
7
+ fastRefresh: boolean;
8
+ }
9
+
9
10
  /**
10
11
  * Handles dependency requests to typescript files
11
12
  * by compiling with `tsc`.
@@ -17,15 +18,16 @@ const RegExpUtil_1 = require("./RegExpUtil");
17
18
  * @see https://github.com/TypeStrong/ts-loader
18
19
  * @see https://github.com/pmmmwh/react-refresh-webpack-plugin
19
20
  */
20
- function tsRule({ tsconfigFilepath, fastRefresh }) {
21
- const babelLoader = {
21
+ export function tsRule({tsconfigFilepath, fastRefresh}: Deps): webpack.RuleSetRule {
22
+ const babelLoader: webpack.RuleSetUseItem = {
22
23
  loader: require.resolve("babel-loader"),
23
24
  options: {
24
- plugins: [require.resolve(path_1.default.join(__dirname, "./core-fe-hmr-babel-plugin")), require.resolve("react-refresh/babel")],
25
+ plugins: [require.resolve(path.join(__dirname, "./core-fe-hmr-babel-plugin")), require.resolve("react-refresh/babel")],
25
26
  },
26
27
  };
28
+
27
29
  // TODO/Alvis: Check whether ts-loader can be replaced by babel loader
28
- const tsLoader = {
30
+ const tsLoader: webpack.RuleSetUseItem = {
29
31
  loader: require.resolve("ts-loader"),
30
32
  options: {
31
33
  colors: false,
@@ -38,7 +40,8 @@ function tsRule({ tsconfigFilepath, fastRefresh }) {
38
40
  transpileOnly: true,
39
41
  },
40
42
  };
41
- const swcLoader = {
43
+
44
+ const swcLoader: webpack.RuleSetUseItem = {
42
45
  loader: require.resolve("swc-loader"),
43
46
  options: {
44
47
  jsc: {
@@ -57,10 +60,9 @@ function tsRule({ tsconfigFilepath, fastRefresh }) {
57
60
  },
58
61
  },
59
62
  };
63
+
60
64
  return {
61
- test: RegExpUtil_1.RegExpUtil.fileExtension(".ts", ".tsx"),
65
+ test: RegExpUtil.fileExtension(".ts", ".tsx"),
62
66
  use: fastRefresh ? [babelLoader, tsLoader] : [swcLoader],
63
67
  };
64
68
  }
65
- exports.tsRule = tsRule;
66
- //# sourceMappingURL=ts.rule.js.map
@@ -1,15 +1,19 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WebpackConfigSerializationUtil = void 0;
7
- const pretty_format_1 = __importDefault(require("pretty-format"));
8
- class WebpackConfigSerializationUtil {
9
- static serializablePlugin(name, PluginConstructor, options) {
1
+ import prettyFormat from "pretty-format";
2
+ import type webpack from "webpack";
3
+
4
+ interface SerializableWebpackPluginDescriptor {
5
+ "@@WP_CONFIG_GEN_TYPE": "WebpackPluginConstructorCall";
6
+ pluginName: string;
7
+ pluginOptions: any;
8
+ }
9
+
10
+ export class WebpackConfigSerializationUtil {
11
+ static serializablePlugin<OptType, T extends {apply(..._: any[]): void}>(name: string, PluginConstructor: new () => T): webpack.WebpackPluginInstance;
12
+ static serializablePlugin<OptType, T extends {apply(..._: any[]): void}>(name: string, PluginConstructor: new (_: OptType) => T, options: OptType): webpack.WebpackPluginInstance;
13
+ static serializablePlugin<OptType, T extends {apply(..._: any[]): void}>(name: string, PluginConstructor: new (_?: OptType) => T, options?: OptType): webpack.WebpackPluginInstance {
10
14
  const plugin = new PluginConstructor(options);
11
15
  return Object.defineProperty(plugin, "toWebpackConfigSerializableType", {
12
- value() {
16
+ value(): SerializableWebpackPluginDescriptor {
13
17
  return {
14
18
  "@@WP_CONFIG_GEN_TYPE": "WebpackPluginConstructorCall",
15
19
  pluginName: name,
@@ -18,8 +22,9 @@ class WebpackConfigSerializationUtil {
18
22
  },
19
23
  });
20
24
  }
21
- static configToString(config) {
22
- const configString = (0, pretty_format_1.default)(config, {
25
+
26
+ static configToString(config: webpack.Configuration): string {
27
+ const configString = prettyFormat(config, {
23
28
  callToJSON: true,
24
29
  escapeRegex: false,
25
30
  escapeString: false,
@@ -27,23 +32,22 @@ class WebpackConfigSerializationUtil {
27
32
  printFunctionName: false,
28
33
  plugins: [
29
34
  {
30
- test(val) {
35
+ test(val: any) {
31
36
  try {
32
37
  return typeof val.toWebpackConfigSerializableType === "function";
33
- }
34
- catch (_a) {
38
+ } catch {
35
39
  return false;
36
40
  }
37
41
  },
38
- serialize(val, config, indentation, depth, refs, printer) {
39
- const _ = val.toWebpackConfigSerializableType();
42
+ serialize(val: any, config, indentation, depth, refs, printer) {
43
+ const _ = val.toWebpackConfigSerializableType() as SerializableWebpackPluginDescriptor;
40
44
  return `new ${_.pluginName}(${printer(_.pluginOptions, config, indentation, depth, refs)})`;
41
45
  },
42
46
  },
43
47
  ],
44
48
  });
45
49
  try {
46
- const { format } = require("prettier");
50
+ const {format} = require("prettier") as typeof import("prettier");
47
51
  return format("module.exports = " + configString, {
48
52
  arrowParens: "avoid",
49
53
  bracketSpacing: false,
@@ -52,12 +56,9 @@ class WebpackConfigSerializationUtil {
52
56
  useTabs: false,
53
57
  filepath: "webpack.config.js",
54
58
  });
55
- }
56
- catch (_a) {
59
+ } catch {
57
60
  // Either prettier cannot be loaded, or formatting failed, return the unformatted config as a fallback.
58
61
  return configString;
59
62
  }
60
63
  }
61
64
  }
62
- exports.WebpackConfigSerializationUtil = WebpackConfigSerializationUtil;
63
- //# sourceMappingURL=WebpackConfigSerializationUtil.js.map
@@ -0,0 +1,22 @@
1
+ import type webpack from "webpack";
2
+ import type {EntryDescriptor} from "../type";
3
+
4
+ interface StrictWebpackEntry {
5
+ [entryName: string]: [string];
6
+ }
7
+
8
+ interface WebpackEntryFactoryOptions {
9
+ configEntryDescriptors: EntryDescriptor[];
10
+ }
11
+
12
+ export class WebpackEntryFactory {
13
+ static generate({configEntryDescriptors}: WebpackEntryFactoryOptions): NonNullable<webpack.Configuration["entry"]> {
14
+ const entry: StrictWebpackEntry = {};
15
+
16
+ for (const {name, entryPath} of configEntryDescriptors) {
17
+ entry[name] = [entryPath];
18
+ }
19
+
20
+ return entry;
21
+ }
22
+ }
@@ -0,0 +1,22 @@
1
+ export interface WebpackOutputPublicURLFactoryOptions {
2
+ env: string | null;
3
+ /**
4
+ * Function to dynamically compute additional webpack config from `env`.
5
+ * Should validates if the config contains `publicUrl` field.
6
+ */
7
+ webpackPublicPath: string | ((env: string) => string) | undefined;
8
+ }
9
+
10
+ export class WebpackOutputPublicURLFactory {
11
+ static generate({env, webpackPublicPath}: WebpackOutputPublicURLFactoryOptions): string {
12
+ if (!env || !webpackPublicPath) {
13
+ return "/";
14
+ }
15
+
16
+ if (typeof webpackPublicPath === "string") {
17
+ return webpackPublicPath;
18
+ }
19
+
20
+ return webpackPublicPath(env);
21
+ }
22
+ }
@@ -1,19 +1,23 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebpackResolveAliasFactory = void 0;
4
- class WebpackResolveAliasFactory {
5
- static generate({ env, resolvers }) {
6
- const moduleAliasMap = {};
7
- for (const { prefix, resolver } of resolvers) {
1
+ import type {DynamicPathResolver} from "../type";
2
+
3
+ interface WebpackResolveAliasMapOptions {
4
+ env: string | null;
5
+ resolvers: DynamicPathResolver[];
6
+ }
7
+
8
+ export class WebpackResolveAliasFactory {
9
+ static generate({env, resolvers}: WebpackResolveAliasMapOptions): {[moduleAlias: string]: string} {
10
+ const moduleAliasMap: {[moduleAlias: string]: string} = {};
11
+
12
+ for (const {prefix, resolver} of resolvers) {
8
13
  if (prefix in moduleAliasMap) {
9
14
  throw new Error(`Duplicated resolver prefix: ${prefix}`);
10
- }
11
- else if (prefix.trim() === "") {
15
+ } else if (prefix.trim() === "") {
12
16
  throw new Error(`Resolver prefix cannot be empty`);
13
- }
14
- else if (/\s/.test(prefix)) {
17
+ } else if (/\s/.test(prefix)) {
15
18
  throw new Error(`Resolver prefix cannot contain whitespace, received: ${prefix}`);
16
19
  }
20
+
17
21
  if (resolver) {
18
22
  const resolvedRealPath = typeof resolver === "string" ? resolver : resolver(env);
19
23
  if (resolvedRealPath) {
@@ -21,8 +25,7 @@ class WebpackResolveAliasFactory {
21
25
  }
22
26
  }
23
27
  }
28
+
24
29
  return moduleAliasMap;
25
30
  }
26
31
  }
27
- exports.WebpackResolveAliasFactory = WebpackResolveAliasFactory;
28
- //# sourceMappingURL=WebpackResolveAliasFactory.js.map
@@ -0,0 +1,19 @@
1
+ import {Constant} from "../Constant";
2
+
3
+ interface WebpackResolveExtensionsFactoryOptions {
4
+ prioritizedExtensionPrefixes?: string[] | undefined;
5
+ }
6
+
7
+ export class WebpackResolveExtensionsFactory {
8
+ static generate({prioritizedExtensionPrefixes = []}: WebpackResolveExtensionsFactoryOptions): string[] {
9
+ const resolveExtensions = [];
10
+
11
+ for (const prefix of prioritizedExtensionPrefixes) {
12
+ resolveExtensions.push(...Constant.resolveExtensions.map(_ => `.${prefix}${_}`));
13
+ }
14
+
15
+ resolveExtensions.push(...Constant.resolveExtensions);
16
+
17
+ return resolveExtensions;
18
+ }
19
+ }
@@ -1,9 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebpackResolveModulesFactory = void 0;
4
- class WebpackResolveModulesFactory {
5
- static generate({ projectSrcDirectory }) {
1
+ interface WebpackResolveModulesFactoryOptions {
2
+ projectSrcDirectory: string;
3
+ }
4
+
5
+ export class WebpackResolveModulesFactory {
6
+ static generate({projectSrcDirectory}: WebpackResolveModulesFactoryOptions): string[] {
6
7
  const resolveModules = [];
8
+
7
9
  /**
8
10
  * To let webpack know how to resolve non-relative paths when `tsconfig.json#compilerOptions.baseUrl` is set to "./src"
9
11
  * Maybe refactor to a better resolution/aliasing solution later(?)
@@ -24,13 +26,13 @@ class WebpackResolveModulesFactory {
24
26
  * ```
25
27
  */
26
28
  resolveModules.push(projectSrcDirectory);
29
+
27
30
  /**
28
31
  * The default behavior to resolve non-relative paths is by looking inside `node_modules` folder.
29
32
  * Put at the end so this has the lowest precedence.
30
33
  */
31
34
  resolveModules.push("node_modules");
35
+
32
36
  return resolveModules;
33
37
  }
34
38
  }
35
- exports.WebpackResolveModulesFactory = WebpackResolveModulesFactory;
36
- //# sourceMappingURL=WebpackResolveModulesFactory.js.map
@@ -0,0 +1,213 @@
1
+ import {Utility} from "@pinnacle0/devtool-util";
2
+ import path from "path";
3
+ import type webpack from "webpack";
4
+ import {Constant} from "../Constant";
5
+ import {CoreUtil} from "../CoreUtil";
6
+ import type {EntryDescriptor, WebpackConfigGeneratorOptions} from "../type";
7
+ import {ConfigEntryDescriptorsFactory} from "./ConfigEntryDescriptorsFactory";
8
+ import {HTMLWebpackPluginsFactory} from "./HTMLWebpackPluginsFactory";
9
+ import {WebpackConfigSerializationUtil} from "./WebpackConfigSerializationUtil";
10
+ import {WebpackEntryFactory} from "./WebpackEntryFactory";
11
+ import {WebpackOutputPublicURLFactory} from "./WebpackOutputPublicURLFactory";
12
+ import {WebpackResolveAliasFactory} from "./WebpackResolveAliasFactory";
13
+ import {WebpackResolveExtensionsFactory} from "./WebpackResolveExtensionsFactory";
14
+ import {WebpackResolveModulesFactory} from "./WebpackResolveModulesFactory";
15
+ import {Plugin} from "./Plugin";
16
+ import {Rule} from "./Rule";
17
+
18
+ /**
19
+ * Generates a webpack config with sane defaults.
20
+ */
21
+ export class WebpackConfigGenerator {
22
+ private readonly env: string | null;
23
+ private readonly projectDirectory: string;
24
+ private readonly projectSrcDirectory: string;
25
+ private readonly tsconfigFilepath: string;
26
+ private readonly enableProfiling: boolean;
27
+ private readonly maxEntryPointKiloByte: number;
28
+ private readonly maxAssetKiloByte: number;
29
+ private readonly isFastMode: boolean;
30
+ private readonly verbose: boolean;
31
+ private readonly defineVars: {[key: string]: string};
32
+ private readonly extraExtensionsForOtherRule: string[];
33
+
34
+ private readonly configEntryDescriptors: EntryDescriptor[];
35
+ private readonly entry: NonNullable<webpack.Configuration["entry"]>;
36
+ private readonly htmlWebpackPluginInstances: NonNullable<webpack.Configuration["plugins"]>;
37
+ private readonly resolveExtensions: NonNullable<NonNullable<webpack.Configuration["resolve"]>["extensions"]>;
38
+ private readonly resolveModules: NonNullable<NonNullable<webpack.Configuration["resolve"]>["modules"]>;
39
+ private readonly resolveAliases: NonNullable<NonNullable<webpack.Configuration["resolve"]>["alias"]>;
40
+ private readonly outputPublicPath: string;
41
+
42
+ private readonly logger = Utility.createConsoleLogger("WebpackConfigGenerator");
43
+
44
+ constructor(private readonly options: WebpackConfigGeneratorOptions) {
45
+ this.env = CoreUtil.currentEnv();
46
+ this.projectDirectory = options.projectDirectory;
47
+ this.projectSrcDirectory = path.join(options.projectDirectory, "src");
48
+ this.tsconfigFilepath = path.join(options.projectDirectory, "tsconfig.json");
49
+
50
+ this.enableProfiling = CoreUtil.profilingEnabled();
51
+ this.isFastMode = CoreUtil.isFastMode();
52
+ this.maxEntryPointKiloByte = options.maxEntryPointKiloByte ?? Constant.maxEntryPointKiloByte;
53
+ this.maxAssetKiloByte = options.maxAssetKiloByte ?? Constant.maxAssetKiloByte;
54
+ this.verbose = options.verbose || false;
55
+ this.defineVars = options.defineVars || {};
56
+ this.extraExtensionsForOtherRule = options.extraExtensionsForOtherRule || [];
57
+
58
+ this.configEntryDescriptors = ConfigEntryDescriptorsFactory.generate({
59
+ indexName: options.indexName || "index",
60
+ projectSrcDirectory: this.projectSrcDirectory,
61
+ extraEntries: options.extraEntries || {},
62
+ });
63
+ this.entry = WebpackEntryFactory.generate({
64
+ configEntryDescriptors: this.configEntryDescriptors,
65
+ });
66
+ this.htmlWebpackPluginInstances = HTMLWebpackPluginsFactory.generate({
67
+ configEntryDescriptors: this.configEntryDescriptors,
68
+ });
69
+ this.outputPublicPath = WebpackOutputPublicURLFactory.generate({
70
+ env: this.env,
71
+ webpackPublicPath: options.webpackPublicPath,
72
+ });
73
+ this.resolveExtensions = WebpackResolveExtensionsFactory.generate({
74
+ prioritizedExtensionPrefixes: options.prioritizedExtensionPrefixes,
75
+ });
76
+ this.resolveModules = WebpackResolveModulesFactory.generate({
77
+ projectSrcDirectory: this.projectSrcDirectory,
78
+ });
79
+ this.resolveAliases = WebpackResolveAliasFactory.generate({
80
+ env: this.env,
81
+ resolvers: options.dynamicPathResolvers ?? [],
82
+ });
83
+
84
+ this.logger.info("Config constructed:");
85
+ for (const info of [
86
+ `-- Code Checking: ${this.isFastMode ? "Minimal Check" : "Default"}`,
87
+ `-- Env: ${this.env || "[N/A]"}`,
88
+ `-- Src Directory: ${this.projectSrcDirectory}`,
89
+ `-- HTML Entries: ${Object.keys(this.entry).join(" / ")}`,
90
+ `-- Webpack Public URL: ${this.outputPublicPath}`,
91
+ `-- Dynamic Aliases: ${JSON.stringify(this.resolveAliases, null, 4)}`,
92
+ `-- Use Cache: ${this.env === null}`,
93
+ ]) {
94
+ console.info(info);
95
+ }
96
+ }
97
+
98
+ development(): webpack.Configuration {
99
+ const config: webpack.Configuration = {
100
+ mode: "development",
101
+ entry: this.entry,
102
+ target: "web", // https://github.com/webpack/webpack-dev-server/issues/2758 Hot-reload will break if we provide list to target
103
+ output: {
104
+ filename: "static/js/[name].js",
105
+ publicPath: "/",
106
+ },
107
+ resolve: {
108
+ extensions: this.resolveExtensions,
109
+ modules: this.resolveModules,
110
+ alias: this.resolveAliases,
111
+ },
112
+ devtool: "inline-cheap-module-source-map",
113
+ optimization: {
114
+ usedExports: true,
115
+ splitChunks: {
116
+ automaticNameDelimiter: "-",
117
+ maxAsyncRequests: 30,
118
+ },
119
+ },
120
+ module: {
121
+ rules: [
122
+ Rule.ts({tsconfigFilepath: this.tsconfigFilepath, fastRefresh: true}),
123
+ Rule.stylesheet({minimize: false}),
124
+ Rule.image(),
125
+ Rule.other({extraExtensionsForOtherRule: this.extraExtensionsForOtherRule}),
126
+ // prettier-format-preserve
127
+ ],
128
+ },
129
+ plugins: [
130
+ ...this.htmlWebpackPluginInstances,
131
+ Plugin.ignoreMomentLocale(),
132
+ Plugin.reactRefresh(),
133
+ Plugin.webpack.progress({enableProfiling: false}),
134
+ Plugin.webpack.define(this.defineVars),
135
+ // prettier-format-preserve
136
+ ],
137
+ cache:
138
+ this.env === null
139
+ ? {
140
+ type: "filesystem",
141
+ cacheDirectory: path.join(this.projectDirectory, ".webpack-cache"),
142
+ }
143
+ : false,
144
+ };
145
+ if (this.verbose || CoreUtil.verbose()) {
146
+ this.logger.info("Full webpack config:");
147
+ console.info(WebpackConfigSerializationUtil.configToString(config));
148
+ }
149
+ return config;
150
+ }
151
+
152
+ production(outputDirectory: string): webpack.Configuration {
153
+ const config: webpack.Configuration = {
154
+ mode: "production",
155
+ entry: this.entry,
156
+ target: ["web", "es5"],
157
+ output: {
158
+ path: outputDirectory,
159
+ filename: this.enableProfiling ? "static/js/[name].js" : pathInfo => this.configEntryDescriptors.find(_ => _.name === pathInfo.chunk!.name)!.outputFilename,
160
+ chunkFilename: this.enableProfiling ? "static/js/[id].[name].js" : "static/js/[id].[chunkhash:8].js",
161
+ publicPath: this.outputPublicPath,
162
+ crossOriginLoading: "anonymous",
163
+ },
164
+ resolve: {
165
+ extensions: this.resolveExtensions,
166
+ modules: this.resolveModules,
167
+ alias: this.resolveAliases,
168
+ },
169
+ bail: true,
170
+ optimization: {
171
+ splitChunks: {
172
+ automaticNameDelimiter: "-",
173
+ maxAsyncRequests: 30,
174
+ },
175
+ minimizer: [
176
+ Plugin.minimizer.terser({sourceMap: true}),
177
+ Plugin.minimizer.css(),
178
+ // prettier-format-preserve
179
+ ],
180
+ },
181
+ performance: {
182
+ maxEntrypointSize: this.enableProfiling ? Number.MAX_SAFE_INTEGER : this.maxEntryPointKiloByte * 1000,
183
+ maxAssetSize: this.maxAssetKiloByte * 1000,
184
+ assetFilter: (filename: string) => Constant.mediaExtensions.concat(this.extraExtensionsForOtherRule).every(_ => !filename.endsWith(_)),
185
+ },
186
+ module: {
187
+ rules: [
188
+ Rule.ts({tsconfigFilepath: this.tsconfigFilepath, fastRefresh: false}),
189
+ Rule.stylesheet({minimize: true}),
190
+ Rule.image(),
191
+ Rule.other({extraExtensionsForOtherRule: this.extraExtensionsForOtherRule}),
192
+ // prettier-format-preserve
193
+ ],
194
+ },
195
+ plugins: [
196
+ ...this.htmlWebpackPluginInstances,
197
+ Plugin.scriptTagCrossOriginPlugin(),
198
+ Plugin.ignoreMomentLocale(),
199
+ Plugin.fileOutput.miniCssExtract({enableProfiling: this.enableProfiling}),
200
+ ...(this.enableProfiling ? [Plugin.webpack.progress({enableProfiling: true})] : []), // disable to not bloat up CI logs
201
+ Plugin.webpack.define(this.defineVars),
202
+ // prettier-format-preserve
203
+ ],
204
+ };
205
+ if (this.verbose || CoreUtil.verbose()) {
206
+ this.logger.info("Full webpack config:");
207
+ console.info(WebpackConfigSerializationUtil.configToString(config));
208
+ }
209
+ return config;
210
+ }
211
+ }
212
+
213
+ export type {WebpackConfigGeneratorOptions};