Skip to content

Commit 1cb8507

Browse files
authored
feat: support dual package (#27)
* feat: support dual package * fix: webpack load esm
1 parent 5c8f6d9 commit 1cb8507

File tree

7 files changed

+98
-13
lines changed

7 files changed

+98
-13
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"sideEffects": false,
2929
"main": "lib/$cjs/index.js",
3030
"module": "lib/$esm/index.js",
31+
"browser": "lib/$esm/index.js",
3132
"types": "lib/$types/index.d.ts",
3233
"directories": {
3334
"lib": "lib"

scripts/build.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import "./clean";
22

33
import { copyPackageSet } from "./tools/copyPackageSet";
4+
import { generateExportsField } from "./tools/dualPackageSupport";
45
import { shell } from "./tools/shell";
56

67
const main = async () => {
@@ -10,7 +11,18 @@ const main = async () => {
1011
shell("yarn tsc -p tsconfig.esm.json"),
1112
]);
1213
await shell("cherry-pick --cwd ./lib --input-dir ../src --types-dir ./\\$types --cjs-dir ./\\$cjs --esm-dir ./\\$esm");
13-
await copyPackageSet();
14+
15+
const exportsFiled = generateExportsField("./src", {
16+
directory: {
17+
import: "./$esm",
18+
// require: "./$cjs", // OFFにするとwebpack 5でesmを読んでくれる
19+
node: "./$cjs",
20+
browser: "./$esm",
21+
default: "./$cjs",
22+
},
23+
});
24+
25+
await copyPackageSet(exportsFiled);
1426
};
1527

1628
main().catch(error => {

scripts/tools/copyPackageSet.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ const pkg = require("../../package.json");
99
/**
1010
* README, LICENCE, CHANGELOG.mdをlibディレクトリに出力する
1111
*/
12-
export const copyPackageSet = async (): Promise<void> => {
12+
export const copyPackageSet = async (exportsField: {}): Promise<void> => {
1313
const libDir = "lib";
1414
const publishPackageJson = path.join(libDir, "package.json");
1515
pkg.private = undefined;
1616
pkg.main = path.posix.relative(libDir, pkg.main);
17+
pkg.browser = path.posix.relative(libDir, pkg.browser);
1718
pkg.module = path.posix.relative(libDir, pkg.module);
1819
pkg.types = path.posix.relative(libDir, pkg.types);
1920
pkg.directories = undefined;
2021
pkg.files = undefined;
22+
pkg.exports = exportsField;
2123
fs.writeFileSync(publishPackageJson, JSON.stringify(pkg, null, 2), {
2224
encoding: "utf-8",
2325
});

scripts/tools/dualPackageSupport.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import * as fs from "fs";
2+
import { posix as path } from "path";
3+
4+
export type SupportModuleType = "browser" | "node" | "require" | "import" | "default";
5+
6+
export type SupportModule = {
7+
// eslint-disable-next-line no-unused-vars
8+
[P in SupportModuleType]?: string;
9+
};
10+
11+
export interface Option {
12+
directory: Partial<SupportModule>;
13+
}
14+
15+
export interface ExportsField {
16+
[filepath: string]: SupportModule;
17+
}
18+
19+
const isFile = (p: string) => {
20+
return fs.existsSync(p) && fs.statSync(p).isFile();
21+
};
22+
23+
const isTypeScriptFile = (p: string): boolean => {
24+
return !!p.match(/tsx?$/);
25+
};
26+
27+
const isIndexFile = (p: string) => {
28+
return !!p.match(/index\.tsx?$/);
29+
};
30+
31+
const convertNameTsToJs = (p: string): string => {
32+
return p.replace(/\.tsx?$/, ".js");
33+
};
34+
35+
const isSupportModuleType = (text: string | undefined): text is SupportModuleType => {
36+
if (!text) {
37+
return false;
38+
}
39+
return ["node", "browser", "require", "import", "default"].includes(text);
40+
};
41+
42+
const trimExtension = (p: string): string => {
43+
const ext = path.extname(p);
44+
return p.replace(new RegExp(ext + "$"), "");
45+
};
46+
47+
export const generateExportsField = (sourceRootDirectory: string, option: Option): ExportsField => {
48+
const pathArray = fs.readdirSync(sourceRootDirectory);
49+
const filteredPathArray = pathArray.filter(p => {
50+
const pathName = path.join(sourceRootDirectory, p);
51+
return isTypeScriptFile(pathName) && isFile(pathName);
52+
});
53+
return filteredPathArray.reduce<ExportsField>((exportsFields, pathName) => {
54+
const filepath = isIndexFile(pathName) ? "." : "./" + trimExtension(pathName);
55+
const jsFilename = convertNameTsToJs(pathName);
56+
const supportModule: SupportModule = {};
57+
Object.entries(option.directory).forEach(([key, exportBaseDirectory]) => {
58+
if (isSupportModuleType(key) && typeof exportBaseDirectory === "string") {
59+
supportModule[key] = "./" + path.join(exportBaseDirectory, jsFilename);
60+
}
61+
});
62+
return { ...exportsFields, [filepath]: supportModule };
63+
}, {});
64+
};

src/Validator/v3/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ export const validate = (openapiDoc: OpenApi.Document, option?: LogOption): void
4343
validate(openapiDoc);
4444
if (validate.errors) {
4545
showLogs(validate.errors, option);
46-
process.exit(1);
46+
throw new Error("Validation Error");
4747
}
4848
};

src/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export * as TypeScriptCodeGenerator from "./CodeGenerator";
2+
export * as Converter from "./Converter";
3+
export * as DefaultCodeTemplate from "./DefaultCodeTemplate";
4+
export { fileSystem } from "./FileSystem";
5+
export * as ResolveReference from "./ResolveReference";
6+
export * as Validator from "./Validator";

yarn.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4359,10 +4359,10 @@ globals@^12.1.0:
43594359
dependencies:
43604360
type-fest "^0.8.1"
43614361

4362-
globalyzer@^0.1.0:
4363-
version "0.1.4"
4364-
resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.4.tgz#bc8e273afe1ac7c24eea8def5b802340c5cc534f"
4365-
integrity sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA==
4362+
4363+
version "0.1.0"
4364+
resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465"
4365+
integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==
43664366

43674367
43684368
version "10.0.0"
@@ -4404,7 +4404,7 @@ globby@^9.2.0:
44044404
pify "^4.0.1"
44054405
slash "^2.0.0"
44064406

4407-
globrex@^0.1.1:
4407+
globrex@^0.1.2:
44084408
version "0.1.2"
44094409
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
44104410
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
@@ -8362,12 +8362,12 @@ through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8:
83628362
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
83638363

83648364
tiny-glob@^0.2.6:
8365-
version "0.2.6"
8366-
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.6.tgz#9e056e169d9788fe8a734dfa1ff02e9b92ed7eda"
8367-
integrity sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw==
8365+
version "0.2.8"
8366+
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.8.tgz#b2792c396cc62db891ffa161fe8b33e76123e531"
8367+
integrity sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==
83688368
dependencies:
8369-
globalyzer "^0.1.0"
8370-
globrex "^0.1.1"
8369+
globalyzer "0.1.0"
8370+
globrex "^0.1.2"
83718371

83728372
tmp@^0.0.33:
83738373
version "0.0.33"

0 commit comments

Comments
 (0)