aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-05-05 08:34:21 -0300
committerSebastian <sebasjm@gmail.com>2023-05-05 08:52:57 -0300
commit6340cc5454f637a97fb7329d2494c1dfc3fb1735 (patch)
treed97d65ed7df5c23ede7caa7047338d978c25d154 /packages
parent5e1f450a20aa00c1783337a3b6024167dbc568bd (diff)
add postcss, fix export names
Diffstat (limited to 'packages')
-rwxr-xr-xpackages/web-util/build.mjs127
-rw-r--r--packages/web-util/package.json34
-rw-r--r--packages/web-util/src/cli.ts1
-rw-r--r--packages/web-util/src/index.browser.ts1
-rw-r--r--packages/web-util/src/index.build.ts141
-rw-r--r--packages/web-util/src/index.testing.ts3
-rw-r--r--packages/web-util/src/index.ts1
-rw-r--r--packages/web-util/src/serve.ts167
-rw-r--r--packages/web-util/src/tests/index.ts2
9 files changed, 281 insertions, 196 deletions
diff --git a/packages/web-util/build.mjs b/packages/web-util/build.mjs
index 8e74f69c7..0b015f22c 100755
--- a/packages/web-util/build.mjs
+++ b/packages/web-util/build.mjs
@@ -15,34 +15,38 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import esbuild from 'esbuild'
-import path from "path"
-import fs from "fs"
+import esbuild from "esbuild";
+import path from "path";
+import fs from "fs";
// eslint-disable-next-line no-undef
-const BASE = process.cwd()
+const BASE = process.cwd();
-let GIT_ROOT = BASE
-while (!fs.existsSync(path.join(GIT_ROOT, '.git')) && GIT_ROOT !== '/') {
- GIT_ROOT = path.join(GIT_ROOT, '../')
+let GIT_ROOT = BASE;
+while (!fs.existsSync(path.join(GIT_ROOT, ".git")) && GIT_ROOT !== "/") {
+ GIT_ROOT = path.join(GIT_ROOT, "../");
}
-if (GIT_ROOT === '/') {
+if (GIT_ROOT === "/") {
// eslint-disable-next-line no-undef
- console.log("not found")
+ console.log("not found");
// eslint-disable-next-line no-undef
process.exit(1);
}
-const GIT_HASH = GIT_ROOT === '/' ? undefined : git_hash()
+const GIT_HASH = GIT_ROOT === "/" ? undefined : git_hash();
-
-let _package = JSON.parse(fs.readFileSync(path.join(BASE, 'package.json')));
+let _package = JSON.parse(fs.readFileSync(path.join(BASE, "package.json")));
function git_hash() {
- const rev = fs.readFileSync(path.join(GIT_ROOT, '.git', 'HEAD')).toString().trim().split(/.*[: ]/).slice(-1)[0];
- if (rev.indexOf('/') === -1) {
+ const rev = fs
+ .readFileSync(path.join(GIT_ROOT, ".git", "HEAD"))
+ .toString()
+ .trim()
+ .split(/.*[: ]/)
+ .slice(-1)[0];
+ if (rev.indexOf("/") === -1) {
return rev;
} else {
- return fs.readFileSync(path.join(GIT_ROOT, '.git', rev)).toString().trim();
+ return fs.readFileSync(path.join(GIT_ROOT, ".git", rev)).toString().trim();
}
}
@@ -50,20 +54,18 @@ const buildConfigBase = {
outdir: "lib",
bundle: true,
minify: false,
- target: [
- 'es6'
- ],
+ target: ["es2021"],
loader: {
- '.key': 'text',
- '.crt': 'text',
- '.html': 'text',
+ ".key": "text",
+ ".crt": "text",
+ ".html": "text",
},
sourcemap: true,
define: {
- '__VERSION__': `"${_package.version}"`,
- '__GIT_HASH__': `"${GIT_HASH}"`,
+ __VERSION__: `"${_package.version}"`,
+ __GIT_HASH__: `"${GIT_HASH}"`,
},
-}
+};
/**
* Build time libraries, under node runtime
@@ -72,36 +74,52 @@ const buildConfigBuild = {
...buildConfigBase,
entryPoints: ["src/index.build.ts"],
outExtension: {
- '.js': '.mjs'
+ ".js": ".mjs",
},
- format: 'esm',
- platform: 'node',
+ format: "esm",
+ platform: "node",
external: ["esbuild"],
// https://github.com/evanw/esbuild/issues/1921
// How to fix "Dynamic require of "os" is not supported"
// esbuild cannot convert external "static" commonjs require statements to static esm imports
- banner: {
+ banner: {
js: `
import { fileURLToPath } from 'url';
import { createRequire as topLevelCreateRequire } from 'module';
const require = topLevelCreateRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
-`
+`,
},
};
/**
* Development libraries, under node runtime
*/
+const buildConfigTesting = {
+ ...buildConfigBase,
+ entryPoints: ["src/index.testing.ts"],
+ outExtension: {
+ ".js": ".mjs",
+ },
+ format: "esm",
+ platform: "browser",
+ external: ["preact", "@gnu-taler/taler-util", "jed", "swr", "axios"],
+ jsxFactory: "h",
+ jsxFragment: "Fragment",
+};
+
+/**
+ * Testing libraries, under node runtime
+ */
const buildConfigNode = {
...buildConfigBase,
entryPoints: ["src/index.node.ts", "src/cli.ts"],
outExtension: {
- '.js': '.cjs'
+ ".js": ".cjs",
},
- format: 'cjs',
- platform: 'node',
+ format: "cjs",
+ platform: "node",
external: ["preact"],
};
@@ -110,26 +128,33 @@ const buildConfigNode = {
*/
const buildConfigBrowser = {
...buildConfigBase,
- entryPoints: ["src/tests/mock.ts", "src/tests/swr.ts", "src/index.browser.ts", "src/live-reload.ts", 'src/stories.tsx'],
+ entryPoints: [
+ "src/tests/mock.ts",
+ "src/tests/swr.ts",
+ "src/index.browser.ts",
+ "src/live-reload.ts",
+ "src/stories.tsx",
+ ],
outExtension: {
- '.js': '.mjs'
+ ".js": ".mjs",
},
- format: 'esm',
- platform: 'browser',
- external: ["preact", "@gnu-taler/taler-util", "jed","swr","axios"],
- jsxFactory: 'h',
- jsxFragment: 'Fragment',
+ format: "esm",
+ platform: "browser",
+ external: ["preact", "@gnu-taler/taler-util", "jed", "swr", "axios"],
+ jsxFactory: "h",
+ jsxFragment: "Fragment",
};
-[buildConfigNode, buildConfigBrowser, buildConfigBuild].forEach((config) => {
- esbuild
- .build(config)
- .catch((e) => {
- // eslint-disable-next-line no-undef
- console.log(e)
- // eslint-disable-next-line no-undef
- process.exit(1)
- });
-
-})
-
+[
+ buildConfigNode,
+ buildConfigBrowser,
+ buildConfigBuild,
+ buildConfigTesting,
+].forEach((config) => {
+ esbuild.build(config).catch((e) => {
+ // eslint-disable-next-line no-undef
+ console.log(e);
+ // eslint-disable-next-line no-undef
+ process.exit(1);
+ });
+});
diff --git a/packages/web-util/package.json b/packages/web-util/package.json
index 77f71c7bb..eda3f0874 100644
--- a/packages/web-util/package.json
+++ b/packages/web-util/package.json
@@ -9,25 +9,21 @@
"license": "AGPL-3.0-or-later",
"private": false,
"exports": {
- "./lib/tests/swr": {
- "types": "./lib/tests/swr.js",
- "default": "./lib/tests/swr.mjs"
- },
- "./lib/tests/mock": {
- "types": "./lib/tests/mock.js",
- "default": "./lib/tests/mock.mjs"
- },
- "./lib/index.browser": {
+ "./browser": {
"types": "./lib/index.browser.js",
"default": "./lib/index.browser.mjs"
},
- "./lib/index.build": {
+ "./build": {
"types": "./lib/index.build.js",
"default": "./lib/index.build.mjs"
},
- "./lib/index.node": {
+ "./node": {
"types": "./lib/index.node.js",
"default": "./lib/index.node.cjs"
+ },
+ "./testing": {
+ "types": "./lib/index.testing.js",
+ "default": "./lib/index.testing.mjs"
}
},
"scripts": {
@@ -42,21 +38,31 @@
"@types/node": "^18.11.17",
"@types/web": "^0.0.82",
"@types/ws": "^8.5.3",
+ "autoprefixer": "^10.4.14",
"axios": "^1.2.2",
"chokidar": "^3.5.3",
"esbuild": "^0.17.7",
"express": "^4.18.2",
+ "postcss": "^8.4.23",
+ "postcss-load-config": "^4.0.1",
"preact": "10.11.3",
"preact-render-to-string": "^5.2.6",
"prettier": "^2.5.1",
"rimraf": "^3.0.2",
+ "sass": "1.56.1",
"swr": "2.0.3",
"tslib": "^2.4.0",
- "sass": "1.56.1",
"typescript": "^4.9.4",
"ws": "7.4.5"
},
"dependencies": {
- "@types/chrome": "0.0.197"
+ "@babel/core": "7.18.9",
+ "@babel/helper-compilation-targets": "7.18.9",
+ "@linaria/babel-preset": "3.0.0-beta.23",
+ "@linaria/core": "3.0.0-beta.22",
+ "@linaria/esbuild": "3.0.0-beta.22",
+ "@linaria/react": "3.0.0-beta.22",
+ "@types/chrome": "0.0.197",
+ "tailwindcss": "^3.3.2"
}
-} \ No newline at end of file
+}
diff --git a/packages/web-util/src/cli.ts b/packages/web-util/src/cli.ts
index b02947f7a..05a22bc8a 100644
--- a/packages/web-util/src/cli.ts
+++ b/packages/web-util/src/cli.ts
@@ -36,7 +36,6 @@ walletCli
return serve({
folder: args.serve.folder || "./dist",
port: args.serve.port || 8000,
- development: args.serve.development,
});
});
diff --git a/packages/web-util/src/index.browser.ts b/packages/web-util/src/index.browser.ts
index c7ba8435f..2a537b405 100644
--- a/packages/web-util/src/index.browser.ts
+++ b/packages/web-util/src/index.browser.ts
@@ -5,5 +5,4 @@ export * from "./utils/http-impl.sw.js";
export * from "./utils/observable.js";
export * from "./context/index.js";
export * from "./components/index.js";
-export * as tests from "./tests/index.js";
export { renderStories, parseGroupImport } from "./stories.js";
diff --git a/packages/web-util/src/index.build.ts b/packages/web-util/src/index.build.ts
index 02e6886ab..19bb7fdfb 100644
--- a/packages/web-util/src/index.build.ts
+++ b/packages/web-util/src/index.build.ts
@@ -1,15 +1,14 @@
-import esbuild from "esbuild";
-import path from "path";
+import esbuild, { PluginBuild } from "esbuild";
+// import linaria from "@linaria/esbuild";
import fs from "fs";
+import path from "path";
+import postcss from "postcss";
import sass from "sass";
-import { PluginBuild } from "esbuild";
+import postcssrc from "postcss-load-config";
// this should give us the current directory where
// the project is being built
const BASE = process.cwd();
-const distProd = path.join(BASE, "dist", "prod");
-const distDev = path.join(BASE, "dist", "dev");
-const sourceDir = path.join(BASE, "src");
const preact = path.join(
BASE,
@@ -32,11 +31,10 @@ const preactCompatPlugin: esbuild.Plugin = {
},
};
-export function getFilesInSource(regex: RegExp): string[] {
- return getFilesInDirectory(sourceDir, regex);
-}
-
-function getFilesInDirectory(startPath: string, regex: RegExp): string[] {
+export function getFilesInDirectory(
+ startPath: string,
+ regex?: RegExp,
+): string[] {
if (!fs.existsSync(startPath)) {
return [];
}
@@ -49,7 +47,7 @@ function getFilesInDirectory(startPath: string, regex: RegExp): string[] {
if (stat.isDirectory()) {
return getFilesInDirectory(filename, regex);
}
- if (regex.test(filename)) {
+ if (!regex || regex.test(filename)) {
return [filename];
}
return [];
@@ -108,7 +106,7 @@ function copyFilesPlugin(files: Array<string>) {
const DEFAULT_SASS_FILTER = /\.(s[ac]ss|css)$/;
-const buildSassPlugin: esbuild.Plugin = {
+const sassPlugin: esbuild.Plugin = {
name: "custom-build-sass",
setup(build) {
build.onLoad({ filter: DEFAULT_SASS_FILTER }, ({ path: file }) => {
@@ -124,7 +122,42 @@ const buildSassPlugin: esbuild.Plugin = {
},
};
-const buildConfig: esbuild.BuildOptions = {
+const postCssPlugin: esbuild.Plugin = {
+ name: "custom-build-postcss",
+ setup(build) {
+ build.onLoad({ filter: DEFAULT_SASS_FILTER }, async ({ path: file }) => {
+ const resolveDir = path.dirname(file);
+ const sourceBuffer = fs.readFileSync(file);
+ const source = sourceBuffer.toString("utf-8");
+ const postCssConfig = await postcssrc();
+ postCssConfig.options.from = file;
+
+ const { css: contents } = await postcss(postCssConfig.plugins).process(
+ source,
+ postCssConfig.options,
+ );
+
+ return {
+ resolveDir,
+ loader: "css",
+ contents,
+ };
+ });
+ },
+};
+
+function linariaPlugin() {
+ // const linariaCssPlugin: esbuild.Plugin = linaria.default({
+ // babelOptions: {
+ // babelrc: false,
+ // configFile: "./babel.config-linaria.json",
+ // },
+ // sourceMap: true,
+ // });
+ // return linariaCssPlugin;
+}
+
+const defaultEsBuildConfig: esbuild.BuildOptions = {
bundle: true,
minify: false,
loader: {
@@ -146,43 +179,71 @@ const buildConfig: esbuild.BuildOptions = {
__VERSION__: `"${_package.version}"`,
__GIT_HASH__: `"${GIT_HASH}"`,
},
- plugins: [
- preactCompatPlugin,
- copyFilesPlugin(["./src/index.html"]),
- buildSassPlugin,
- ],
};
-/**
- * Build sources for prod environment
- */
-export function buildProd(entryPoints: string[]) {
- return esbuild.build({
- ...buildConfig,
- entryPoints,
- outdir: distProd,
- });
+export interface BuildParams {
+ source: {
+ assets: string[];
+ js: string[];
+ };
+ destination: string;
+ css: "sass" | "postcss"; // | "linaria";
+}
+
+export function computeConfig(params: BuildParams) {
+ const plugins: Array<esbuild.Plugin> = [
+ preactCompatPlugin,
+ copyFilesPlugin(params.source.assets),
+ ];
+
+ switch (params.css) {
+ case "sass": {
+ plugins.push(sassPlugin);
+ break;
+ }
+ case "postcss": {
+ plugins.push(postCssPlugin);
+ break;
+ }
+
+ // case "linaria": {
+ // plugins.push(linariaPlugin());
+ // break;
+ // }
+
+ default: {
+ const cssType: never = params.css;
+ throw Error(`not supported: ${cssType}`);
+ }
+ }
+ return {
+ ...defaultEsBuildConfig,
+ entryPoints: params.source.js,
+ outdir: params.destination,
+ plugins,
+ };
}
/**
- * Build sources for dev environment
+ * Build sources for prod environment
*/
-function buildDev(entryPoints: string[]): Promise<esbuild.BuildResult> {
- return esbuild.build({
- ...buildConfig,
- entryPoints,
- outdir: distDev,
- });
+export function build(config: BuildParams) {
+ return esbuild.build(computeConfig(config));
}
+const LIVE_RELOAD_SCRIPT =
+ "./node_modules/@gnu-taler/web-util/lib/live-reload.mjs";
+
/**
* Do startup for development environment
*/
export function initializeDev(
- entryPoints: string[],
+ config: BuildParams,
): () => Promise<esbuild.BuildResult> {
- buildConfig.inject = [
- "./node_modules/@gnu-taler/web-util/lib/live-reload.mjs",
- ];
- return () => buildDev(entryPoints);
+ function buildDevelopment() {
+ const result = computeConfig(config);
+ result.inject = [LIVE_RELOAD_SCRIPT];
+ return esbuild.build(result);
+ }
+ return buildDevelopment;
}
diff --git a/packages/web-util/src/index.testing.ts b/packages/web-util/src/index.testing.ts
new file mode 100644
index 000000000..2349debc5
--- /dev/null
+++ b/packages/web-util/src/index.testing.ts
@@ -0,0 +1,3 @@
+export * from "./tests/hook.js";
+export * from "./tests/swr.js";
+export * from "./tests/mock.js";
diff --git a/packages/web-util/src/index.ts b/packages/web-util/src/index.ts
deleted file mode 100644
index ff8b4c563..000000000
--- a/packages/web-util/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export default {};
diff --git a/packages/web-util/src/serve.ts b/packages/web-util/src/serve.ts
index f37ef90ce..93d8082fe 100644
--- a/packages/web-util/src/serve.ts
+++ b/packages/web-util/src/serve.ts
@@ -21,7 +21,6 @@ const logger = new Logger("serve.ts");
const PATHS = {
WS: "/ws",
- NOTIFY: "/notify",
EXAMPLE: "/examples",
APP: "/app",
};
@@ -30,101 +29,97 @@ export async function serve(opts: {
folder: string;
port: number;
source?: string;
- development?: boolean;
examplesLocationJs?: string;
examplesLocationCss?: string;
- onUpdate?: () => Promise<void>;
+ onSourceUpdate?: () => Promise<void>;
}): Promise<void> {
const app = express();
app.use(PATHS.APP, express.static(opts.folder));
- const servers = [
- http.createServer(app),
- https.createServer(httpServerOptions, app),
- ];
- logger.info(` ${PATHS.APP}: application`);
- logger.info(` ${PATHS.EXAMPLE}: examples`);
- logger.info(` ${PATHS.WS}: websocket`);
- logger.info(` ${PATHS.NOTIFY}: broadcast`);
-
- if (opts.development) {
- const wss = new WebSocket.Server({ noServer: true });
-
- wss.on("connection", function connection(ws) {
- ws.send("welcome");
- });
-
- servers.forEach(function addWSHandler(server) {
- server.on("upgrade", function upgrade(request, socket, head) {
- const { pathname } = parse(request.url || "");
- if (pathname === PATHS.WS) {
- wss.handleUpgrade(request, socket, head, function done(ws) {
- wss.emit("connection", ws, request);
- });
- } else {
- socket.destroy();
- }
- });
- });
- const sendToAllClients = function (data: object): void {
- wss.clients.forEach(function each(client) {
- if (client.readyState === WebSocket.OPEN) {
- client.send(JSON.stringify(data));
- }
- });
- };
- const watchingFolder = opts.source ?? opts.folder;
- logger.info(`watching ${watchingFolder} for change`);
-
- chokidar.watch(watchingFolder).on("change", (path, stats) => {
- logger.info(`changed ${path}`);
-
- if (opts.onUpdate) {
- sendToAllClients({ type: "file-updated-start", data: { path } });
- opts
- .onUpdate()
- .then((result) => {
- sendToAllClients({
- type: "file-updated-done",
- data: { path, result },
- });
- })
- .catch((error) => {
- sendToAllClients({
- type: "file-updated-failed",
- data: { path, error },
- });
- });
+ const httpServer = http.createServer(app);
+ const httpPort = opts.port;
+ const httpsServer = https.createServer(httpServerOptions, app);
+ const httpsPort = opts.port + 1;
+ const servers = [httpServer, httpsServer];
+
+ logger.info(`Dev server. Endpoints:`);
+ logger.info(` ${PATHS.APP}: where root application can be tested`);
+ logger.info(` ${PATHS.EXAMPLE}: where examples can be found and browse`);
+ logger.info(` ${PATHS.WS}: websocket for live reloading`);
+
+ const wss = new WebSocket.Server({ noServer: true });
+
+ wss.on("connection", function connection(ws) {
+ ws.send("welcome");
+ });
+
+ servers.forEach(function addWSHandler(server) {
+ server.on("upgrade", function upgrade(request, socket, head) {
+ const { pathname } = parse(request.url || "");
+ if (pathname === PATHS.WS) {
+ wss.handleUpgrade(request, socket, head, function done(ws) {
+ wss.emit("connection", ws, request);
+ });
} else {
- sendToAllClients({ type: "file-change", data: { path } });
+ socket.destroy();
}
});
+ });
- if (opts.onUpdate) opts.onUpdate();
-
- app.get(PATHS.EXAMPLE, function (req: any, res: any) {
- res.set("Content-Type", "text/html");
- res.send(
- storiesHtml
- .replace(
- "__EXAMPLES_JS_FILE_LOCATION__",
- opts.examplesLocationJs ?? `.${PATHS.APP}/stories.js`,
- )
- .replace(
- "__EXAMPLES_CSS_FILE_LOCATION__",
- opts.examplesLocationCss ?? `.${PATHS.APP}/stories.css`,
- ),
- );
- });
-
- app.get(PATHS.NOTIFY, function (req: any, res: any) {
- res.send("ok");
- });
-
- servers.forEach(function startServer(server, index) {
- logger.info(`serving ${opts.folder} on ${opts.port + index}`);
- server.listen(opts.port + index);
+ const sendToAllClients = function (data: object): void {
+ wss.clients.forEach(function each(client) {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(data));
+ }
});
- }
+ };
+ const watchingFolder = opts.source ?? opts.folder;
+ logger.info(`watching ${watchingFolder} for changes`);
+
+ chokidar.watch(watchingFolder).on("change", (path, stats) => {
+ logger.info(`changed: ${path}`);
+
+ if (opts.onSourceUpdate) {
+ sendToAllClients({ type: "file-updated-start", data: { path } });
+ opts
+ .onSourceUpdate()
+ .then((result) => {
+ sendToAllClients({
+ type: "file-updated-done",
+ data: { path, result },
+ });
+ })
+ .catch((error) => {
+ sendToAllClients({
+ type: "file-updated-failed",
+ data: { path, error },
+ });
+ });
+ } else {
+ sendToAllClients({ type: "file-change", data: { path } });
+ }
+ });
+
+ if (opts.onSourceUpdate) opts.onSourceUpdate();
+
+ app.get(PATHS.EXAMPLE, function (req: any, res: any) {
+ res.set("Content-Type", "text/html");
+ res.send(
+ storiesHtml
+ .replace(
+ "__EXAMPLES_JS_FILE_LOCATION__",
+ opts.examplesLocationJs ?? `.${PATHS.APP}/stories.js`,
+ )
+ .replace(
+ "__EXAMPLES_CSS_FILE_LOCATION__",
+ opts.examplesLocationCss ?? `.${PATHS.APP}/stories.css`,
+ ),
+ );
+ });
+
+ logger.info(`Serving ${opts.folder} on ${httpPort}: plain HTTP`);
+ httpServer.listen(httpPort);
+ logger.info(`Serving ${opts.folder} on ${httpsPort}: HTTP + TLS`);
+ httpsServer.listen(httpsPort);
}
diff --git a/packages/web-util/src/tests/index.ts b/packages/web-util/src/tests/index.ts
deleted file mode 100644
index 2c0d929f8..000000000
--- a/packages/web-util/src/tests/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./hook.js";
-// export * from "./axios.js"