@simplysm/sd-cli 7.0.263 → 7.0.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -22
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-128x128.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-144x144.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-152x152.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-192x192.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-384x384.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-512x512.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-72x72.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/assets/icons/icon-96x96.png +0 -0
- package/{src/entry-points/file/assets → assets/client-files}/favicon.ico +0 -0
- package/dist/bin/sd-cli.mjs +44 -5
- package/dist/build-tool/SdCliCordova.mjs +3 -3
- package/dist/build-tool/SdCliIndexFileGenerator.mjs +2 -3
- package/dist/builder/SdCliClientBuilder.d.ts +2 -0
- package/dist/builder/SdCliClientBuilder.mjs +45 -12
- package/dist/builder/SdCliServerBuilder.d.ts +2 -0
- package/dist/builder/SdCliServerBuilder.mjs +27 -13
- package/dist/entry-points/SdCliPrepare.mjs +34 -34
- package/dist/entry-points/SdCliProjectGenerator.d.ts +7 -0
- package/dist/entry-points/SdCliProjectGenerator.mjs +65 -33
- package/dist/entry-points/file/base/fc_package_eslintrc.mjs +11 -11
- package/dist/entry-points/file/base/fc_package_tsconfig.d.ts +1 -0
- package/dist/entry-points/file/base/fc_package_tsconfig.mjs +3 -2
- package/dist/entry-points/file/client/fc_package_AppModule.mjs +1 -1
- package/dist/entry-points/file/client/fc_package_AppPage.mjs +2 -22
- package/dist/entry-points/file/client/fc_package_Page.d.ts +4 -0
- package/dist/entry-points/file/client/fc_package_Page.mjs +19 -0
- package/dist/entry-points/file/project/fc_project_gitignore.mjs +1 -1
- package/dist/entry-points/file/project/fc_project_readme.mjs +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/ng-tools/SdCliNgModuleGenerator.mjs +35 -36
- package/dist/packages/SdCliPackage.mjs +2 -2
- package/docs/client-add-page.md +8 -0
- package/docs/client-router.md +85 -0
- package/docs/client-sw.md +101 -0
- package/docs/conf-orm.md +81 -0
- package/docs/conf-usage.md +5 -0
- package/docs/lib-local-update.md +50 -0
- package/docs/lib-ts-paths.md +25 -0
- package/package.json +6 -6
- package/src/SdCliBuildResultError.ts +9 -9
- package/src/bin/sd-cli.ts +48 -5
- package/src/build-tool/SdCliCacheCompilerHost.ts +77 -77
- package/src/build-tool/SdCliCordova.ts +2 -2
- package/src/build-tool/SdCliGithubApi.ts +110 -110
- package/src/build-tool/SdCliIndexFileGenerator.ts +79 -80
- package/src/build-tool/SdCliNgCacheCompilerHost.ts +58 -58
- package/src/build-tool/SdCliPackageLinter.ts +74 -74
- package/src/builder/SdCliClientBuilder.ts +58 -13
- package/src/builder/SdCliServerBuilder.ts +34 -14
- package/src/entry-points/SdCliFileCrypto.ts +87 -87
- package/src/entry-points/SdCliPrepare.ts +55 -55
- package/src/entry-points/SdCliProjectGenerator.ts +80 -38
- package/src/entry-points/file/base/fc_package_eslintrc.ts +10 -10
- package/src/entry-points/file/base/fc_package_tsconfig.ts +3 -2
- package/src/entry-points/file/client/fc_package_AppModule.ts +1 -1
- package/src/entry-points/file/client/fc_package_AppPage.ts +1 -21
- package/src/entry-points/file/client/fc_package_Page.ts +19 -0
- package/src/entry-points/file/project/fc_project_gitignore.ts +1 -1
- package/src/entry-points/file/project/fc_project_readme.ts +2 -1
- package/src/index.ts +55 -55
- package/src/ng-tools/SdCliNgModuleGenerator.ts +639 -640
- package/src/ng-tools/babel/SdCliBbFileMetadata.ts +568 -568
- package/src/ng-tools/babel/SdCliBbRootMetadata.ts +239 -239
- package/src/ng-tools/babel/SdCliBbUtil.ts +15 -15
- package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +234 -234
- package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +177 -177
- package/src/ng-tools/commons.ts +3 -3
- package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +384 -384
- package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +32 -32
- package/src/ng-tools/typescript/SdCliTsUtil.ts +29 -29
- package/src/packages/SdCliPackage.ts +1 -1
- package/src/utils/SdCliConfigUtil.ts +94 -94
- package/src/utils/SdCliNpmConfigUtil.ts +16 -16
- package/dist/entry-points/file/client/fc_package_appicons.d.ts +0 -1
- package/dist/entry-points/file/client/fc_package_appicons.mjs +0 -6
- package/src/entry-points/file/client/fc_package_appicons.ts +0 -5
|
@@ -1,80 +1,79 @@
|
|
|
1
|
-
import { ITsconfig } from "../commons";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
private
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.replace(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
1
|
+
import { ITsconfig } from "../commons";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
4
|
+
import chokidar from "chokidar";
|
|
5
|
+
|
|
6
|
+
export class SdCliIndexFileGenerator {
|
|
7
|
+
private readonly _indexFilePath = path.resolve(this.rootPath, "src/index.ts");
|
|
8
|
+
private _contentCache: string | undefined;
|
|
9
|
+
|
|
10
|
+
public constructor(public readonly rootPath: string,
|
|
11
|
+
public readonly config: ISdAutoIndexConfig) {
|
|
12
|
+
this._contentCache = FsUtil.exists(this._indexFilePath) ? FsUtil.readFile(this._indexFilePath) : undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async watchAsync(): Promise<void> {
|
|
16
|
+
const watcher = chokidar.watch([path.resolve(this.rootPath, "src")], { persistent: true });
|
|
17
|
+
watcher.on("add", async (filePath) => {
|
|
18
|
+
if (filePath.endsWith(".ts")) {
|
|
19
|
+
await this.runAsync();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
watcher.on("unlink", async (filePath) => {
|
|
23
|
+
if (filePath.endsWith(".ts")) {
|
|
24
|
+
await this.runAsync();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
await this.runAsync();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public async runAsync(): Promise<void> {
|
|
32
|
+
const importTexts: string[] = [];
|
|
33
|
+
|
|
34
|
+
// 옵션의 polyfills 를 모두 import
|
|
35
|
+
if (this.config.polyfills) {
|
|
36
|
+
for (const polyfill of this.config.polyfills) {
|
|
37
|
+
importTexts.push(`import "${polyfill}";`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 내부 파일들 import
|
|
42
|
+
const filePaths = await this._getFilePathsAsync();
|
|
43
|
+
for (const filePath of filePaths) {
|
|
44
|
+
const requirePath = PathUtil.posix(path.relative(path.dirname(this._indexFilePath), filePath))
|
|
45
|
+
.replace(/\.ts$/, "")
|
|
46
|
+
.replace(/\/index$/, "");
|
|
47
|
+
|
|
48
|
+
const sourceTsFileContent = await FsUtil.readFileAsync(filePath);
|
|
49
|
+
if (sourceTsFileContent.split("\n").some((line) => line.startsWith("export "))) {
|
|
50
|
+
importTexts.push(`export * from "./${requirePath}";`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
importTexts.push(`import "./${requirePath}";`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const content = importTexts.join("\n") + "\n";
|
|
58
|
+
const prevContent = this._contentCache;
|
|
59
|
+
this._contentCache = content;
|
|
60
|
+
if (content.trim() !== prevContent?.trim()) {
|
|
61
|
+
await FsUtil.writeFileAsync(this._indexFilePath, content);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private async _getFilePathsAsync(): Promise<string[]> {
|
|
66
|
+
const tsconfig: ITsconfig = await FsUtil.readJsonAsync(path.resolve(this.rootPath, "tsconfig.json"));
|
|
67
|
+
const entryFilePaths = tsconfig.files?.map((item) => path.resolve(this.rootPath, item)) ?? [];
|
|
68
|
+
|
|
69
|
+
return (await FsUtil.globAsync(path.resolve(this.rootPath, "src/**/*.ts"), { nodir: true }))
|
|
70
|
+
.filter((item) => (
|
|
71
|
+
!entryFilePaths.includes(item)
|
|
72
|
+
&& item !== this._indexFilePath
|
|
73
|
+
));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ISdAutoIndexConfig {
|
|
78
|
+
polyfills?: string[];
|
|
79
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { PathUtil } from "@simplysm/sd-core-node";
|
|
3
|
-
import sass from "sass";
|
|
4
|
-
import { fileURLToPath, pathToFileURL, URL } from "url";
|
|
5
|
-
|
|
6
|
-
export class SdCliNgCacheCompilerHost {
|
|
7
|
-
public static wrap(compilerHost: ts.CompilerHost,
|
|
8
|
-
sourceFileCache: Map<string, IFileCache>): ts.CompilerHost {
|
|
9
|
-
const cacheCompilerHost = { ...compilerHost };
|
|
10
|
-
|
|
11
|
-
cacheCompilerHost["readResource"] = (fileName: string) => {
|
|
12
|
-
const cache = sourceFileCache.getOrCreate(PathUtil.posix(fileName), {});
|
|
13
|
-
if (cache.content === undefined) {
|
|
14
|
-
cache.content = compilerHost.readFile.call(cacheCompilerHost, fileName);
|
|
15
|
-
}
|
|
16
|
-
return cache.content;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
cacheCompilerHost["transformResource"] = async (data, context) => {
|
|
20
|
-
if (context.resourceFile != null || context.type !== "style") {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const cache = sourceFileCache.getOrCreate(PathUtil.posix(context.containingFile), {});
|
|
25
|
-
if (cache.styleContent === undefined) {
|
|
26
|
-
const scssResult = await sass.compileStringAsync(data, {
|
|
27
|
-
url: new URL((context.containingFile as string) + ".sd.scss"),
|
|
28
|
-
importer: {
|
|
29
|
-
findFileUrl: (url) => {
|
|
30
|
-
if (!url.startsWith("~")) return pathToFileURL(url);
|
|
31
|
-
return new URL(url.substring(1), pathToFileURL("node_modules"));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
cache.styleContent = scssResult.css.toString();
|
|
37
|
-
|
|
38
|
-
const deps = scssResult.loadedUrls.slice(1).map((item) => PathUtil.posix(fileURLToPath(item.href)));
|
|
39
|
-
for (const dep of deps) {
|
|
40
|
-
const depCache = sourceFileCache.getOrCreate(dep, {});
|
|
41
|
-
depCache.importerSet = depCache.importerSet ?? new Set<string>();
|
|
42
|
-
depCache.importerSet.add(PathUtil.posix(context.containingFile));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return { content: cache.styleContent };
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
return cacheCompilerHost;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
interface IFileCache {
|
|
53
|
-
exists?: boolean;
|
|
54
|
-
sourceFile?: ts.SourceFile;
|
|
55
|
-
content?: string;
|
|
56
|
-
styleContent?: string;
|
|
57
|
-
importerSet?: Set<string>;
|
|
58
|
-
}
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { PathUtil } from "@simplysm/sd-core-node";
|
|
3
|
+
import sass from "sass";
|
|
4
|
+
import { fileURLToPath, pathToFileURL, URL } from "url";
|
|
5
|
+
|
|
6
|
+
export class SdCliNgCacheCompilerHost {
|
|
7
|
+
public static wrap(compilerHost: ts.CompilerHost,
|
|
8
|
+
sourceFileCache: Map<string, IFileCache>): ts.CompilerHost {
|
|
9
|
+
const cacheCompilerHost = { ...compilerHost };
|
|
10
|
+
|
|
11
|
+
cacheCompilerHost["readResource"] = (fileName: string) => {
|
|
12
|
+
const cache = sourceFileCache.getOrCreate(PathUtil.posix(fileName), {});
|
|
13
|
+
if (cache.content === undefined) {
|
|
14
|
+
cache.content = compilerHost.readFile.call(cacheCompilerHost, fileName);
|
|
15
|
+
}
|
|
16
|
+
return cache.content;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
cacheCompilerHost["transformResource"] = async (data, context) => {
|
|
20
|
+
if (context.resourceFile != null || context.type !== "style") {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const cache = sourceFileCache.getOrCreate(PathUtil.posix(context.containingFile), {});
|
|
25
|
+
if (cache.styleContent === undefined) {
|
|
26
|
+
const scssResult = await sass.compileStringAsync(data, {
|
|
27
|
+
url: new URL((context.containingFile as string) + ".sd.scss"),
|
|
28
|
+
importer: {
|
|
29
|
+
findFileUrl: (url) => {
|
|
30
|
+
if (!url.startsWith("~")) return pathToFileURL(url);
|
|
31
|
+
return new URL(url.substring(1), pathToFileURL("node_modules"));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
cache.styleContent = scssResult.css.toString();
|
|
37
|
+
|
|
38
|
+
const deps = scssResult.loadedUrls.slice(1).map((item) => PathUtil.posix(fileURLToPath(item.href)));
|
|
39
|
+
for (const dep of deps) {
|
|
40
|
+
const depCache = sourceFileCache.getOrCreate(dep, {});
|
|
41
|
+
depCache.importerSet = depCache.importerSet ?? new Set<string>();
|
|
42
|
+
depCache.importerSet.add(PathUtil.posix(context.containingFile));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { content: cache.styleContent };
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return cacheCompilerHost;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface IFileCache {
|
|
53
|
+
exists?: boolean;
|
|
54
|
+
sourceFile?: ts.SourceFile;
|
|
55
|
+
content?: string;
|
|
56
|
+
styleContent?: string;
|
|
57
|
+
importerSet?: Set<string>;
|
|
58
|
+
}
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
import { ISdCliPackageBuildResult } from "../commons";
|
|
2
|
-
import ts from "typescript";
|
|
3
|
-
import { FsUtil } from "@simplysm/sd-core-node";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { ESLint } from "eslint";
|
|
6
|
-
|
|
7
|
-
export class SdCliPackageLinter {
|
|
8
|
-
private readonly _lintResultCache = new Map<string, ISdCliPackageBuildResult[]>();
|
|
9
|
-
|
|
10
|
-
public constructor(private readonly _rootPath: string) {
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public async lintAsync(filePaths: string[], program?: ts.Program): Promise<ISdCliPackageBuildResult[]> {
|
|
14
|
-
if (!FsUtil.exists(path.resolve(this._rootPath, ".eslintrc.cjs"))) return [];
|
|
15
|
-
|
|
16
|
-
const linter = new ESLint(
|
|
17
|
-
program && filePaths.some((item) => item.endsWith(".ts")) ? {
|
|
18
|
-
overrideConfig: {
|
|
19
|
-
overrides: [
|
|
20
|
-
{
|
|
21
|
-
files: ["*.ts"],
|
|
22
|
-
parserOptions: {
|
|
23
|
-
/*programs: [program],
|
|
24
|
-
tsconfigRootDir: null,
|
|
25
|
-
project: null*/
|
|
26
|
-
tsconfigRootDir: this._rootPath,
|
|
27
|
-
project: "tsconfig-build.json"
|
|
28
|
-
},
|
|
29
|
-
settings: {
|
|
30
|
-
"import/resolver": {
|
|
31
|
-
"typescript": {
|
|
32
|
-
/*programs: [program],
|
|
33
|
-
project: null*/
|
|
34
|
-
project: path.resolve(this._rootPath, "tsconfig-build.json")
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
} : {}
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
const lintFilePaths = await filePaths
|
|
45
|
-
.filterAsync(async (filePath) => (
|
|
46
|
-
!filePath.endsWith(".d.ts") &&
|
|
47
|
-
/\.[cm]?[tj]sx?$/.test(filePath) &&
|
|
48
|
-
!(await linter.isPathIgnored(filePath))
|
|
49
|
-
));
|
|
50
|
-
for (const lintFilePath of lintFilePaths) {
|
|
51
|
-
this._lintResultCache.delete(lintFilePath);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const lintResults = await linter.lintFiles(lintFilePaths);
|
|
55
|
-
|
|
56
|
-
const result = lintResults.map((lintResult) => ({
|
|
57
|
-
filePath: lintResult.filePath,
|
|
58
|
-
results: lintResult.messages.map((msg) => ({
|
|
59
|
-
filePath: lintResult.filePath,
|
|
60
|
-
line: msg.line,
|
|
61
|
-
char: msg.column,
|
|
62
|
-
code: msg.ruleId ?? undefined,
|
|
63
|
-
severity: msg.severity === 1 ? "warning" as const : "error" as const,
|
|
64
|
-
message: msg.message
|
|
65
|
-
}))
|
|
66
|
-
}));
|
|
67
|
-
|
|
68
|
-
for (const resultItem of result) {
|
|
69
|
-
this._lintResultCache.set(resultItem.filePath, resultItem.results);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return Array.from(this._lintResultCache.values()).mapMany();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
1
|
+
import { ISdCliPackageBuildResult } from "../commons";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import { FsUtil } from "@simplysm/sd-core-node";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { ESLint } from "eslint";
|
|
6
|
+
|
|
7
|
+
export class SdCliPackageLinter {
|
|
8
|
+
private readonly _lintResultCache = new Map<string, ISdCliPackageBuildResult[]>();
|
|
9
|
+
|
|
10
|
+
public constructor(private readonly _rootPath: string) {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async lintAsync(filePaths: string[], program?: ts.Program): Promise<ISdCliPackageBuildResult[]> {
|
|
14
|
+
if (!FsUtil.exists(path.resolve(this._rootPath, ".eslintrc.cjs"))) return [];
|
|
15
|
+
|
|
16
|
+
const linter = new ESLint(
|
|
17
|
+
program && filePaths.some((item) => item.endsWith(".ts")) ? {
|
|
18
|
+
overrideConfig: {
|
|
19
|
+
overrides: [
|
|
20
|
+
{
|
|
21
|
+
files: ["*.ts"],
|
|
22
|
+
parserOptions: {
|
|
23
|
+
/*programs: [program],
|
|
24
|
+
tsconfigRootDir: null,
|
|
25
|
+
project: null*/
|
|
26
|
+
tsconfigRootDir: this._rootPath,
|
|
27
|
+
project: "tsconfig-build.json"
|
|
28
|
+
},
|
|
29
|
+
settings: {
|
|
30
|
+
"import/resolver": {
|
|
31
|
+
"typescript": {
|
|
32
|
+
/*programs: [program],
|
|
33
|
+
project: null*/
|
|
34
|
+
project: path.resolve(this._rootPath, "tsconfig-build.json")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
} : {}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const lintFilePaths = await filePaths
|
|
45
|
+
.filterAsync(async (filePath) => (
|
|
46
|
+
!filePath.endsWith(".d.ts") &&
|
|
47
|
+
/\.[cm]?[tj]sx?$/.test(filePath) &&
|
|
48
|
+
!(await linter.isPathIgnored(filePath))
|
|
49
|
+
));
|
|
50
|
+
for (const lintFilePath of lintFilePaths) {
|
|
51
|
+
this._lintResultCache.delete(lintFilePath);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const lintResults = await linter.lintFiles(lintFilePaths);
|
|
55
|
+
|
|
56
|
+
const result = lintResults.map((lintResult) => ({
|
|
57
|
+
filePath: lintResult.filePath,
|
|
58
|
+
results: lintResult.messages.map((msg) => ({
|
|
59
|
+
filePath: lintResult.filePath,
|
|
60
|
+
line: msg.line,
|
|
61
|
+
char: msg.column,
|
|
62
|
+
code: msg.ruleId ?? undefined,
|
|
63
|
+
severity: msg.severity === 1 ? "warning" as const : "error" as const,
|
|
64
|
+
message: msg.message
|
|
65
|
+
}))
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
for (const resultItem of result) {
|
|
69
|
+
this._lintResultCache.set(resultItem.filePath, resultItem.results);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return Array.from(this._lintResultCache.values()).mapMany();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -46,6 +46,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
46
46
|
|
|
47
47
|
private readonly _hasAngularRoute: boolean;
|
|
48
48
|
|
|
49
|
+
private readonly _cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
50
|
+
|
|
49
51
|
public constructor(private readonly _rootPath: string,
|
|
50
52
|
private readonly _config: ISdCliClientPackageConfig,
|
|
51
53
|
private readonly _workspaceRootPath: string) {
|
|
@@ -92,11 +94,39 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
92
94
|
return super.on(event, listener);
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
private async _checkCacheAsync(watch: boolean): Promise<void> {
|
|
98
|
+
const workspacePkgLockContent = await FsUtil.readFileAsync(path.resolve(this._workspaceRootPath, "package-lock.json"));
|
|
99
|
+
|
|
100
|
+
// const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
101
|
+
|
|
102
|
+
const versionHash = createHash("sha1")
|
|
103
|
+
.update(workspacePkgLockContent)
|
|
104
|
+
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
105
|
+
.update(JSON.stringify(this._config))
|
|
106
|
+
.update(watch.toString())
|
|
107
|
+
.digest("hex");
|
|
108
|
+
if (
|
|
109
|
+
!FsUtil.exists(path.resolve(this._cacheBasePath, "version")) // 버전파일이 없거나
|
|
110
|
+
|| (
|
|
111
|
+
FsUtil.exists(path.resolve(this._cacheBasePath, "version")) &&
|
|
112
|
+
await FsUtil.readFileAsync(path.resolve(this._cacheBasePath, "version")) !== versionHash
|
|
113
|
+
) // 버전이 현재 버전과 다르면
|
|
114
|
+
) {
|
|
115
|
+
// 캐시 삭제
|
|
116
|
+
await FsUtil.removeAsync(path.resolve(this._cacheBasePath));
|
|
117
|
+
}
|
|
118
|
+
// 버전쓰기
|
|
119
|
+
await FsUtil.writeFileAsync(path.resolve(this._cacheBasePath, "version"), versionHash);
|
|
120
|
+
}
|
|
121
|
+
|
|
95
122
|
public async watchAsync(): Promise<void> {
|
|
96
123
|
// DIST 비우기
|
|
97
124
|
await FsUtil.removeAsync(path.resolve(this._rootPath, ".electron"));
|
|
98
125
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
99
126
|
|
|
127
|
+
// 캐시체크
|
|
128
|
+
await this._checkCacheAsync(true);
|
|
129
|
+
|
|
100
130
|
// NgModule 생성
|
|
101
131
|
await this._ngModuleGenerator.runAsync();
|
|
102
132
|
|
|
@@ -176,6 +206,9 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
176
206
|
this._logger.debug("removeAsync:2");
|
|
177
207
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
178
208
|
|
|
209
|
+
// 캐시체크
|
|
210
|
+
await this._checkCacheAsync(false);
|
|
211
|
+
|
|
179
212
|
// NgModule 생성
|
|
180
213
|
this._logger.debug("ngModule");
|
|
181
214
|
await this._ngModuleGenerator.runAsync();
|
|
@@ -215,7 +248,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
215
248
|
await augmentAppWithServiceWorker(
|
|
216
249
|
PathUtil.posix(path.relative(this._workspaceRootPath, this._rootPath)) as any,
|
|
217
250
|
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._parsedTsconfig.options.outDir!))) as any,
|
|
218
|
-
`/${packageKey}
|
|
251
|
+
`/${packageKey}/` as any,
|
|
219
252
|
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._rootPath, "ngsw-config.json")))
|
|
220
253
|
);
|
|
221
254
|
}
|
|
@@ -333,8 +366,6 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
333
366
|
const pkgKey = npmConfig.name.split("/").last()!;
|
|
334
367
|
const publicPath = builderType === "web" ? `/${pkgKey}/` : watch ? `/${pkgKey}/${builderType}/` : ``;
|
|
335
368
|
|
|
336
|
-
const cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
337
|
-
|
|
338
369
|
const distPath = (builderType === "cordova" && !watch) ? path.resolve(this._cordova!.cordovaPath, "www")
|
|
339
370
|
: (builderType === "electron" && !watch) ? path.resolve(this._rootPath, ".electron/src")
|
|
340
371
|
: builderType === "web" ? this._parsedTsconfig.options.outDir
|
|
@@ -346,6 +377,25 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
346
377
|
const polyfillsFilePath = path.resolve(this._rootPath, "src/polyfills.ts");
|
|
347
378
|
const stylesFilePath = path.resolve(this._rootPath, "src/styles.scss");
|
|
348
379
|
|
|
380
|
+
const versionHash = createHash("sha1")
|
|
381
|
+
.update(workspacePkgLockContent)
|
|
382
|
+
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
383
|
+
.update(JSON.stringify(this._config))
|
|
384
|
+
.update(watch.toString())
|
|
385
|
+
.digest("hex");
|
|
386
|
+
if (
|
|
387
|
+
!FsUtil.exists(path.resolve(this._cacheBasePath, "version")) // 버전파일이 없거나
|
|
388
|
+
|| (
|
|
389
|
+
FsUtil.exists(path.resolve(this._cacheBasePath, "version")) &&
|
|
390
|
+
FsUtil.readFile(path.resolve(this._cacheBasePath, "version")) !== versionHash
|
|
391
|
+
) // 버전이 현재 버전과 다르면
|
|
392
|
+
) {
|
|
393
|
+
// 캐시 삭제
|
|
394
|
+
FsUtil.remove(path.resolve(this._cacheBasePath));
|
|
395
|
+
}
|
|
396
|
+
// 버전쓰기
|
|
397
|
+
FsUtil.writeFile(path.resolve(this._cacheBasePath, "version"), versionHash);
|
|
398
|
+
|
|
349
399
|
let prevProgressMessage = "";
|
|
350
400
|
return {
|
|
351
401
|
mode: watch ? "development" : "production",
|
|
@@ -400,14 +450,9 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
400
450
|
cache: {
|
|
401
451
|
type: "filesystem",
|
|
402
452
|
profile: undefined,
|
|
403
|
-
cacheDirectory:
|
|
453
|
+
cacheDirectory: this._cacheBasePath,
|
|
404
454
|
maxMemoryGenerations: 1,
|
|
405
|
-
name:
|
|
406
|
-
.update(workspacePkgLockContent)
|
|
407
|
-
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
408
|
-
.update(JSON.stringify(this._config))
|
|
409
|
-
.update(watch.toString())
|
|
410
|
-
.digest("hex")
|
|
455
|
+
name: "webpack"
|
|
411
456
|
},
|
|
412
457
|
snapshot: {
|
|
413
458
|
immutablePaths: internalModuleCachePaths,
|
|
@@ -487,7 +532,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
487
532
|
{
|
|
488
533
|
loader: "@angular-devkit/build-angular/src/babel/webpack-loader",
|
|
489
534
|
options: {
|
|
490
|
-
cacheDirectory: path.resolve(
|
|
535
|
+
cacheDirectory: path.resolve(this._cacheBasePath, "webpack-babel"),
|
|
491
536
|
scriptTarget: ts.ScriptTarget.ES2017,
|
|
492
537
|
aot: true,
|
|
493
538
|
optimize: !watch,
|
|
@@ -694,8 +739,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
694
739
|
sri: false,
|
|
695
740
|
cache: {
|
|
696
741
|
enabled: true,
|
|
697
|
-
basePath:
|
|
698
|
-
path: path.resolve(
|
|
742
|
+
basePath: this._cacheBasePath,
|
|
743
|
+
path: path.resolve(this._cacheBasePath, "webpack-html")
|
|
699
744
|
},
|
|
700
745
|
postTransform: undefined,
|
|
701
746
|
optimization: {
|
|
@@ -24,6 +24,8 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
24
24
|
private readonly _parsedTsconfig: ts.ParsedCommandLine;
|
|
25
25
|
private readonly _npmConfigMap = new Map<string, INpmConfig>();
|
|
26
26
|
|
|
27
|
+
private readonly _cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
28
|
+
|
|
27
29
|
public constructor(private readonly _rootPath: string,
|
|
28
30
|
private readonly _config: ISdCliServerPackageConfig,
|
|
29
31
|
private readonly _workspaceRootPath: string) {
|
|
@@ -41,10 +43,38 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
41
43
|
return super.on(event, listener);
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
private async _checkCacheAsync(watch: boolean): Promise<void> {
|
|
47
|
+
const workspacePkgLockContent = await FsUtil.readFileAsync(path.resolve(this._workspaceRootPath, "package-lock.json"));
|
|
48
|
+
|
|
49
|
+
// const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
50
|
+
|
|
51
|
+
const versionHash = createHash("sha1")
|
|
52
|
+
.update(workspacePkgLockContent)
|
|
53
|
+
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
54
|
+
.update(JSON.stringify(this._config))
|
|
55
|
+
.update(watch.toString())
|
|
56
|
+
.digest("hex");
|
|
57
|
+
if (
|
|
58
|
+
!FsUtil.exists(path.resolve(this._cacheBasePath, "version")) // 버전파일이 없거나
|
|
59
|
+
|| (
|
|
60
|
+
FsUtil.exists(path.resolve(this._cacheBasePath, "version")) &&
|
|
61
|
+
await FsUtil.readFileAsync(path.resolve(this._cacheBasePath, "version")) !== versionHash
|
|
62
|
+
) // 버전이 현재 버전과 다르면
|
|
63
|
+
) {
|
|
64
|
+
// 캐시 삭제
|
|
65
|
+
await FsUtil.removeAsync(path.resolve(this._cacheBasePath));
|
|
66
|
+
}
|
|
67
|
+
// 버전쓰기
|
|
68
|
+
await FsUtil.writeFileAsync(path.resolve(this._cacheBasePath, "version"), versionHash);
|
|
69
|
+
}
|
|
70
|
+
|
|
44
71
|
public async watchAsync(): Promise<void> {
|
|
45
72
|
// DIST 비우기
|
|
46
73
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
47
74
|
|
|
75
|
+
// 캐시체크
|
|
76
|
+
await this._checkCacheAsync(true);
|
|
77
|
+
|
|
48
78
|
// 빌드 준비
|
|
49
79
|
const extModules = this._getExternalModules();
|
|
50
80
|
const webpackConfig = this._getWebpackConfig(true, extModules);
|
|
@@ -233,11 +263,6 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
233
263
|
const pkgKey = npmConfig.name.split("/").last()!;
|
|
234
264
|
// const pkgVersion = npmConfig.version;
|
|
235
265
|
|
|
236
|
-
const workspacePkgLockContent = FsUtil.readFile(path.resolve(this._workspaceRootPath, "package-lock.json"));
|
|
237
|
-
|
|
238
|
-
const cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
239
|
-
// const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
240
|
-
|
|
241
266
|
let prevProgressMessage = "";
|
|
242
267
|
return {
|
|
243
268
|
mode: watch ? "development" : "production",
|
|
@@ -291,14 +316,9 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
291
316
|
cache: {
|
|
292
317
|
type: "filesystem",
|
|
293
318
|
profile: watch ? undefined : false,
|
|
294
|
-
cacheDirectory:
|
|
319
|
+
cacheDirectory: this._cacheBasePath,
|
|
295
320
|
maxMemoryGenerations: 1,
|
|
296
|
-
name:
|
|
297
|
-
.update(workspacePkgLockContent)
|
|
298
|
-
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
299
|
-
.update(JSON.stringify(this._config))
|
|
300
|
-
.update(watch.toString())
|
|
301
|
-
.digest("hex")
|
|
321
|
+
name: "webpack"
|
|
302
322
|
},
|
|
303
323
|
snapshot: {
|
|
304
324
|
immutablePaths: internalModuleCachePaths,
|
|
@@ -474,7 +494,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
474
494
|
continue;
|
|
475
495
|
}
|
|
476
496
|
|
|
477
|
-
if (FsUtil.
|
|
497
|
+
if (FsUtil.glob(path.resolve(modulePath, "**/binding.gyp")).length > 0) {
|
|
478
498
|
results.push({ name: moduleName, exists: true });
|
|
479
499
|
}
|
|
480
500
|
|
|
@@ -495,7 +515,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
495
515
|
continue;
|
|
496
516
|
}
|
|
497
517
|
|
|
498
|
-
if (FsUtil.
|
|
518
|
+
if (FsUtil.glob(path.resolve(optModulePath, "**/binding.gyp")).length > 0) {
|
|
499
519
|
results.push({ name: optModuleName, exists: true });
|
|
500
520
|
}
|
|
501
521
|
|