Skip to content

Commit

Permalink
refactor: build script update, disabled bundling
Browse files Browse the repository at this point in the history
  • Loading branch information
ncpa0cpl committed Aug 3, 2022
1 parent 80d10c8 commit 1acb4f1
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 42 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
],
"semi": ["error", "always"],
"@typescript-eslint/consistent-type-imports": 2,
"@typescript-eslint/consistent-type-exports": 2,
"@typescript-eslint/member-delimiter-style": 2,
"@typescript-eslint/no-confusing-non-null-assertion": 2,
"@typescript-eslint/no-misused-new": 2,
Expand Down
12 changes: 6 additions & 6 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
__mocks__
__tests__
.eslintignore
.eslintrc.json
.github
.gitignore
.husky
.prettierrc.json
.vscode
coverage
docs
git-hook-tasks.config.json
jest.config.js
scripts
src
.eslintignore
.eslintrc.json
.gitignore
.prettierrc.json
git-hook-tasks.config.json
jest.config.js
tsconfig.test.json
yarn-error.log
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"git-hook-tasks": "github:ncpa0cpl/git-hook-tasks",
"husky": "^8.0.1",
"jest": "^28.1.0",
"node-os-walk": "^1.0.0",
"prettier": "^2.6.2",
"prettier-plugin-jsdoc": "^0.3.38",
"ts-jest": "^28.0.2",
Expand All @@ -26,7 +27,7 @@
"require": "./dist/cjs/index.cjs"
},
"./jsx-runtime": {
"types": "./dist/types/jsx/jsx-runtime.d.ts",
"types": "./dist/types/jsx-runtime.d.ts",
"import": "./dist/esm/jsx-runtime.mjs",
"require": "./dist/cjs/jsx-runtime.cjs"
}
Expand Down
142 changes: 113 additions & 29 deletions scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// const esbuild = require("esbuild");
// const path = require("path");
import esbuild from "esbuild";
import path from "path";
import { walk } from "node-os-walk";

// get first process argument
const argv = process.argv.at(2);
const argv = process.argv[2];

