feat: frontend PWA scaffolding with React and Tailwind

This commit is contained in:
Daniel Bedeleanu
2026-04-10 14:05:50 +03:00
parent 373652e8b8
commit 7f8b24aabb
33622 changed files with 4317382 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
import type { Options as SWCOptions } from '@swc/core';
export declare function registerHook(swcOptions: SWCOptions): void;
export declare function deregisterHook(): void;
export declare function requireFromString(code: string, filename: string): any;

View File

@@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
deregisterHook: null,
registerHook: null,
requireFromString: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
deregisterHook: function() {
return deregisterHook;
},
registerHook: function() {
return registerHook;
},
requireFromString: function() {
return requireFromString;
}
});
const _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
const _nodefs = require("node:fs");
const _nodepath = require("node:path");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const oldJSHook = require.extensions['.js'];
const extensions = [
'.ts',
'.cts',
'.mts',
'.cjs',
'.mjs'
];
function registerHook(swcOptions) {
// lazy require swc since it loads React before even setting NODE_ENV
// resulting loading Development React on Production
const { transformSync } = require('../swc');
require.extensions['.js'] = function(mod, oldFilename) {
try {
return oldJSHook(mod, oldFilename);
} catch (error) {
if (error.code !== 'ERR_REQUIRE_ESM') {
throw error;
}
// calling oldJSHook throws ERR_REQUIRE_ESM, so run _compile manually
// TODO: investigate if we can remove readFileSync
const content = (0, _nodefs.readFileSync)(oldFilename, 'utf8');
const { code } = transformSync(content, swcOptions);
mod._compile(code, oldFilename);
}
};
for (const ext of extensions){
const oldHook = require.extensions[ext] ?? oldJSHook;
require.extensions[ext] = function(mod, oldFilename) {
const _compile = mod._compile;
mod._compile = function(code, filename) {
const swc = transformSync(code, swcOptions);
return _compile.call(this, swc.code, filename);
};
return oldHook(mod, oldFilename);
};
}
}
function deregisterHook() {
require.extensions['.js'] = oldJSHook;
extensions.forEach((ext)=>delete require.extensions[ext]);
}
function requireFromString(code, filename) {
const paths = _nodemodule.default._nodeModulePaths((0, _nodepath.dirname)(filename));
const m = new _nodemodule.default(filename, module.parent);
m.paths = paths;
m._compile(code, filename);
return m.exports;
}
//# sourceMappingURL=require-hook.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/next-config-ts/require-hook.ts"],"sourcesContent":["import type { Options as SWCOptions } from '@swc/core'\nimport Module from 'node:module'\nimport { readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nconst oldJSHook = require.extensions['.js']\nconst extensions = ['.ts', '.cts', '.mts', '.cjs', '.mjs']\n\nexport function registerHook(swcOptions: SWCOptions) {\n // lazy require swc since it loads React before even setting NODE_ENV\n // resulting loading Development React on Production\n const { transformSync } = require('../swc') as typeof import('../swc')\n\n require.extensions['.js'] = function (mod: any, oldFilename) {\n try {\n return oldJSHook(mod, oldFilename)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ERR_REQUIRE_ESM') {\n throw error\n }\n\n // calling oldJSHook throws ERR_REQUIRE_ESM, so run _compile manually\n // TODO: investigate if we can remove readFileSync\n const content = readFileSync(oldFilename, 'utf8')\n const { code } = transformSync(content, swcOptions)\n mod._compile(code, oldFilename)\n }\n }\n\n for (const ext of extensions) {\n const oldHook = require.extensions[ext] ?? oldJSHook\n require.extensions[ext] = function (mod: any, oldFilename) {\n const _compile = mod._compile\n\n mod._compile = function (code: string, filename: string) {\n const swc = transformSync(code, swcOptions)\n return _compile.call(this, swc.code, filename)\n }\n\n return oldHook(mod, oldFilename)\n }\n }\n}\n\nexport function deregisterHook() {\n require.extensions['.js'] = oldJSHook\n extensions.forEach((ext) => delete require.extensions[ext])\n}\n\nexport function requireFromString(code: string, filename: string) {\n const paths = (Module as any)._nodeModulePaths(dirname(filename))\n const m = new Module(filename, module.parent!) as any\n m.paths = paths\n m._compile(code, filename)\n return m.exports\n}\n"],"names":["deregisterHook","registerHook","requireFromString","oldJSHook","require","extensions","swcOptions","transformSync","mod","oldFilename","error","code","content","readFileSync","_compile","ext","oldHook","filename","swc","call","forEach","paths","Module","_nodeModulePaths","dirname","m","module","parent","exports"],"mappings":";;;;;;;;;;;;;;;;IA4CgBA,cAAc;eAAdA;;IApCAC,YAAY;eAAZA;;IAyCAC,iBAAiB;eAAjBA;;;mEAhDG;wBACU;0BACL;;;;;;AAExB,MAAMC,YAAYC,QAAQC,UAAU,CAAC,MAAM;AAC3C,MAAMA,aAAa;IAAC;IAAO;IAAQ;IAAQ;IAAQ;CAAO;AAEnD,SAASJ,aAAaK,UAAsB;IACjD,qEAAqE;IACrE,oDAAoD;IACpD,MAAM,EAAEC,aAAa,EAAE,GAAGH,QAAQ;IAElCA,QAAQC,UAAU,CAAC,MAAM,GAAG,SAAUG,GAAQ,EAAEC,WAAW;QACzD,IAAI;YACF,OAAON,UAAUK,KAAKC;QACxB,EAAE,OAAOC,OAAO;YACd,IAAI,AAACA,MAAgCC,IAAI,KAAK,mBAAmB;gBAC/D,MAAMD;YACR;YAEA,qEAAqE;YACrE,kDAAkD;YAClD,MAAME,UAAUC,IAAAA,oBAAY,EAACJ,aAAa;YAC1C,MAAM,EAAEE,IAAI,EAAE,GAAGJ,cAAcK,SAASN;YACxCE,IAAIM,QAAQ,CAACH,MAAMF;QACrB;IACF;IAEA,KAAK,MAAMM,OAAOV,WAAY;QAC5B,MAAMW,UAAUZ,QAAQC,UAAU,CAACU,IAAI,IAAIZ;QAC3CC,QAAQC,UAAU,CAACU,IAAI,GAAG,SAAUP,GAAQ,EAAEC,WAAW;YACvD,MAAMK,WAAWN,IAAIM,QAAQ;YAE7BN,IAAIM,QAAQ,GAAG,SAAUH,IAAY,EAAEM,QAAgB;gBACrD,MAAMC,MAAMX,cAAcI,MAAML;gBAChC,OAAOQ,SAASK,IAAI,CAAC,IAAI,EAAED,IAAIP,IAAI,EAAEM;YACvC;YAEA,OAAOD,QAAQR,KAAKC;QACtB;IACF;AACF;AAEO,SAAST;IACdI,QAAQC,UAAU,CAAC,MAAM,GAAGF;IAC5BE,WAAWe,OAAO,CAAC,CAACL,MAAQ,OAAOX,QAAQC,UAAU,CAACU,IAAI;AAC5D;AAEO,SAASb,kBAAkBS,IAAY,EAAEM,QAAgB;IAC9D,MAAMI,QAAQ,AAACC,mBAAM,CAASC,gBAAgB,CAACC,IAAAA,iBAAO,EAACP;IACvD,MAAMQ,IAAI,IAAIH,mBAAM,CAACL,UAAUS,OAAOC,MAAM;IAC5CF,EAAEJ,KAAK,GAAGA;IACVI,EAAEX,QAAQ,CAACH,MAAMM;IACjB,OAAOQ,EAAEG,OAAO;AAClB","ignoreList":[0]}

