add postcss, fix export names

This commit is contained in:
Sebastian 2023-05-05 08:34:21 -03:00
parent 5e1f450a20
commit 6340cc5454
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
10 changed files with 1967 additions and 421 deletions

View File

@ -15,34 +15,38 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import esbuild from 'esbuild' import esbuild from "esbuild";
import path from "path" import path from "path";
import fs from "fs" import fs from "fs";
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const BASE = process.cwd() const BASE = process.cwd();
let GIT_ROOT = BASE let GIT_ROOT = BASE;
while (!fs.existsSync(path.join(GIT_ROOT, '.git')) && GIT_ROOT !== '/') { while (!fs.existsSync(path.join(GIT_ROOT, ".git")) && GIT_ROOT !== "/") {
GIT_ROOT = path.join(GIT_ROOT, '../') GIT_ROOT = path.join(GIT_ROOT, "../");
} }
if (GIT_ROOT === '/') { if (GIT_ROOT === "/") {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
console.log("not found") console.log("not found");
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
process.exit(1); 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() { function git_hash() {
const rev = fs.readFileSync(path.join(GIT_ROOT, '.git', 'HEAD')).toString().trim().split(/.*[: ]/).slice(-1)[0]; const rev = fs
if (rev.indexOf('/') === -1) { .readFileSync(path.join(GIT_ROOT, ".git", "HEAD"))
.toString()
.trim()
.split(/.*[: ]/)
.slice(-1)[0];
if (rev.indexOf("/") === -1) {
return rev; return rev;
} else { } 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", outdir: "lib",
bundle: true, bundle: true,
minify: false, minify: false,
target: [ target: ["es2021"],
'es6'
],
loader: { loader: {
'.key': 'text', ".key": "text",
'.crt': 'text', ".crt": "text",
'.html': 'text', ".html": "text",
}, },
sourcemap: true, sourcemap: true,
define: { define: {
'__VERSION__': `"${_package.version}"`, __VERSION__: `"${_package.version}"`,
'__GIT_HASH__': `"${GIT_HASH}"`, __GIT_HASH__: `"${GIT_HASH}"`,
}, },
} };
/** /**
* Build time libraries, under node runtime * Build time libraries, under node runtime
@ -72,10 +74,10 @@ const buildConfigBuild = {
...buildConfigBase, ...buildConfigBase,
entryPoints: ["src/index.build.ts"], entryPoints: ["src/index.build.ts"],
outExtension: { outExtension: {
'.js': '.mjs' ".js": ".mjs",
}, },
format: 'esm', format: "esm",
platform: 'node', platform: "node",
external: ["esbuild"], external: ["esbuild"],
// https://github.com/evanw/esbuild/issues/1921 // https://github.com/evanw/esbuild/issues/1921
// How to fix "Dynamic require of "os" is not supported" // How to fix "Dynamic require of "os" is not supported"
@ -87,21 +89,37 @@ const buildConfigBuild = {
const require = topLevelCreateRequire(import.meta.url); const require = topLevelCreateRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
` `,
}, },
}; };
/** /**
* Development libraries, under node runtime * 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 = { const buildConfigNode = {
...buildConfigBase, ...buildConfigBase,
entryPoints: ["src/index.node.ts", "src/cli.ts"], entryPoints: ["src/index.node.ts", "src/cli.ts"],
outExtension: { outExtension: {
'.js': '.cjs' ".js": ".cjs",
}, },
format: 'cjs', format: "cjs",
platform: 'node', platform: "node",
external: ["preact"], external: ["preact"],
}; };
@ -110,26 +128,33 @@ const buildConfigNode = {
*/ */
const buildConfigBrowser = { const buildConfigBrowser = {
...buildConfigBase, ...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: { outExtension: {
'.js': '.mjs' ".js": ".mjs",
}, },
format: 'esm', format: "esm",
platform: 'browser', platform: "browser",
external: ["preact", "@gnu-taler/taler-util", "jed", "swr", "axios"], external: ["preact", "@gnu-taler/taler-util", "jed", "swr", "axios"],
jsxFactory: 'h', jsxFactory: "h",
jsxFragment: 'Fragment', jsxFragment: "Fragment",
}; };
[buildConfigNode, buildConfigBrowser, buildConfigBuild].forEach((config) => { [
esbuild buildConfigNode,
.build(config) buildConfigBrowser,
.catch((e) => { buildConfigBuild,
buildConfigTesting,
].forEach((config) => {
esbuild.build(config).catch((e) => {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
console.log(e) console.log(e);
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
process.exit(1) process.exit(1);
});
}); });
})

View File

@ -9,25 +9,21 @@
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"private": false, "private": false,
"exports": { "exports": {
"./lib/tests/swr": { "./browser": {
"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": {
"types": "./lib/index.browser.js", "types": "./lib/index.browser.js",
"default": "./lib/index.browser.mjs" "default": "./lib/index.browser.mjs"
}, },
"./lib/index.build": { "./build": {
"types": "./lib/index.build.js", "types": "./lib/index.build.js",
"default": "./lib/index.build.mjs" "default": "./lib/index.build.mjs"
}, },
"./lib/index.node": { "./node": {
"types": "./lib/index.node.js", "types": "./lib/index.node.js",
"default": "./lib/index.node.cjs" "default": "./lib/index.node.cjs"
},
"./testing": {
"types": "./lib/index.testing.js",
"default": "./lib/index.testing.mjs"
} }
}, },
"scripts": { "scripts": {
@ -42,21 +38,31 @@
"@types/node": "^18.11.17", "@types/node": "^18.11.17",
"@types/web": "^0.0.82", "@types/web": "^0.0.82",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"autoprefixer": "^10.4.14",
"axios": "^1.2.2", "axios": "^1.2.2",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"esbuild": "^0.17.7", "esbuild": "^0.17.7",
"express": "^4.18.2", "express": "^4.18.2",
"postcss": "^8.4.23",
"postcss-load-config": "^4.0.1",
"preact": "10.11.3", "preact": "10.11.3",
"preact-render-to-string": "^5.2.6", "preact-render-to-string": "^5.2.6",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "1.56.1",
"swr": "2.0.3", "swr": "2.0.3",
"tslib": "^2.4.0", "tslib": "^2.4.0",
"sass": "1.56.1",
"typescript": "^4.9.4", "typescript": "^4.9.4",
"ws": "7.4.5" "ws": "7.4.5"
}, },
"dependencies": { "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"
} }
} }

View File

@ -36,7 +36,6 @@ walletCli
return serve({ return serve({
folder: args.serve.folder || "./dist", folder: args.serve.folder || "./dist",
port: args.serve.port || 8000, port: args.serve.port || 8000,
development: args.serve.development,
}); });
}); });