if (argv !== "esmodule" && argv !== "commonjs") {
console.error("Invalid target, allowed values: 'esmodule', 'commonjs'");
Expand All @@ -14,44 +13,129 @@ if (argv !== "esmodule" && argv !== "commonjs") {
const format = argv === "esmodule" ? "esm" : "cjs";
const outDir = format === "esm" ? "./dist/esm" : "./dist/cjs";

const ext = format === "esm" ? ".mjs" : ".cjs";
const ALLOWED_EXTENSIONS = [
".ts",
".js",
".cjs",
".mjs",
".mts",
".cts",
".tsx",
".jsx",
];

async function main() {
await esbuild.build({
outfile: path.resolve(process.cwd(), outDir, `index${ext}`),
tsconfig: path.resolve(process.cwd(), "tsconfig.build.json"),
entryPoints: [path.resolve(process.cwd(), "src/index.ts")],
format: format,
bundle: true,
});
/**
* @param {string} relativePath
* @param {string[]} rest
*/
function p(relativePath, ...rest) {
return path.resolve(process.cwd(), relativePath, ...rest);
}

/**
* @param {string} str
* @param {string[]} suffixes
*/
function endsWith(str, ...suffixes) {
for (const suffix of suffixes) {
if (str.endsWith(suffix)) {
return true;
}
}
return false;
}

/** @param {string} ext */
const ESbuildImportExtensionPlugin = (ext) => ({
name: "esbuild-esm-import-plugin",
setup(build) {
build.onResolve({ filter: /.*/ }, (args) => {
if (args.importer) return { path: args.path + ext, external: true };
});
},
});

/**
* @param {{
* entrypoint: string;
* outfile: string;
* format: "esm" | "cjs";
* ext: string;
* }} options
*/
async function buildFile({ entrypoint, outfile, format, ext }) {
await esbuild.build({
outfile: path.resolve(process.cwd(), outDir, `jsx-runtime${ext}`),
target: "es6",
outfile,
tsconfig: path.resolve(process.cwd(), "tsconfig.build.json"),
entryPoints: [path.resolve(process.cwd(), "src/jsx/jsx-runtime.ts")],
entryPoints: [entrypoint],
format: format,
bundle: true,
outExtension: {
".js": ext,
},
plugins: [ESbuildImportExtensionPlugin(ext)],
});
}

/**
* @param {{
* rootDir: string;
* outDir: string;
* format: "esm" | "cjs";
* ext?: string;
* }} options
*/
async function build(options) {
const { format, outDir, rootDir } = options;
const ext = options.ext ?? (format === "esm" ? ".mjs" : ".cjs");

for await (const [root, _, files] of walk(rootDir)) {
for (const file of files) {
if (endsWith(file.name, ...ALLOWED_EXTENSIONS)) {
const fileName = path.parse(file.name).name;
const filepath = path.resolve(root, file.name);
const filepathRel = path.relative(rootDir, filepath);
const fileOutDirRel = path.dirname(filepathRel);

buildFile({
entrypoint: filepath,
outfile: path.resolve(outDir, fileOutDirRel, fileName + ext),
format,
ext,
});
}
}
}
}

async function main() {
/** @type Array<Promise<void>> */
const operations = [];

operations.push(
build({
rootDir: p("./src"),
outDir: p(outDir),
format,
})
);

if (format === "cjs") {
const legacyDir = "./dist/legacy";

await esbuild.build({
outfile: path.resolve(process.cwd(), legacyDir, `index.js`),
tsconfig: path.resolve(process.cwd(), "tsconfig.build.json"),
entryPoints: [path.resolve(process.cwd(), "src/index.ts")],
format: "cjs",
bundle: true,
});

await esbuild.build({
outfile: path.resolve(process.cwd(), legacyDir, `jsx-runtime.js`),
tsconfig: path.resolve(process.cwd(), "tsconfig.build.json"),
entryPoints: [path.resolve(process.cwd(), "src/jsx/jsx-runtime.ts")],
format: "cjs",
bundle: true,
});
// Build for legacy environments that do not support .cjs extensions
operations.push(
build({
rootDir: p("./src"),
outDir: p(legacyDir),
format: "cjs",
ext: ".js",
})
);
}

await Promise.all(operations);
}

main();
13 changes: 7 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import "./utilities/array-flat-polyfill";

export * from "./express/index";
export * from "./jsx/jsx.types";

export { renderToHtml, renderToHtmlAsync } from "./html-parser/render-to-html";
export * from "./express";
export {
renderToStringTemplateTag,
type StringTemplateParserOptions,
} from "./string-template-parser/render-to-string-template-tag";
export { renderToStringTemplateTag } from "./string-template-parser/render-to-string-template-tag";
export {
type ContextDefinition,
type ContextMap,
defineContext,
} from "./context-map/context-map";
export type { AttributeBool } from "./jsx/base-html-tag-props";
export type { StringTemplateParserOptions } from "./string-template-parser/render-to-string-template-tag";
export type { HTMLProps } from "./jsx/base-html-tag-props";
export * from "./jsx/jsx.types";
37 changes: 37 additions & 0 deletions src/utilities/array-flat-polyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable @typescript-eslint/prefer-for-of */

function flat<A extends any[], D extends number = 1>(
this: A,
depth?: D
): FlatArray<A, D>[] {
const copy: FlatArray<A, D>[] = [];

if (depth === undefined) {
// @ts-expect-error
depth = 1;
}

for (let i = 0; i < this.length; i++) {
const item = this[i];

if (depth! > 0 && Array.isArray(item)) {
const itemFlatCopy = flat.call(item, depth! - 1);
for (let j = 0; j < itemFlatCopy.length; j++) {
copy.push(itemFlatCopy[j]);
}
} else {
copy.push(item);
}
}

return copy;
}

// Add flat polyfill to Array prototype if not defined
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, "flat", {
configurable: true,
value: flat,
writable: true,
});
}

0 comments on commit 1acb4f1

Please sign in to comment.