View File

@@ -0,0 +1,5 @@
export declare function transpileConfig({ nextConfigPath, configFileName, cwd, }: {
nextConfigPath: string;
configFileName: string;
cwd: string;
}): Promise<any>;

View File

@@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "transpileConfig", {
enumerable: true,
get: function() {
return transpileConfig;
}
});
const _nodepath = require("node:path");
const _promises = require("node:fs/promises");
const _requirehook = require("./require-hook");
const _log = require("../output/log");
const _installdependencies = require("../../lib/install-dependencies");
function resolveSWCOptions(cwd, compilerOptions) {
const resolvedBaseUrl = (0, _nodepath.resolve)(cwd, compilerOptions.baseUrl ?? '.');
return {
jsc: {
target: 'es5',
parser: {
syntax: 'typescript'
},
paths: compilerOptions.paths,
baseUrl: resolvedBaseUrl
},
module: {
type: 'commonjs'
},
isModule: 'unknown'
};
}
// Ported from next/src/lib/verify-typescript-setup.ts
// Although this overlaps with the later `verifyTypeScriptSetup`,
// it is acceptable since the time difference in the worst case is trivial,
// as we are only preparing to install the dependencies once more.
async function verifyTypeScriptSetup(cwd, configFileName) {
try {
// Quick module check.
require.resolve('typescript', {
paths: [
cwd
]
});
} catch (error) {
if (error && typeof error === 'object' && 'code' in error && error.code === 'MODULE_NOT_FOUND') {
(0, _log.warn)(`Installing TypeScript as it was not found while loading "${configFileName}".`);
await (0, _installdependencies.installDependencies)(cwd, [
{
pkg: 'typescript'
}
], true).catch((err)=>{
if (err && typeof err === 'object' && 'command' in err) {
console.error(`Failed to install TypeScript, please install it manually to continue:\n` + err.command + '\n');
}
throw err;
});
}
}
}
async function getTsConfig(cwd) {
const ts = require(require.resolve('typescript', {
paths: [
cwd
]
}));
// NOTE: This doesn't fully cover the edge case for setting
// "typescript.tsconfigPath" in next config which is currently
// a restriction.
const tsConfigPath = ts.findConfigFile(cwd, ts.sys.fileExists, 'tsconfig.json');
if (!tsConfigPath) {
// It is ok to not return ts.getDefaultCompilerOptions() because
// we are only lookfing for paths and baseUrl from tsConfig.
return {};
}
const configFile = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
const parsedCommandLine = ts.parseJsonConfigFileContent(configFile.config, ts.sys, cwd);
return parsedCommandLine.options;
}
async function transpileConfig({ nextConfigPath, configFileName, cwd }) {
let hasRequire = false;
try {
// Ensure TypeScript is installed to use the API.
await verifyTypeScriptSetup(cwd, configFileName);
const compilerOptions = await getTsConfig(cwd);
const swcOptions = resolveSWCOptions(cwd, compilerOptions);
const nextConfigString = await (0, _promises.readFile)(nextConfigPath, 'utf8');
// lazy require swc since it loads React before even setting NODE_ENV
// resulting loading Development React on Production
const { transform } = require('../swc');
const { code } = await transform(nextConfigString, swcOptions);
// register require hook only if require exists
if (code.includes('require(')) {
(0, _requirehook.registerHook)(swcOptions);
hasRequire = true;
}
// filename & extension don't matter here
return (0, _requirehook.requireFromString)(code, (0, _nodepath.resolve)(cwd, 'next.config.compiled.js'));
} catch (error) {
throw error;
} finally{
if (hasRequire) {
(0, _requirehook.deregisterHook)();
}
}
}
//# sourceMappingURL=transpile-config.js.map

File diff suppressed because one or more lines are too long