@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
@@ -0,0 +1,35 @@
1
+ import type {Config} from "@jest/types";
2
+
3
+ const config: Config.InitialOptionsWithRootDir = {
4
+ // Stop running tests after `n` failures
5
+ bail: 1,
6
+
7
+ // A preset that is used as a base for Jest's configuration
8
+ preset: "ts-jest",
9
+
10
+ // A set of global variables that need to be available in all test environments
11
+ globals: {
12
+ "ts-jest": {
13
+ tsconfig: "<rootDir>/config/tsconfig.test.json",
14
+ },
15
+ },
16
+
17
+ // The root directory that Jest should scan for tests and modules within
18
+ rootDir: "../",
19
+
20
+ // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
21
+ testPathIgnorePatterns: ["/node_modules/", "<rootDir>/build/"],
22
+
23
+ // A map from regular expressions to paths to transformers
24
+ transform: {
25
+ [String.raw`\.(ts|tsx)$`]: "ts-jest",
26
+ },
27
+
28
+ // Indicates whether each individual test should be reported during the run
29
+ verbose: true,
30
+
31
+ // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
32
+ watchPathIgnorePatterns: ["<rootDir>/build/", "dist/"],
33
+ };
34
+
35
+ export default config;
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "lib": ["ES2020"],
5
+ "module": "CommonJS",
6
+ "target": "ES2015",
7
+ "noEmit": true
8
+ },
9
+ "include": ["../config", "../script/"]
10
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "lib": ["ES2020"],
5
+ "module": "CommonJS",
6
+ "target": "ES2015",
7
+ "rootDir": "../",
8
+ "outDir": "../build/",
9
+ "isolatedModules": true
10
+ },
11
+ "include": ["../src/"]
12
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "lib": ["ES2020"],
5
+ "module": "CommonJS",
6
+ "target": "ES2015",
7
+ "rootDir": "../",
8
+ "isolatedModules": true
9
+ },
10
+ "include": ["../test/"]
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinnacle0/webpack-util",
3
- "version": "0.3.25",
3
+ "version": "0.3.26",
4
4
  "license": "MIT",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -12,7 +12,7 @@
