tmp
This commit is contained in:
8
bin/.eslintrc.js
Normal file
8
bin/.eslintrc.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
},
|
||||
};
|
||||
75
bin/build.js
Normal file
75
bin/build.js
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/node
|
||||
console.time('Bundling time');
|
||||
const {build} = require('vite');
|
||||
const {join} = require('path');
|
||||
|
||||
/** @type 'production' | 'development' | 'test' */
|
||||
const mode = process.env.MODE || 'production';
|
||||
|
||||
const configs = [
|
||||
join(process.cwd(), 'config/main.vite.js'),
|
||||
join(process.cwd(), 'config/preload.vite.js'),
|
||||
join(process.cwd(), 'config/renderer.vite.js'),
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Run `vite build` for config file
|
||||
* @param {string} configFile
|
||||
* @return {Promise<RollupOutput | RollupOutput[]>}
|
||||
*/
|
||||
const buildByConfig = (configFile) => build({configFile, mode});
|
||||
|
||||
/**
|
||||
* Creates a separate package.json in which:
|
||||
* - The version number is set based on the current date in the format yy.mm.dd
|
||||
* - Removed all dependencies except those marked as "external".
|
||||
* @see /config/external-packages.js
|
||||
*
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
const generatePackageJson = () => {
|
||||
// Get project package.json
|
||||
const packageJson = require(join(process.cwd(), 'package.json'));
|
||||
|
||||
// Cleanup
|
||||
delete packageJson.scripts;
|
||||
|
||||
{
|
||||
// Remove all bundled dependencies
|
||||
// Keep only `external` dependencies
|
||||
delete packageJson.devDependencies;
|
||||
const {default: external} = require('../config/external-packages');
|
||||
for (const type of ['dependencies', 'optionalDependencies']) {
|
||||
if (packageJson[type] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(packageJson[type])) {
|
||||
if (!external.includes(key)) {
|
||||
delete packageJson[type][key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Set version based on current date in yy.mm.dd format
|
||||
// The year is calculated on the principle of a `getFullYear() - 2000`, so that in 2120 the version was `120` and not `20` 😅
|
||||
const now = new Date;
|
||||
packageJson.version = `${now.getFullYear() - 2000}.${now.getMonth() + 1}.${now.getDate()}`;
|
||||
}
|
||||
|
||||
// Create new package.json
|
||||
const {writeFile} = require('fs/promises');
|
||||
return writeFile(join(process.cwd(), 'dist/source/package.json'), JSON.stringify(packageJson));
|
||||
};
|
||||
|
||||
|
||||
Promise.all(configs.map(buildByConfig))
|
||||
.then(generatePackageJson)
|
||||
.then(() => console.timeEnd('Bundling time'))
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
36
bin/buildEnvTypes.js
Normal file
36
bin/buildEnvTypes.js
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {resolveConfig} = require('vite');
|
||||
const {writeFileSync, mkdirSync, existsSync} = require('fs');
|
||||
const {resolve, dirname} = require('path');
|
||||
|
||||
/**
|
||||
* @param {string[]} modes
|
||||
* @param {string} filePath
|
||||
*/
|
||||
async function buildMode(modes, filePath) {
|
||||
const interfaces = await Promise.all(modes.map(async mode => {
|
||||
const modeInterfaceName = `${mode}Env`;
|
||||
const {env} = await resolveConfig({mode, configFile: resolve(process.cwd(), 'config/main.vite.js')}, 'build');
|
||||
|
||||
const interfaceDeclaration = `interface ${modeInterfaceName} ${JSON.stringify(env)}`;
|
||||
|
||||
return {modeInterfaceName, interfaceDeclaration};
|
||||
}));
|
||||
|
||||
const interfacesDeclarations = interfaces.map(({interfaceDeclaration}) => interfaceDeclaration).join('\n');
|
||||
const type = interfaces.map(({modeInterfaceName}) => modeInterfaceName).join(' | ');
|
||||
|
||||
const dir = dirname(filePath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir);
|
||||
}
|
||||
|
||||
writeFileSync(filePath, `${interfacesDeclarations}\ntype ImportMetaEnv = ${type}\n`, {encoding: 'utf-8', flag: 'w'});
|
||||
}
|
||||
|
||||
buildMode(['production', 'development', 'test'], resolve(process.cwd(), './types/env.d.ts'))
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
88
bin/request-electron-deps.js
Normal file
88
bin/request-electron-deps.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Temporally
|
||||
* @deprecated
|
||||
* @see https://github.com/electron/electron/issues/28006
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef Vendors
|
||||
* @type {{
|
||||
* node: string,
|
||||
* v8: string,
|
||||
* uv: string,
|
||||
* zlib: string,
|
||||
* brotli: string,
|
||||
* ares: string,
|
||||
* modules: string,
|
||||
* nghttp2: string,
|
||||
* napi: string,
|
||||
* llhttp: string,
|
||||
* http_parser: string,
|
||||
* openssl: string,
|
||||
* cldr: string,
|
||||
* icu: string,
|
||||
* tz: string,
|
||||
* unicode: string,
|
||||
* electron: string,
|
||||
* }}
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {null | Vendors}
|
||||
*/
|
||||
let runtimeCache = null;
|
||||
|
||||
/**
|
||||
* Returns information about dependencies of the specified version of the electron
|
||||
* @return {Vendors}
|
||||
*
|
||||
* @see https://electronjs.org/headers/index.json
|
||||
*/
|
||||
const loadDeps = () => {
|
||||
const stringifiedDeps = require('child_process').execSync(
|
||||
'electron -p JSON.stringify(process.versions)',
|
||||
{
|
||||
encoding: 'utf-8',
|
||||
env: {
|
||||
ELECTRON_RUN_AS_NODE: '1',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return JSON.parse(stringifiedDeps);
|
||||
};
|
||||
|
||||
const saveToCache = (dist) => {
|
||||
runtimeCache = dist;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {null|Vendors}
|
||||
*/
|
||||
const loadFromCache = () => runtimeCache;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {Vendors}
|
||||
*/
|
||||
const getElectronDist = () => {
|
||||
let dist = loadFromCache();
|
||||
|
||||
if (dist) {
|
||||
return dist;
|
||||
}
|
||||
|
||||
dist = loadDeps();
|
||||
|
||||
saveToCache(dist);
|
||||
|
||||
return dist;
|
||||
};
|
||||
|
||||
const {node, modules} = getElectronDist();
|
||||
|
||||
module.exports.node = node;
|
||||
module.exports.chrome = modules;//.split('.')[0];
|
||||
142
bin/watch.js
Normal file
142
bin/watch.js
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/node
|
||||
|
||||
// TODO:
|
||||
// - Disable dependency optimization during development.
|
||||
// - Need more tests
|
||||
// - Refactoring
|
||||
|
||||
const slash = require('slash');
|
||||
const chokidar = require('chokidar');
|
||||
const {createServer, build, normalizePath} = require('vite');
|
||||
const electronPath = require('electron');
|
||||
const {spawn} = require('child_process');
|
||||
const {join, relative} = require('path');
|
||||
|
||||
const mode = process.env.MODE || 'development';
|
||||
|
||||
const TIMEOUT = 500;
|
||||
|
||||
function debounce(f, ms) {
|
||||
let isCoolDown = false;
|
||||
return function () {
|
||||
if (isCoolDown) return;
|
||||
f.apply(this, arguments);
|
||||
isCoolDown = true;
|
||||
setTimeout(() => isCoolDown = false, ms);
|
||||
};
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
||||
// Create Vite dev server
|
||||
const viteDevServer = await createServer({
|
||||
mode,
|
||||
configFile: join(process.cwd(), 'config/renderer.vite.js'),
|
||||
});
|
||||
|
||||
await viteDevServer.listen();
|
||||
|
||||
|
||||
// Determining the current URL of the server. It depend on /config/renderer.vite.js
|
||||
// Write a value to an environment variable to pass it to the main process.
|
||||
{
|
||||
const protocol = `http${viteDevServer.config.server.https ? 's' : ''}:`;
|
||||
const host = viteDevServer.config.server.host || 'localhost';
|
||||
const port = viteDevServer.config.server.port; // Vite searches for and occupies the first free port: 3000, 3001, 3002 and so on
|
||||
const path = '/';
|
||||
process.env.VITE_DEV_SERVER_URL = `${protocol}//${host}:${port}${path}`;
|
||||
}
|
||||
|
||||
|
||||
/** @type {ChildProcessWithoutNullStreams | null} */
|
||||
let spawnProcess = null;
|
||||
const runMain = debounce(() => {
|
||||
if (spawnProcess !== null) {
|
||||
spawnProcess.kill('SIGINT');
|
||||
spawnProcess = null;
|
||||
}
|
||||
|
||||
spawnProcess = spawn(electronPath, [join(process.cwd(), 'dist/source/main/index.cjs.js')]);
|
||||
|
||||
spawnProcess.stdout.on('data', d => console.log(d.toString()));
|
||||
spawnProcess.stderr.on('data', d => console.error(d.toString()));
|
||||
|
||||
return spawnProcess;
|
||||
|
||||
}, TIMEOUT);
|
||||
|
||||
const buildMain = () => {
|
||||
return build({mode, configFile: join(process.cwd(), 'config/main.vite.js')});
|
||||
};
|
||||
|
||||
const buildMainDebounced = debounce(buildMain, TIMEOUT);
|
||||
|
||||
const runPreload = debounce((file) => {
|
||||
viteDevServer.ws.send({
|
||||
type: 'full-reload',
|
||||
path: '/' + slash(relative(viteDevServer.config.root, file)),
|
||||
});
|
||||
|
||||
}, TIMEOUT);
|
||||
|
||||
const buildPreload = () => {
|
||||
return build({mode, configFile: join(process.cwd(), 'config/preload.vite.js')});
|
||||
};
|
||||
|
||||
const buildPreloadDebounced = debounce(buildPreload, TIMEOUT);
|
||||
|
||||
|
||||
await Promise.all([
|
||||
buildMain(),
|
||||
buildPreload(),
|
||||
]);
|
||||
|
||||
|
||||
const watcher = chokidar.watch([
|
||||
join(process.cwd(), 'src/main/**'),
|
||||
join(process.cwd(), 'src/preload/**'),
|
||||
join(process.cwd(), 'dist/source/main/**'),
|
||||
join(process.cwd(), 'dist/source/preload/**'),
|
||||
], {ignoreInitial: true});
|
||||
|
||||
|
||||
watcher
|
||||
.on('unlink', path => {
|
||||
const normalizedPath = normalizePath(path);
|
||||
if (spawnProcess !== null && normalizedPath.includes('/dist/source/main/')) {
|
||||
spawnProcess.kill('SIGINT');
|
||||
spawnProcess = null;
|
||||
}
|
||||
})
|
||||
.on('add', path => {
|
||||
const normalizedPath = normalizePath(path);
|
||||
if (normalizedPath.includes('/dist/source/main/')) {
|
||||
return runMain();
|
||||
}
|
||||
|
||||
if (spawnProcess !== undefined && normalizedPath.includes('/dist/source/preload/')) {
|
||||
return runPreload(normalizedPath);
|
||||
}
|
||||
})
|
||||
.on('change', (path) => {
|
||||
const normalizedPath = normalizePath(path);
|
||||
|
||||
if (normalizedPath.includes('/src/main/')) {
|
||||
return buildMainDebounced();
|
||||
}
|
||||
|
||||
if (normalizedPath.includes('/dist/source/main/')) {
|
||||
return runMain();
|
||||
}
|
||||
|
||||
if (normalizedPath.includes('/src/preload/')) {
|
||||
return buildPreloadDebounced();
|
||||
}
|
||||
|
||||
if (normalizedPath.includes('/dist/source/preload/')) {
|
||||
return runPreload(normalizedPath);
|
||||
}
|
||||
});
|
||||
|
||||
await runMain();
|
||||
})();
|
||||
Reference in New Issue
Block a user