@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,20 +1,24 @@
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.ConfigEntryDescriptorsFactory = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const Constant_1 = require("../Constant");
10
- class ConfigEntryDescriptorsFactory {
11
- static generate({ indexName, projectSrcDirectory, extraEntries }) {
12
- const entryDescriptors = [];
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import {Constant} from "../Constant";
4
+ import type {EntryDescriptor} from "../type";
5
+
6
+ interface ConfigEntryDescriptorsFactoryOptions {
7
+ indexName: string;
8
+ projectSrcDirectory: string;
9
+ extraEntries: Record<string, string>;
10
+ }
11
+
12
+ export class ConfigEntryDescriptorsFactory {
13
+ static generate({indexName, projectSrcDirectory, extraEntries}: ConfigEntryDescriptorsFactoryOptions): EntryDescriptor[] {
14
+ const entryDescriptors: EntryDescriptor[] = [];
15
+
13
16
  const mainEntryDescriptor = ConfigEntryDescriptorsFactory.createEntryDescriptor({
14
17
  name: indexName,
15
18
  directory: projectSrcDirectory,
16
19
  });
17
20
  entryDescriptors.push(mainEntryDescriptor);
21
+
18
22
  for (const [extraEntryName, extraEntryDirectory] of Object.entries(extraEntries)) {
19
23
  const extraEntryDescriptor = ConfigEntryDescriptorsFactory.createEntryDescriptor({
20
24
  name: extraEntryName,
@@ -22,52 +26,55 @@ class ConfigEntryDescriptorsFactory {
22
26
  });
23
27
  entryDescriptors.push(extraEntryDescriptor);
24
28
  }
29
+
25
30
  return entryDescriptors;
26
31
  }
27
- static createEntryDescriptor({ name, directory }) {
32
+
33
+ private static createEntryDescriptor({name, directory}: {name: string; directory: string}): EntryDescriptor {
28
34
  const entryPath = ConfigEntryDescriptorsFactory.findEntryFilepath(directory);
29
35
  const htmlPath = ConfigEntryDescriptorsFactory.findEntryHTMLFilepath(directory);
36
+
30
37
  if (entryPath === null) {
31
- throw new Error(`Cannot find entry file for "${name}" in "${directory}", files checked: ${Constant_1.Constant.mainEntryFilenames.join("/")}`);
38
+ throw new Error(`Cannot find entry file for "${name}" in "${directory}", files checked: ${Constant.mainEntryFilenames.join("/")}`);
32
39
  }
40
+
33
41
  if (htmlPath === null) {
34
42
  // Output is a pure js entry (without a companion `index.html` template file)
35
43
  // Do not include a hash in the output filenames.
36
44
  // One particular use case for this is create a "third-party-error-handler" pure js entry,
37
45
  // so this static filename can be hard coded at our backend.
38
46
  const outputFilename = "static/js/[name].js";
39
- return { name, entryPath, outputFilename };
40
- }
41
- else {
47
+ return {name, entryPath, outputFilename};
48
+ } else {
42
49
  // Output is an html entry (with a companion `index.html` template file)
43
50
  // We might want to include a hash to the output filenames
44
51
  // (don't set the output filename to contain hash for profiling build).
45
52
  const outputFilename = "static/js/[chunkhash:8].js";
46
- return { name, entryPath, outputFilename, htmlPath };
53
+ return {name, entryPath, outputFilename, htmlPath};
47
54
  }
48
55
  }
49
- static findEntryFilepath(searchDirectory) {
50
- if (!(fs_1.default.existsSync(searchDirectory) && fs_1.default.statSync(searchDirectory).isDirectory())) {
56
+
57
+ private static findEntryFilepath(searchDirectory: string): string | null {
58
+ if (!(fs.existsSync(searchDirectory) && fs.statSync(searchDirectory).isDirectory())) {
51
59
  return null;
52
60
  }
53
- for (const filename of Constant_1.Constant.mainEntryFilenames) {
54
- const filepath = path_1.default.join(searchDirectory, filename);
55
- if (fs_1.default.existsSync(filepath) && fs_1.default.statSync(filepath).isFile()) {
61
+ for (const filename of Constant.mainEntryFilenames) {
62
+ const filepath = path.join(searchDirectory, filename);
63
+ if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) {
56
64
  return filepath;
57
65
  }
58
66
  }
59
67
  return null;
60
68
  }
61
- static findEntryHTMLFilepath(searchDirectory) {
62
- if (!(fs_1.default.existsSync(searchDirectory) && fs_1.default.statSync(searchDirectory).isDirectory())) {
69
+
70
+ private static findEntryHTMLFilepath(searchDirectory: string): string | null {
71
+ if (!(fs.existsSync(searchDirectory) && fs.statSync(searchDirectory).isDirectory())) {
63
72
  return null;
64
73
  }
65
- const filepath = path_1.default.join(searchDirectory, "index.html");
66
- if (fs_1.default.existsSync(filepath) && fs_1.default.statSync(filepath).isFile()) {
74
+ const filepath = path.join(searchDirectory, "index.html");
75
+ if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) {
67
76
  return filepath;
68
77
  }
69
78
  return null;
70
79
  }
71
80
  }
72
- exports.ConfigEntryDescriptorsFactory = ConfigEntryDescriptorsFactory;
73
- //# sourceMappingURL=ConfigEntryDescriptorsFactory.js.map
@@ -0,0 +1,24 @@
1
+ import type webpack from "webpack";
2
+ import type {EntryDescriptor} from "../type";
3
+ import {Plugin} from "./Plugin";
4
+
5
+ interface HTMLWebpackPluginsFactoryOptions {
6
+ configEntryDescriptors: EntryDescriptor[];
7
+ }
8
+
9
+ export class HTMLWebpackPluginsFactory {
10
+ static generate({configEntryDescriptors}: HTMLWebpackPluginsFactoryOptions): webpack.Plugin[] {
11
+ const htmlPlugins: webpack.Plugin[] = [];
12
+
13
+ for (const {name, entryPath, htmlPath} of configEntryDescriptors) {
14
+ if (htmlPath !== undefined) {
15
+ const plugin = Plugin.fileOutput.html({
16
+ entry: {name, entryPath, htmlPath},
17
+ });
18
+ htmlPlugins.push(plugin);
19
+ }
20
+ }
21
+
22
+ return htmlPlugins;
23
+ }
24
+ }
@@ -0,0 +1,31 @@
1
+ import MiniCssExtractPlugin from "mini-css-extract-plugin";
2
+ import CssMinimizerWebpackPlugin from "css-minimizer-webpack-plugin";
3
+ import type webpack from "webpack";
4
+ import {WebpackConfigSerializationUtil} from "../WebpackConfigSerializationUtil";
5
+
6
+ interface ExtractCssPluginOptions {
7
+ enableProfiling: boolean;
8
+ }
9
+
10
+ /**
11
+ * Applies CssNano to minimize stylesheets
12
+ * after bundles/chunks are built.
13
+ */
14
+ export function cssMinimizerPlugin(): webpack.WebpackPluginInstance {
15
+ return WebpackConfigSerializationUtil.serializablePlugin("CssMinimizerWebpackPlugin", CssMinimizerWebpackPlugin);
16
+ }
17
+
18
+ /**
19
+ * Extract output of css transformation pipeline to standalone css files.
20
+ * Must be used with `MiniCssExtractPlugin.loader`, which is included with
21
+ * `Rule.stylesheet({minimize: true})`.
22
+ */
23
+ export function miniCssExtractPlugin({enableProfiling}: ExtractCssPluginOptions): webpack.WebpackPluginInstance {
24
+ return WebpackConfigSerializationUtil.serializablePlugin("MiniCssExtractPlugin", MiniCssExtractPlugin, {
25
+ filename: enableProfiling ? "static/css/[name].[contenthash:8].css" : "static/css/[contenthash:8].css",
26
+ // order of css output depends on the order of imports in js,
27
+ // unless all imports in js are sorted (e.g. by alphabetical order),
28
+ // this flag must be set to true to avoid error
29
+ ignoreOrder: true,
30
+ });
31
+ }
@@ -0,0 +1,47 @@
1
+ import HTMLWebpackPlugin from "html-webpack-plugin";
2
+ import {ScriptTagCrossOriginPlugin} from "./script-tag-crossorigin-plugin";
3
+ import type webpack from "webpack";
4
+ import type {HTMLEntryDescriptor} from "../../type";
5
+ import {WebpackConfigSerializationUtil} from "../WebpackConfigSerializationUtil";
6
+
7
+ interface HTMLPluginOptions {
8
+ entry: HTMLEntryDescriptor;
9
+ }
10
+
11
+ /**
12
+ * Creates a html file from a template with <script> and <link> injected
13
+ * with the respective hashed output filenames.
14
+ */
15
+ export function htmlPlugin({entry}: HTMLPluginOptions): webpack.WebpackPluginInstance {
16
+ return WebpackConfigSerializationUtil.serializablePlugin("HTMLWebpackPlugin", HTMLWebpackPlugin, {
17
+ template: entry.htmlPath,
18
+ filename: `${entry.name}.html`,
19
+ chunks: [entry.name],
20
+ minify: {
21
+ collapseBooleanAttributes: true,
22
+ collapseInlineTagWhitespace: true,
23
+ collapseWhitespace: true,
24
+ includeAutoGeneratedTags: false,
25
+ keepClosingSlash: true,
26
+ minifyCSS: true,
27
+ minifyJS: true,
28
+ minifyURLs: true,
29
+ removeAttributeQuotes: true,
30
+ removeComments: true,
31
+ removeEmptyAttributes: true,
32
+ removeRedundantAttributes: true,
33
+ removeScriptTypeAttributes: true,
34
+ removeStyleLinkTypeAttributes: true,
35
+ removeTagWhitespace: true,
36
+ useShortDoctype: true,
37
+ },
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Adds attributes to `<script>` tag inside html file generated by
43
+ * HTMLWebpackPlugin. Used to add `crossorigin="anonymous"`.
44
+ */
45
+ export function scriptTagCrossOriginPlugin(): webpack.WebpackPluginInstance {
46
+ return WebpackConfigSerializationUtil.serializablePlugin("ScriptTagCrossOriginPlugin", ScriptTagCrossOriginPlugin);
47
+ }
@@ -0,0 +1,33 @@
1
+ import {cssMinimizerPlugin, miniCssExtractPlugin} from "./css.plugin";
2
+ import {scriptTagCrossOriginPlugin, htmlPlugin} from "./html.plugin";
3
+ import {ignoreMomentLocalePlugin} from "./moment.plugin";
4
+ import {reactRefreshPlugin, terserPlugin} from "./ts.plugin";
5
+ import {webpackDefinePlugin, webpackProgressPlugin} from "./webpack.plugin";
6
+
7
+ /**
8
+ * Static factories to create \`webpack.config#plugins\` items.
9
+ *
10
+ * Plugins with similar functionality are grouped under a js object (as a namespace).
11
+ */
12
+ export class Plugin {
13
+ static readonly scriptTagCrossOriginPlugin = scriptTagCrossOriginPlugin;
14
+
15
+ static readonly ignoreMomentLocale = ignoreMomentLocalePlugin;
16
+
17
+ static readonly reactRefresh = reactRefreshPlugin;
18
+
19
+ static readonly fileOutput = {
20
+ html: htmlPlugin,
21
+ miniCssExtract: miniCssExtractPlugin,
22
+ };
23
+
24
+ static readonly minimizer = {
25
+ terser: terserPlugin,
26
+ css: cssMinimizerPlugin,
27
+ };
28
+
29
+ static readonly webpack = {
30
+ progress: webpackProgressPlugin,
31
+ define: webpackDefinePlugin,
32
+ };
33
+ }
@@ -1,11 +1,6 @@
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.ignoreMomentLocalePlugin = void 0;
7
- const webpack_1 = __importDefault(require("webpack"));
8
- const WebpackConfigSerializationUtil_1 = require("../WebpackConfigSerializationUtil");
1
+ import webpack from "webpack";
2
+ import {WebpackConfigSerializationUtil} from "../WebpackConfigSerializationUtil";
3
+
9
4
  /**
10
5
  * Prevents moment locales from being bundled by importing moment
11
6
  * (moment by default imports all locales)
@@ -14,8 +9,8 @@ const WebpackConfigSerializationUtil_1 = require("../WebpackConfigSerializationU
14
9
  * To include a locale, it must be explicitly imported
15
10
  * (preferably at the entry file).
16
11
  */
17
- function ignoreMomentLocalePlugin() {
18
- return WebpackConfigSerializationUtil_1.WebpackConfigSerializationUtil.serializablePlugin("webpack.IgnorePlugin", webpack_1.default.IgnorePlugin, {
12
+ export function ignoreMomentLocalePlugin(): webpack.WebpackPluginInstance {
13
+ return WebpackConfigSerializationUtil.serializablePlugin("webpack.IgnorePlugin", webpack.IgnorePlugin, {
19
14
  // check dependency-request against the provided regex,
20
15
  // and exclude resource from final bundle if matched;
21
16
  // e.g. `/^\.\/locale$/` matches the dependency-request `require("./locale/" + name)`
@@ -25,5 +20,3 @@ function ignoreMomentLocalePlugin() {
25
20
  contextRegExp: /moment$/,
26
21
  });
27
22
  }
28
- exports.ignoreMomentLocalePlugin = ignoreMomentLocalePlugin;
29
- //# sourceMappingURL=moment.plugin.js.map
@@ -0,0 +1,22 @@
1
+ import HtmlWebpackPlugin from "html-webpack-plugin";
2
+ import type webpack from "webpack";
3
+
4
+ const PLUGIN_NAME = "ScriptTagCrossOriginPlugin";
5
+
6
+ // This plugin adds crossorigin="anonymous" to html-webpack-plugin generated <script> tags, only work with html-webpack-plugin@4.0.0+
7
+ export class ScriptTagCrossOriginPlugin implements webpack.WebpackPluginInstance {
8
+ apply(compiler: webpack.Compiler): void {
9
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
10
+ const hook = HtmlWebpackPlugin.getHooks(compilation).alterAssetTags;
11
+ hook.tap(PLUGIN_NAME, result => {
12
+ const {assetTags} = result;
13
+ for (const scriptTag of assetTags.scripts) {
14
+ if (scriptTag.attributes?.src && /.js$/.test(scriptTag.attributes.src.toString())) {
15
+ scriptTag.attributes.crossorigin = "anonymous";
16
+ }
17
+ }
18
+ return result;
19
+ });
20
+ });
21
+ }
22
+ }
@@ -0,0 +1,29 @@
1
+ import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
2
+ import TerserWebpackPlugin from "terser-webpack-plugin";
3
+ import type webpack from "webpack";
4
+ import {WebpackConfigSerializationUtil} from "../WebpackConfigSerializationUtil";
5
+
6
+ interface TerserPluginOptions {
7
+ sourceMap: boolean;
8
+ }
9
+
10
+ /**
11
+ * Applies Terser to minimize javascript
12
+ * after bundles/chunks are built.
13
+ */
14
+ export function terserPlugin({sourceMap}: TerserPluginOptions): webpack.WebpackPluginInstance {
15
+ return WebpackConfigSerializationUtil.serializablePlugin("TerserWebpackPlugin", TerserWebpackPlugin, {
16
+ terserOptions: {
17
+ sourceMap,
18
+ },
19
+ });
20
+ }
21
+
22
+ /**
23
+ * Adds react fast refresh functionality.
24
+ * Requires babel plugin "react-refresh/babel".
25
+ * Should not be used in production.
26
+ */
27
+ export function reactRefreshPlugin(): webpack.WebpackPluginInstance {
28
+ return WebpackConfigSerializationUtil.serializablePlugin("ReactRefreshPlugin", ReactRefreshWebpackPlugin);
29
+ }
@@ -0,0 +1,21 @@
1
+ import webpack from "webpack";
2
+ import {WebpackConfigSerializationUtil} from "../WebpackConfigSerializationUtil";
3
+
4
+ interface WebpackProgressPluginOptions {
5
+ enableProfiling: boolean;
6
+ }
7
+
8
+ /**
9
+ * Reports progress during compilation.
10
+ * Basically the same behavior as running webpack-cli with:
11
+ * `$ webpack --progress`
12
+ */
13
+ export function webpackProgressPlugin({enableProfiling}: WebpackProgressPluginOptions): webpack.WebpackPluginInstance {
14
+ return WebpackConfigSerializationUtil.serializablePlugin("webpack.ProgressPlugin", webpack.ProgressPlugin, {
15
+ profile: enableProfiling,
16
+ });
17
+ }
18
+
19
+ export function webpackDefinePlugin(map: {[key: string]: string}): webpack.WebpackPluginInstance {
20
+ return WebpackConfigSerializationUtil.serializablePlugin("webpack.DefinePlugin", webpack.DefinePlugin, map);
21
+ }
@@ -1,26 +1,20 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RegExpUtil = void 0;
4
- class RegExpUtil {
5
- static fileExtension(...extensions) {
6
- const escapedExtensions = [];
1
+ export class RegExpUtil {
2
+ static fileExtension(...extensions: [string, ...string[]]): RegExp {
3
+ const escapedExtensions: string[] = [];
7
4
  for (const ext of extensions) {
8
5
  RegExpUtil.validateFileExtension(ext);
9
- escapedExtensions.push(ext.replace(/\./g, String.raw `\.`));
6
+ escapedExtensions.push(ext.replace(/\./g, String.raw`\.`));
10
7
  }
11
8
  return new RegExp(`(${escapedExtensions.join("|")})$`);
12
9
  }
13
- static validateFileExtension(ext) {
10
+
11
+ private static validateFileExtension(ext: string): void {
14
12
  if (ext.trim() === "") {
15
13
  throw new Error("Extension cannot be empty.");
16
- }
17
- else if (/\s/.test(ext)) {
14
+ } else if (/\s/.test(ext)) {
18
15
  throw new Error(`Extension cannot contain whitespace, received: "${ext}".`);
19
- }
20
- else if (!/^(\.[a-z0-9]+)+$/.test(ext)) {
16
+ } else if (!/^(\.[a-z0-9]+)+$/.test(ext)) {
21
17
  throw new Error(`Extension should begin with dot, and contains lowercase letters and numbers, received: "${ext}".`);
22
18
  }
23
19
  }
24
20
  }
25
- exports.RegExpUtil = RegExpUtil;
26
- //# sourceMappingURL=RegExpUtil.js.map
@@ -1,5 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ import type * as babel from "@babel/core";
2
+
3
+ interface State extends Pick<babel.PluginPass, "file" | "key" | "opts" | "cwd" | "filename"> {
4
+ hasInjectedDeclineWebpackHMRNode: boolean;
5
+ }
6
+
3
7
  /**
4
8
  * Injects `if (module.hot) module.hot.decline()` code snippet in files that contains "core-fe" Module classes.
5
9
  *
@@ -7,39 +11,68 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
11
  * otherwise react loses refrence of the MainComponent created by `ModuleProxy` in "core-fe"
8
12
  * and throws a runtime error during development (which is bad for developer experience).
9
13
  */
10
- function default_1({ types: t }) {
14
+ export default function ({types: t}: typeof babel): babel.PluginObj<State> {
11
15
  return {
12
16
  visitor: {
13
17
  ImportDeclaration(path, state) {
14
18
  if (state.hasInjectedDeclineWebpackHMRNode) {
15
19
  return;
16
20
  }
17
- const { node: { source: { value: importSource }, specifiers: importSpecifiers, }, } = path;
21
+
22
+ const {
23
+ node: {
24
+ source: {value: importSource},
25
+ specifiers: importSpecifiers,
26
+ },
27
+ } = path;
28
+
18
29
  if (importSource !== "core-fe") {
19
30
  return;
20
31
  }
32
+
21
33
  if (!hasImportSpecifierOfIdentifierModule(t, importSpecifiers)) {
22
34
  return;
23
35
  }
36
+
24
37
  // We now know the TS/JS file has included `Module`, inject the code snippet
25
- const programPath = path.findParent(parentPath => t.isProgram(parentPath.node));
38
+ const programPath = path.findParent(parentPath => t.isProgram(parentPath.node))! as babel.NodePath<babel.types.Program>;
39
+
26
40
  // prettier-ignore
27
- const declineWebpackHMRNode = t.ifStatement(t.memberExpression(t.identifier("module"), t.identifier("hot")), t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier("module"), t.identifier("hot")), t.identifier("decline")), [])));
41
+ const declineWebpackHMRNode = t.ifStatement(
42
+ t.memberExpression(
43
+ t.identifier("module"),
44
+ t.identifier("hot")
45
+ ),
46
+ t.expressionStatement(
47
+ t.callExpression(
48
+ t.memberExpression(
49
+ t.memberExpression(
50
+ t.identifier("module"),
51
+ t.identifier("hot"),
52
+ ),
53
+ t.identifier("decline"),
54
+ ),
55
+ [],
56
+ ),
57
+ ),
58
+ );
59
+
28
60
  // Append `if (module.hot) module.hot.decline()` to end of program body
29
61
  programPath.pushContainer("body", declineWebpackHMRNode);
62
+
30
63
  // We only need to inject the code snippet once per file, mark as injected
31
64
  state.hasInjectedDeclineWebpackHMRNode = true;
32
65
  },
33
66
  },
34
67
  };
35
68
  }
36
- exports.default = default_1;
69
+
37
70
  /**
38
71
  * @param t `babel.types`
39
72
  * @param importSpecifiers The "specifier" property of a `babel.types.ImportDeclaration` node
40
73
  * @returns true if the import declaration includes the identifier `Module`
41
74
  */
42
- function hasImportSpecifierOfIdentifierModule(t, importSpecifiers) {
75
+ function hasImportSpecifierOfIdentifierModule(t: typeof babel.types, importSpecifiers: babel.types.ImportDeclaration["specifiers"]): boolean {
43
76
  const specifier = importSpecifiers.find(specifier => {
44
77
  // Check if it is one of:
45
78
  // -> `import { <IMPORT_SPECIFIER_NODE> } from "core-fe";`
@@ -48,6 +81,7 @@ function hasImportSpecifierOfIdentifierModule(t, importSpecifiers) {
48
81
  const importedSpecifier = specifier.imported;
49
82
  return t.isIdentifier(importedSpecifier) && importedSpecifier.name === "Module";
50
83
  }
84
+
51
85
  // Check if it is:
52
86
  // -> `import * as <IMPORT_NAMESPACE_SPECIFIER_NODE> from "core-fe";`
53
87
  if (t.isImportNamespaceSpecifier(specifier)) {
@@ -55,8 +89,8 @@ function hasImportSpecifierOfIdentifierModule(t, importSpecifiers) {
55
89
  // Maybe enforce "core-fe" should not be imported with a namespace with an ESLint rule?
56
90
  return true;
57
91
  }
92
+
58
93
  return false;
59
94
  });
60
95
  return specifier !== undefined;
61
96
  }
62
- //# sourceMappingURL=core-fe-hmr-babel-plugin.js.map
@@ -1,7 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.imageRule = void 0;
4
- const RegExpUtil_1 = require("./RegExpUtil");
1
+ import type webpack from "webpack";
2
+ import {RegExpUtil} from "./RegExpUtil";
3
+
5
4
  /**
6
5
  * Handles dependency requests to image assets (".png", ".jpeg", ".jpg", ".gif", ".svg")
7
6
  * by inlining as images as DataURL,
@@ -9,9 +8,9 @@ const RegExpUtil_1 = require("./RegExpUtil");
9
8
  *
10
9
  * @see https://webpack.js.org/guides/asset-modules/
11
10
  */
12
- function imageRule() {
11
+ export function imageRule(): webpack.RuleSetRule {
13
12
  return {
14
- test: RegExpUtil_1.RegExpUtil.fileExtension(".png", ".jpeg", ".jpg", ".gif", ".svg"),
13
+ test: RegExpUtil.fileExtension(".png", ".jpeg", ".jpg", ".gif", ".svg"),
15
14
  type: "asset",
16
15
  generator: {
17
16
  filename: "static/img/[name].[hash:8][ext][query]",
@@ -23,5 +22,3 @@ function imageRule() {
23
22
  },
24
23
  };
25
24
  }
26
- exports.imageRule = imageRule;
27
- //# sourceMappingURL=image.rule.js.map
@@ -0,0 +1,17 @@
1
+ import {imageRule} from "./image.rule";
2
+ import {otherRule} from "./other.rule";
3
+ import {stylesheetRule} from "./stylesheet.rule";
4
+ import {tsRule} from "./ts.rule";
5
+
6
+ /**
7
+ * Static factories to create `webpack.config#modules.rules` items.
8
+ */
9
+ export class Rule {
10
+ static readonly image = imageRule;
11
+
12
+ static readonly other = otherRule;
13
+
14
+ static readonly ts = tsRule;
15
+
16
+ static readonly stylesheet = stylesheetRule;
17
+ }
@@ -0,0 +1,23 @@
1
+ import type webpack from "webpack";
2
+ import {Constant} from "../../Constant";
3
+ import {RegExpUtil} from "./RegExpUtil";
4
+
5
+ interface OtherRuleDeps {
6
+ extraExtensionsForOtherRule: string[];
7
+ }
8
+
9
+ /**
10
+ * Handles dependency requests to file assets
11
+ * by emitting as separate files.
12
+ *
13
+ * @see https://webpack.js.org/guides/asset-modules/
14
+ */
15
+ export function otherRule({extraExtensionsForOtherRule}: OtherRuleDeps): webpack.RuleSetRule {
16
+ return {
17
+ test: RegExpUtil.fileExtension(".ico", ...Constant.mediaExtensions, ...Constant.fontExtensions, ...extraExtensionsForOtherRule),
18
+ type: "asset",
19
+ generator: {
20
+ filename: "static/other/[name].[hash:8][ext][query]",
21
+ },
22
+ };
23
+ }