View File

@ -5,5 +5,4 @@ export * from "./utils/http-impl.sw.js";
export * from "./utils/observable.js"; export * from "./utils/observable.js";
export * from "./context/index.js"; export * from "./context/index.js";
export * from "./components/index.js"; export * from "./components/index.js";
export * as tests from "./tests/index.js";
export { renderStories, parseGroupImport } from "./stories.js"; export { renderStories, parseGroupImport } from "./stories.js";

View File

@ -1,15 +1,14 @@
import esbuild from "esbuild"; import esbuild, { PluginBuild } from "esbuild";
import path from "path"; // import linaria from "@linaria/esbuild";
import fs from "fs"; import fs from "fs";
import path from "path";
import postcss from "postcss";
import sass from "sass"; import sass from "sass";
import { PluginBuild } from "esbuild"; import postcssrc from "postcss-load-config";
// this should give us the current directory where // this should give us the current directory where
// the project is being built // the project is being built
const BASE = process.cwd(); 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( const preact = path.join(
BASE, BASE,
@ -32,11 +31,10 @@ const preactCompatPlugin: esbuild.Plugin = {
}, },
}; };
export function getFilesInSource(regex: RegExp): string[] { export function getFilesInDirectory(
return getFilesInDirectory(sourceDir, regex); startPath: string,
} regex?: RegExp,
): string[] {
function getFilesInDirectory(startPath: string, regex: RegExp): string[] {
if (!fs.existsSync(startPath)) { if (!fs.existsSync(startPath)) {
return []; return [];
} }
@ -49,7 +47,7 @@ function getFilesInDirectory(startPath: string, regex: RegExp): string[] {
if (stat.isDirectory()) { if (stat.isDirectory()) {
return getFilesInDirectory(filename, regex); return getFilesInDirectory(filename, regex);
} }
if (regex.test(filename)) { if (!regex || regex.test(filename)) {
return [filename]; return [filename];
} }
return []; return [];
@ -108,7 +106,7 @@ function copyFilesPlugin(files: Array<string>) {
const DEFAULT_SASS_FILTER = /\.(s[ac]ss|css)$/; const DEFAULT_SASS_FILTER = /\.(s[ac]ss|css)$/;
const buildSassPlugin: esbuild.Plugin = { const sassPlugin: esbuild.Plugin = {
name: "custom-build-sass", name: "custom-build-sass",
setup(build) { setup(build) {
build.onLoad({ filter: DEFAULT_SASS_FILTER }, ({ path: file }) => { 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, bundle: true,
minify: false, minify: false,
loader: { loader: {
@ -146,43 +179,71 @@ const buildConfig: esbuild.BuildOptions = {
__VERSION__: `"${_package.version}"`, __VERSION__: `"${_package.version}"`,
__GIT_HASH__: `"${GIT_HASH}"`, __GIT_HASH__: `"${GIT_HASH}"`,
}, },
plugins: [
preactCompatPlugin,
copyFilesPlugin(["./src/index.html"]),
buildSassPlugin,
],
}; };
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 prod environment * Build sources for prod environment
*/ */
export function buildProd(entryPoints: string[]) { export function build(config: BuildParams) {
return esbuild.build({ return esbuild.build(computeConfig(config));
...buildConfig,
entryPoints,
outdir: distProd,
});
} }
/** const LIVE_RELOAD_SCRIPT =
* Build sources for dev environment "./node_modules/@gnu-taler/web-util/lib/live-reload.mjs";
*/
function buildDev(entryPoints: string[]): Promise<esbuild.BuildResult> {
return esbuild.build({
...buildConfig,
entryPoints,
outdir: distDev,
});
}
/** /**
* Do startup for development environment * Do startup for development environment
*/ */
export function initializeDev( export function initializeDev(
entryPoints: string[], config: BuildParams,
): () => Promise<esbuild.BuildResult> { ): () => Promise<esbuild.BuildResult> {
buildConfig.inject = [ function buildDevelopment() {
"./node_modules/@gnu-taler/web-util/lib/live-reload.mjs", const result = computeConfig(config);
]; result.inject = [LIVE_RELOAD_SCRIPT];
return () => buildDev(entryPoints); return esbuild.build(result);
}
return buildDevelopment;
} }

View File

@ -0,0 +1,3 @@
export * from "./tests/hook.js";
export * from "./tests/swr.js";
export * from "./tests/mock.js";

View File

@ -1 +0,0 @@
export default {};

View File

@ -21,7 +21,6 @@ const logger = new Logger("serve.ts");
const PATHS = { const PATHS = {
WS: "/ws", WS: "/ws",
NOTIFY: "/notify",
EXAMPLE: "/examples", EXAMPLE: "/examples",
APP: "/app", APP: "/app",
}; };
@ -30,24 +29,25 @@ export async function serve(opts: {
folder: string; folder: string;
port: number; port: number;
source?: string; source?: string;
development?: boolean;
examplesLocationJs?: string; examplesLocationJs?: string;
examplesLocationCss?: string; examplesLocationCss?: string;
onUpdate?: () => Promise<void>; onSourceUpdate?: () => Promise<void>;
}): Promise<void> { }): Promise<void> {
const app = express(); const app = express();
app.use(PATHS.APP, express.static(opts.folder)); 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 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 }); const wss = new WebSocket.Server({ noServer: true });
wss.on("connection", function connection(ws) { wss.on("connection", function connection(ws) {
@ -75,15 +75,15 @@ export async function serve(opts: {
}); });
}; };
const watchingFolder = opts.source ?? opts.folder; const watchingFolder = opts.source ?? opts.folder;
logger.info(`watching ${watchingFolder} for change`); logger.info(`watching ${watchingFolder} for changes`);
chokidar.watch(watchingFolder).on("change", (path, stats) => { chokidar.watch(watchingFolder).on("change", (path, stats) => {
logger.info(`changed ${path}`); logger.info(`changed: ${path}`);
if (opts.onUpdate) { if (opts.onSourceUpdate) {
sendToAllClients({ type: "file-updated-start", data: { path } }); sendToAllClients({ type: "file-updated-start", data: { path } });
opts opts
.onUpdate() .onSourceUpdate()
.then((result) => { .then((result) => {
sendToAllClients({ sendToAllClients({
type: "file-updated-done", type: "file-updated-done",
@ -101,7 +101,7 @@ export async function serve(opts: {
} }
}); });
if (opts.onUpdate) opts.onUpdate(); if (opts.onSourceUpdate) opts.onSourceUpdate();
app.get(PATHS.EXAMPLE, function (req: any, res: any) { app.get(PATHS.EXAMPLE, function (req: any, res: any) {
res.set("Content-Type", "text/html"); res.set("Content-Type", "text/html");
@ -118,13 +118,8 @@ export async function serve(opts: {
); );
}); });
app.get(PATHS.NOTIFY, function (req: any, res: any) { logger.info(`Serving ${opts.folder} on ${httpPort}: plain HTTP`);
res.send("ok"); httpServer.listen(httpPort);
}); logger.info(`Serving ${opts.folder} on ${httpsPort}: HTTP + TLS`);
httpsServer.listen(httpsPort);
servers.forEach(function startServer(server, index) {
logger.info(`serving ${opts.folder} on ${opts.port + index}`);
server.listen(opts.port + index);
});
}
} }

View File

@ -1,2 +0,0 @@
export * from "./hook.js";
// export * from "./axios.js"

File diff suppressed because it is too large Load Diff