12
12
  "dependencies": {
13
13
  "@babel/core": "7.18.6",
14
14
  "@pmmmwh/react-refresh-webpack-plugin": "0.5.7",
15
- "@swc/core": "1.2.209",
15
+ "@swc/core": "1.2.210",
16
16
  "autoprefixer": "10.4.7",
17
17
  "babel-loader": "8.2.5",
18
18
  "css-loader": "6.7.1",
@@ -0,0 +1,65 @@
1
+ import {PrettierUtil, TaskRunner, Utility} from "@pinnacle0/devtool-util";
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ const FilePath = {
6
+ config: path.join(__dirname, "../config"),
7
+ build: path.join(__dirname, "../build"),
8
+ script: path.join(__dirname, "../script"),
9
+ src: path.join(__dirname, "../src"),
10
+
11
+ jestConfig: path.join(__dirname, "../config/jest.config.ts"),
12
+ tsConfigForSrc: path.join(__dirname, "../config/tsconfig.src.json"),
13
+ projectPackageJSON: path.join(__dirname, "../package.json"),
14
+ projectReadMe: path.join(__dirname, "../README.md"),
15
+ projectLicense: path.join(__dirname, "../LICENSE.md"),
16
+ buildPackageJSON: path.join(__dirname, "../build/package.json"),
17
+ buildReadMe: path.join(__dirname, "../build/README.md"),
18
+ buildLicense: path.join(__dirname, "../build/LICENSE.md"),
19
+ };
20
+
21
+ new TaskRunner("build").execute([
22
+ {
23
+ name: "code style check",
24
+ skipInFastMode: true,
25
+ execute: () => {
26
+ PrettierUtil.check(FilePath.config);
27
+ PrettierUtil.check(FilePath.script);
28
+ PrettierUtil.check(FilePath.src);
29
+ },
30
+ },
31
+ {
32
+ name: "lint",
33
+ skipInFastMode: true,
34
+ execute: () => {
35
+ Utility.runCommand("eslint", ["--ext=.js,.jsx,.ts,.tsx", FilePath.src]);
36
+ },
37
+ },
38
+ {
39
+ name: "test",
40
+ skipInFastMode: true,
41
+ execute: () => {
42
+ Utility.runCommand("jest", ["--config", FilePath.jestConfig, "--bail"]);
43
+ },
44
+ },
45
+ {
46
+ name: "prepare build directory",
47
+ execute: () => {
48
+ Utility.prepareEmptyDirectory(FilePath.build);
49
+ },
50
+ },
51
+ {
52
+ name: "compile with tsc",
53
+ execute: () => {
54
+ Utility.runCommand("tsc", ["--project", FilePath.tsConfigForSrc]);
55
+ },
56
+ },
57
+ {
58
+ name: "copy package.json, markdown files",
59
+ execute: () => {
60
+ fs.copyFileSync(FilePath.projectPackageJSON, FilePath.buildPackageJSON);
61
+ fs.copyFileSync(FilePath.projectReadMe, FilePath.buildReadMe);
62
+ fs.copyFileSync(FilePath.projectLicense, FilePath.buildLicense);
63
+ },
64
+ },
65
+ ]);
@@ -0,0 +1,7 @@
1
+ import {PrettierUtil} from "@pinnacle0/devtool-util";
2
+ import path from "path";
3
+
4
+ PrettierUtil.format(path.join(__dirname, "../config"));
5
+ PrettierUtil.format(path.join(__dirname, "../script"));
6
+ PrettierUtil.format(path.join(__dirname, "../src"));
7
+ PrettierUtil.format(path.join(__dirname, "../test"));
@@ -0,0 +1,35 @@
1
+ import {Utility} from "@pinnacle0/devtool-util";
2
+ import fs from "fs";
3
+
4
+ /**
5
+ * `canadyarn` is a mono-repo package version checker for single version installation, developed by Pinnacle team.
6
+ *
7
+ * Ref: https://www.npmjs.com/package/canadyarn
8
+ */
9
+ export class CanadyarnRunner {
10
+ private readonly rootDirectory: string;
11
+ private readonly logger = Utility.createConsoleLogger("CanadyarnRunner");
12
+
13
+ constructor({rootDirectory}: {rootDirectory: string}) {
14
+ this.rootDirectory = rootDirectory;
15
+ }
16
+
17
+ run() {
18
+ this.runCanadyarn();
19
+ }
20
+
21
+ private runCanadyarn() {
22
+ const packageJSONPath = this.rootDirectory + "/package.json";
23
+
24
+ if (fs.existsSync(packageJSONPath) && fs.statSync(packageJSONPath).isFile()) {
25
+ const packageJSONContents: Record<string, any> = JSON.parse(fs.readFileSync(packageJSONPath, {encoding: "utf8"}));
26
+
27
+ if (packageJSONContents?.scripts?.canadyarn) {
28
+ this.logger.task("Running `canadyarn` at " + this.rootDirectory);
29
+ Utility.runCommand("yarn", ["--cwd", this.rootDirectory, "canadyarn"]);
30
+ }
31
+ } else {
32
+ throw new Error(`Cannot load root directory [${this.rootDirectory}] package.json`);
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,44 @@
1
+ import {PrettierUtil, Utility} from "@pinnacle0/devtool-util";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import type {InternalCheckerOptions} from "./type";
5
+
6
+ export class CodeStyleChecker {
7
+ private readonly checkableSrcDirectories: [string, ...string[]];
8
+ private readonly logger = Utility.createConsoleLogger("CodeStyleChecker");
9
+
10
+ constructor({projectDirectory, extraCheckDirectories = []}: InternalCheckerOptions) {
11
+ this.checkableSrcDirectories = [path.join(projectDirectory, "src")];
12
+ for (const directory of extraCheckDirectories) {
13
+ const others = ["test", "script"].map(folder => path.join(directory, folder)).filter(path => fs.existsSync(path));
14
+ this.checkableSrcDirectories.push(path.join(directory, "src"), ...others);
15
+ }
16
+ }
17
+
18
+ run() {
19
+ this.checkPrettier();
20
+ this.checkESLint();
21
+ this.checkStylelint();
22
+ }
23
+
24
+ private checkPrettier() {
25
+ this.logger.task("Checking Prettier");
26
+ for (const srcDirectory of this.checkableSrcDirectories) {
27
+ PrettierUtil.check(srcDirectory);
28
+ }
29
+ }
30
+
31
+ private checkESLint() {
32
+ this.logger.task("Checking ESLint");
33
+ for (const srcDirectory of this.checkableSrcDirectories) {
34
+ Utility.runCommand("eslint", ["--no-error-on-unmatched-pattern", "--max-warnings=1", "--ext=.js,.jsx,.ts,.tsx", srcDirectory]);
35
+ }
36
+ }
37
+
38
+ private checkStylelint() {
39
+ this.logger.task("Checking Stylelint");
40
+ for (const srcDirectory of this.checkableSrcDirectories) {
41
+ Utility.runCommand("stylelint", ["--allow-empty-input", "--max-warnings=1", path.join(srcDirectory, "**/*.{css,less}")]);
42
+ }
43
+ }
44
+ }
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Constant = void 0;
4
- exports.Constant = Object.freeze({
1
+ export const Constant = Object.freeze({
5
2
  maxEntryPointKiloByte: 1500,
6
3
  maxAssetKiloByte: 4000,
7
4
  /**
@@ -22,4 +19,3 @@ exports.Constant = Object.freeze({
22
19
  */
23
20
  mainEntryFilenames: ["index.tsx", "index.ts", "index.jsx", "index.js", "index.less", "index.css"],
24
21
  });
25
- //# sourceMappingURL=Constant.js.map
@@ -0,0 +1,24 @@
1
+ import yargs from "yargs";
2
+
3
+ function currentEnv(): string | null {
4
+ return (yargs.parseSync().env as string) || null;
5
+ }
6
+
7
+ function profilingEnabled(): boolean {
8
+ return Boolean(yargs.parseSync().profile);
9
+ }
10
+
11
+ function isFastMode(): boolean {
12
+ return yargs.parseSync().mode === "fast";
13
+ }
14
+
15
+ function verbose(): boolean {
16
+ return Boolean(yargs.parseSync().verbose);
17
+ }
18
+
19
+ export const CoreUtil = Object.freeze({
20
+ currentEnv,
21
+ profilingEnabled,
22
+ isFastMode,
23
+ verbose,
24
+ });
@@ -0,0 +1,119 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import {Constant} from "./Constant";
4
+ import type {InternalCheckerOptions} from "./type";
5
+
6
+ export class ProjectStructureChecker {
7
+ private readonly projectDirectory: string;
8
+ private readonly extraCheckDirectories: string[];
9
+ private readonly packageJSONPath: string;
10
+ private readonly tsConfigPath: string;
11
+
12
+ constructor(private readonly options: InternalCheckerOptions) {
13
+ this.projectDirectory = options.projectDirectory;
14
+ this.extraCheckDirectories = options.extraCheckDirectories ?? [];
15
+ this.packageJSONPath = path.join(options.projectDirectory, "package.json");
16
+ this.tsConfigPath = path.join(options.projectDirectory, "tsconfig.json");
17
+ }
18
+
19
+ run() {
20
+ this.checkMainProjectDirectory();
21
+ this.checkMainProjectSrcDirectory();
22
+ this.checkExtraDirectories();
23
+ this.checkPackageJSON();
24
+ this.checkTSConfig();
25
+
26
+ this.checkPrettierInstallation();
27
+ this.checkESLintInstallation();
28
+ this.checkStyleLintInstallation();
29
+ }
30
+
31
+ private checkMainProjectDirectory() {
32
+ if (!(fs.existsSync(this.projectDirectory) && fs.statSync(this.projectDirectory).isDirectory())) {
33
+ throw new Error(`Cannot check project directory at "${this.projectDirectory}" because it is not a folder.`);
34
+ }
35
+
36
+ const mainProjectStaticDirectory = path.join(this.projectDirectory, "static");
37
+ if (!(fs.existsSync(mainProjectStaticDirectory) && fs.statSync(mainProjectStaticDirectory).isDirectory())) {
38
+ throw new Error(`Cannot find "static" directory in project at "${this.projectDirectory}"`);
39
+ }
40
+ }
41
+
42
+ private checkMainProjectSrcDirectory() {
43
+ const mainProjectSrcDirectory = path.join(this.projectDirectory, "src");
44
+ if (!(fs.existsSync(mainProjectSrcDirectory) && fs.statSync(mainProjectSrcDirectory).isDirectory())) {
45
+ throw new Error(`Cannot find "src" folder inside directory at "${this.projectDirectory}".`);
46
+ }
47
+
48
+ let isMainEntryFound = false;
49
+ Constant.mainEntryFilenames
50
+ .map(entryName => path.join(mainProjectSrcDirectory, entryName))
51
+ .forEach(entryPath => {
52
+ if (fs.existsSync(entryPath) && fs.statSync(entryPath).isFile()) {
53
+ isMainEntryFound = true;
54
+ }
55
+ });
56
+ if (!isMainEntryFound) {
57
+ throw new Error(`Cannot find main entry file in src/ at "${mainProjectSrcDirectory}"; checked: ${Constant.mainEntryFilenames.map(_ => `"${_}"`).join(" / ")}.`);
58
+ }
59
+ }
60
+
61
+ private checkExtraDirectories() {
62
+ for (const extraCheckDirectory of this.extraCheckDirectories) {
63
+ if (!(fs.existsSync(extraCheckDirectory) && fs.statSync(extraCheckDirectory).isDirectory())) {
64
+ throw new Error(`Cannot check extra directory at "${extraCheckDirectory}" because it is not a folder.`);
65
+ }
66
+ }
67
+ }
68
+
69
+ private checkPackageJSON() {
70
+ if (!(fs.existsSync(this.packageJSONPath) && fs.statSync(this.packageJSONPath).isFile())) {
71
+ throw new Error(`Cannot find package.json at "${this.packageJSONPath}".`);
72
+ }
73
+ const packageJSONContents: Record<string, any> = JSON.parse(fs.readFileSync(this.packageJSONPath, {encoding: "utf8"}));
74
+ for (const [depName, depVersion] of Object.entries<string>(packageJSONContents.dependencies || {})) {
75
+ if (!/^\d/.test(depVersion)) {
76
+ throw new Error(`Dependency "${depName}" must be an exact version, but found "${depVersion}" in package.json at "${this.packageJSONPath}".`);
77
+ }
78
+ }
79
+ for (const [depName, depVersion] of Object.entries<string>(packageJSONContents.devDependencies || {})) {
80
+ if (!/^\d/.test(depVersion)) {
81
+ throw new Error(`Dependency "${depName}" must be an exact version, but found "${depVersion}" in package.json at "${this.packageJSONPath}".`);
82
+ }
83
+ }
84
+ }
85
+
86
+ private checkTSConfig() {
87
+ const mainProjectSrcDirectory = path.join(this.projectDirectory, "src");
88
+ // Checking the first-level of src/* is enough here
89
+ const hasTSFiles = fs.readdirSync(mainProjectSrcDirectory).some(fileName => fileName.endsWith(".ts") || fileName.endsWith(".tsx"));
90
+ const hasTSConfigFile = fs.existsSync(this.tsConfigPath) && fs.statSync(this.tsConfigPath).isFile();
91
+ if (hasTSFiles && !hasTSConfigFile) {
92
+ throw new Error(`Cannot find tsconfig.json at "${this.tsConfigPath}".`);
93
+ }
94
+ }
95
+
96
+ private checkPrettierInstallation() {
97
+ try {
98
+ require("prettier");
99
+ } catch {
100
+ throw new Error(`Cannot load prettier module (requiring from "webpack-util"), make sure prettier is installed.`);
101
+ }
102
+ }
103
+
104
+ private checkESLintInstallation() {
105
+ try {
106
+ require("eslint");
107
+ } catch {
108
+ throw new Error(`Cannot load eslint module (requiring from "webpack-util"), make sure eslint is installed.`);
109
+ }
110
+ }
111
+
112
+ private checkStyleLintInstallation() {
113
+ try {
114
+ require("stylelint");
115
+ } catch {
116
+ throw new Error(`Cannot load stylelint module (requiring from "webpack-util"), make sure stylelint is installed.`);
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,28 @@
1
+ import {Utility} from "@pinnacle0/devtool-util";
2
+ import type {InternalCheckerOptions} from "./type";
3
+ import fs from "fs";
4
+
5
+ export class TestRunner {
6
+ private readonly directories: [string, ...string[]];
7
+ private readonly logger = Utility.createConsoleLogger("TestRunner");
8
+
9
+ constructor({projectDirectory, extraCheckDirectories = []}: InternalCheckerOptions) {
10
+ this.directories = [projectDirectory, ...extraCheckDirectories];
11
+ }
12
+
13
+ run() {
14
+ this.directories.forEach(dir => this.runTestScript(dir));
15
+ }
16
+
17
+ private runTestScript(directory: string) {
18
+ const packageJSONPath = directory + "/package.json";
19
+ if (fs.existsSync(packageJSONPath) && fs.statSync(packageJSONPath).isFile()) {
20
+ const packageJSONContents: Record<string, any> = JSON.parse(fs.readFileSync(packageJSONPath, {encoding: "utf8"}));
21
+
22
+ if (packageJSONContents?.scripts?.test) {
23
+ this.logger.task("Running `yarn test` at " + directory);
24
+ Utility.runCommand("yarn", ["--cwd", directory, "test"]);
25
+ }
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,29 @@
1
+ import {Utility} from "@pinnacle0/devtool-util";
2
+ import path from "path";
3
+ import type {InternalCheckerOptions} from "./type";
4
+
5
+ /**
6
+ * Check typescript type for both projectDirectory src, extraCheckDirectories src using their own tsconfig inside their directory
7
+ */
8
+ export class TypescriptTypeChecker {
9
+ private readonly logger = Utility.createConsoleLogger("TypescriptTypeChecker");
10
+ private tsconfigPaths: string[] = [];
11
+
12
+ constructor({projectDirectory, extraCheckDirectories}: InternalCheckerOptions) {
13
+ const checkableDirectories = [projectDirectory, ...(extraCheckDirectories ?? [])];
14
+ for (const directory of checkableDirectories) {
15
+ this.tsconfigPaths.push(path.join(directory, "tsconfig.json"));
16
+ }
17
+ }
18
+
19
+ run() {
20
+ this.checkTypeScriptTyping();
21
+ }
22
+
23
+ private checkTypeScriptTyping() {
24
+ this.logger.task("Checking TypeScript");
25
+ for (const tsconfigPath of this.tsconfigPaths) {
26
+ Utility.runCommand("tsc", ["--noEmit", "--emitDeclarationOnly", "false", "-P", tsconfigPath]);
27
+ }
28
+ }
29
+ }
@@ -1,20 +1,21 @@
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.WebpackBuilder = void 0;
7
- const devtool_util_1 = require("@pinnacle0/devtool-util");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
- const path_1 = __importDefault(require("path"));
10
- const webpack_1 = __importDefault(require("webpack"));
11
- const CoreUtil_1 = require("./CoreUtil");
12
- const WebpackConfigGenerator_1 = require("./WebpackConfigGenerator");
13
- const CanadyarnRunner_1 = require("./CanadyarnRunner");
14
- const ProjectStructureChecker_1 = require("./ProjectStructureChecker");
15
- const TypescriptTypeChecker_1 = require("./TypescriptTypeChecker");
16
- const TestRunner_1 = require("./TestRunner");
17
- const CodeStyleChecker_1 = require("./CodeStyleChecker");
1
+ import {Utility} from "@pinnacle0/devtool-util";
2
+ import fs from "fs-extra";
3
+ import path from "path";
4
+ import webpack from "webpack";
5
+ import {CoreUtil} from "./CoreUtil";
6
+ import {WebpackConfigGenerator} from "./WebpackConfigGenerator";
7
+ import {CanadyarnRunner} from "./CanadyarnRunner";
8
+ import {ProjectStructureChecker} from "./ProjectStructureChecker";
9
+ import {TypescriptTypeChecker} from "./TypescriptTypeChecker";
10
+ import {TestRunner} from "./TestRunner";
11
+ import {CodeStyleChecker} from "./CodeStyleChecker";
12
+ import type {InternalCheckerOptions} from "./type";
13
+ import type {WebpackConfigGeneratorOptions} from "./WebpackConfigGenerator";
14
+
15
+ export interface WebpackBuilderOptions extends WebpackConfigGeneratorOptions, InternalCheckerOptions {
16
+ onSuccess?: () => void;
17
+ }
18
+
18
19
  /**
19
20
  * Build the website by webpack.
20
21
  *
@@ -29,40 +30,55 @@ const CodeStyleChecker_1 = require("./CodeStyleChecker");
29
30
  *
30
31
  * Add "--mode fast" to command line, if you want to skip style and lint checks.
31
32
  */
32
- class WebpackBuilder {
33
- constructor(options) {
34
- var _a;
35
- this.logger = devtool_util_1.Utility.createConsoleLogger("WebpackBuilder");
36
- const webpackConfigGenerator = new WebpackConfigGenerator_1.WebpackConfigGenerator(options);
33
+ export class WebpackBuilder {
34
+ private readonly projectDirectory: string;
35
+ private readonly rootDirectory: string;
36
+ private readonly extraCheckDirectories: string[];
37
+ private readonly projectStaticDirectory: string;
38
+ private readonly projectProfilingJSONOutputPath: string;
39
+ private readonly outputDirectory: string;
40
+ private readonly webpackConfig: webpack.Configuration;
41
+ private readonly isFastMode: boolean;
42
+ private readonly enableProfiling: boolean;
43
+ private readonly onSuccess?: (() => void) | undefined;
44
+
45
+ private readonly logger = Utility.createConsoleLogger("WebpackBuilder");
46
+
47
+ constructor(options: WebpackBuilderOptions) {
48
+ const webpackConfigGenerator = new WebpackConfigGenerator(options);
49
+
37
50
  this.projectDirectory = options.projectDirectory;
38
51
  this.rootDirectory = options.rootDirectory ? options.rootDirectory : this.projectDirectory;
39
- this.extraCheckDirectories = (_a = options.extraCheckDirectories) !== null && _a !== void 0 ? _a : [];
40
- this.projectStaticDirectory = path_1.default.join(this.projectDirectory, "static");
41
- this.projectProfilingJSONOutputPath = path_1.default.join(this.projectDirectory, "profile.json");
42
- this.outputDirectory = path_1.default.join(this.projectDirectory, "build/dist");
43
- this.isFastMode = CoreUtil_1.CoreUtil.isFastMode();
44
- this.enableProfiling = CoreUtil_1.CoreUtil.profilingEnabled();
52
+ this.extraCheckDirectories = options.extraCheckDirectories ?? [];
53
+ this.projectStaticDirectory = path.join(this.projectDirectory, "static");
54
+ this.projectProfilingJSONOutputPath = path.join(this.projectDirectory, "profile.json");
55
+ this.outputDirectory = path.join(this.projectDirectory, "build/dist");
56
+
57
+ this.isFastMode = CoreUtil.isFastMode();
58
+ this.enableProfiling = CoreUtil.profilingEnabled();
45
59
  this.onSuccess = options.onSuccess;
60
+
46
61
  this.webpackConfig = webpackConfigGenerator.production(this.outputDirectory);
47
62
  }
63
+
48
64
  run() {
49
65
  if (!this.isFastMode) {
50
- new CanadyarnRunner_1.CanadyarnRunner({
66
+ new CanadyarnRunner({
51
67
  rootDirectory: this.rootDirectory,
52
68
  }).run();
53
- new ProjectStructureChecker_1.ProjectStructureChecker({
69
+ new ProjectStructureChecker({
54
70
  projectDirectory: this.projectDirectory,
55
71
  extraCheckDirectories: this.extraCheckDirectories,
56
72
  }).run();
57
- new TypescriptTypeChecker_1.TypescriptTypeChecker({
73
+ new TypescriptTypeChecker({
58
74
  projectDirectory: this.projectDirectory,
59
75
  extraCheckDirectories: this.extraCheckDirectories,
60
76
  }).run();
61
- new TestRunner_1.TestRunner({
77
+ new TestRunner({
62
78
  projectDirectory: this.projectDirectory,
63
79
  extraCheckDirectories: this.extraCheckDirectories,
64
80
  }).run();
65
- new CodeStyleChecker_1.CodeStyleChecker({
81
+ new CodeStyleChecker({
66
82
  projectDirectory: this.projectDirectory,
67
83
  extraCheckDirectories: this.extraCheckDirectories,
68
84
  }).run();
@@ -71,46 +87,52 @@ class WebpackBuilder {
71
87
  this.copyStatic();
72
88
  this.bundleByWebpack();
73
89
  }
74
- cleanDistFolder() {
90
+
91
+ private cleanDistFolder() {
75
92
  this.logger.task("Cleaning build dist folder");
76
- fs_extra_1.default.emptyDirSync(this.outputDirectory);
93
+ fs.emptyDirSync(this.outputDirectory);
77
94
  }
78
- copyStatic() {
95
+
96
+ private copyStatic() {
79
97
  this.logger.task("Copying static assets to build dist folder");
80
- fs_extra_1.default.copySync(this.projectStaticDirectory, this.outputDirectory, { dereference: true });
98
+ fs.copySync(this.projectStaticDirectory, this.outputDirectory, {dereference: true});
81
99
  }
82
- bundleByWebpack() {
100
+
101
+ private bundleByWebpack() {
83
102
  this.logger.task("Starting webpack");
84
- (0, webpack_1.default)(this.webpackConfig).run((error, stats) => {
103
+
104
+ webpack(this.webpackConfig).run((error?: Error | null, stats?: webpack.Stats) => {
85
105
  if (error) {
86
106
  throw error;
87
- }
88
- else if (stats) {
107
+ } else if (stats) {
89
108
  const statsJSON = stats.toJson();
90
109
  if (this.enableProfiling) {
91
110
  this.logger.task(["Generating profile for analysis", this.projectProfilingJSONOutputPath]);
92
- fs_extra_1.default.writeFileSync(this.projectProfilingJSONOutputPath, JSON.stringify(statsJSON, null, 2), { encoding: "utf8" });
111
+ fs.writeFileSync(this.projectProfilingJSONOutputPath, JSON.stringify(statsJSON, null, 2), {encoding: "utf8"});
93
112
  }
113
+
94
114
  if (stats.hasErrors() || stats.hasWarnings()) {
95
115
  this.logger.error("Webpack compiled with the following errors/warnings:");
96
116
  console.error(stats.toString("errors-warnings"));
97
117
  process.exit(1);
98
118
  }
119
+
99
120
  this.logger.info("Build successfully");
121
+
100
122
  if (this.onSuccess) {
101
123
  this.logger.info("Running onSuccess callback");
102
124
  this.onSuccess();
103
125
  }
104
- }
105
- else {
126
+ } else {
106
127
  this.logger.error("Webpack compiler `run()` returns no `error` and no `stats`, this is unexpected.");
107
128
  process.exit(1);
108
129
  }
109
130
  });
110
131
  }
111
- getRawWarningsAndErrors(info) {
112
- const warnings = [];
113
- const errors = [];
132
+
133
+ private getRawWarningsAndErrors(info: any): {warnings: any[]; errors: any[]} {
134
+ const warnings: any[] = [];
135
+ const errors: any[] = [];
114
136
  if (typeof info === "object" && info !== null) {
115
137
  if (Array.isArray(info.warnings)) {
116
138
  warnings.push(...info.warnings);
@@ -119,15 +141,13 @@ class WebpackBuilder {
119
141
  errors.push(...info.errors);
120
142
  }
121
143
  if (Array.isArray(info.children)) {
122
- info.children.forEach((_) => {
144
+ info.children.forEach((_: any) => {
123
145
  const childInfo = this.getRawWarningsAndErrors(_);
124
146
  warnings.push(...childInfo.warnings);
125
147
  errors.push(...childInfo.errors);
126
148
  });
127
149
  }
128
150
  }
129
- return { warnings, errors };
151
+ return {warnings, errors};
130
152
  }
131
153
  }
132
- exports.WebpackBuilder = WebpackBuilder;
133
- //# sourceMappingURL=WebpackBuilder.js.map