Skip to content

Commit

Permalink
fix(windows): fix build error with unnormalized brisa dir (#603)
Browse files Browse the repository at this point in the history
* refactor: create load-constants helper

* fix: normalize argv[1] pathname to work on Windows
  • Loading branch information
aralroca authored Nov 3, 2024
1 parent 7ea17d8 commit 59cb1c3
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 175 deletions.
162 changes: 7 additions & 155 deletions packages/brisa/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,110 +1,14 @@
import path from 'node:path';
import type { BunPlugin } from 'bun';
import { version } from '../package.json';
import type { BrisaConstants, I18nConfig } from './types';
import importFileIfExists from './utils/import-file-if-exists';
import {
blueLog,
cyanLog,
greenLog,
redLog,
yellowLog,
} from './utils/log/log-color';
internalConstants,
loadProjectConstants,
} from './utils/load-constants';

const { NODE_ENV } = process.env;

// Note: process.env.IS_PROD is to be defined in the build process
const IS_PRODUCTION =
Boolean(process.env.IS_PROD) ||
NODE_ENV === 'production' ||
process.argv.some((t) => t === 'PROD');

const CLI_DIR = path.join('brisa', 'out', 'cli');
const IS_SERVE_PROCESS =
Boolean(process.env.IS_SERVE_PROCESS) ||
Boolean(process.argv[1]?.endsWith?.(path.join(CLI_DIR, 'serve', 'index.js')));

const IS_STANDALONE_SERVER = Boolean(process.env.IS_STANDALONE_SERVER);

const IS_BUILD_PROCESS = Boolean(
process.argv[1]?.endsWith?.(path.join(CLI_DIR, 'build.js')),
);

const BRISA_DIR = process.argv[1]?.replace(new RegExp(`${CLI_DIR}.*`), 'brisa');

const rootDir = IS_STANDALONE_SERVER ? import.meta.dirname : process.cwd();
const staticExportOutputOption = new Set([
'static',
'desktop',
'android',
'ios',
]);

const srcDir = IS_STANDALONE_SERVER
? import.meta.dirname
: path.resolve(rootDir, 'src');

const buildDir = IS_STANDALONE_SERVER
? import.meta.dirname
: (process.env.BRISA_BUILD_FOLDER ?? path.resolve(rootDir, 'build'));

const WORKSPACE = IS_BUILD_PROCESS ? srcDir : buildDir;

const PAGE_404 = '/_404';
const PAGE_500 = '/_500';
const OS_CAN_LOAD_BALANCE =
process.platform !== 'darwin' && process.platform !== 'win32';

const CACHE_CONTROL = IS_PRODUCTION
? 'public, max-age=31536000, immutable'
: 'no-store, must-revalidate';

const defaultConfig = {
trailingSlash: false,
assetPrefix: '',
basePath: '',
extendPlugins: (plugins: BunPlugin[]) => plugins,
output: 'bun',
clustering: IS_PRODUCTION && OS_CAN_LOAD_BALANCE,
integrations: [],
idleTimeout: 30,
};
const internal = internalConstants();

let constants = {
JS_RUNTIME: typeof Bun !== 'undefined' ? 'bun' : 'node',
PAGE_404,
PAGE_500,
VERSION: version,
RESERVED_PAGES: [PAGE_404, PAGE_500],
IS_PRODUCTION,
IS_DEVELOPMENT:
process.argv.some((t) => t === 'DEV') || NODE_ENV === 'development',
IS_SERVE_PROCESS,
IS_BUILD_PROCESS,
PORT: Number.parseInt(process.argv[2]) || 3000,
BUILD_DIR: buildDir,
ROOT_DIR: rootDir,
BRISA_DIR,
SRC_DIR: srcDir,
ASSETS_DIR: path.resolve(buildDir, 'public'),
PAGES_DIR: path.resolve(buildDir, 'pages'),
LOG_PREFIX: {
WAIT: cyanLog('[ wait ]') + ' ',
READY: greenLog('[ ready ] ') + ' ',
INFO: blueLog('[ info ] ') + ' ',
ERROR: redLog('[ error ] ') + ' ',
WARN: yellowLog('[ warn ] ') + ' ',
TICK: greenLog('✓ ') + ' ',
},
REGEX: {
CATCH_ALL: /\[\[\.{3}.*?\]\]/g,
DYNAMIC: /\[.*?\]/g,
REST_DYNAMIC: /\[\.{3}.*?\]/g,
},
HEADERS: {
CACHE_CONTROL,
},
...(await loadDynamicConstants()),
...internal,
...(await loadProjectConstants(internal)),
} satisfies BrisaConstants;

/**
Expand All @@ -119,63 +23,11 @@ export const getConstants = (): BrisaConstants =>
? (globalThis.mockConstants as typeof constants)
: constants;

async function loadDynamicConstants() {
const binaryExternalLibs = ['lightningcss'];
const CSS_FILES =
(await importFileIfExists('css-files', buildDir))?.default ?? [];
const integrations = await importFileIfExists(
'_integrations',
path.resolve(buildDir, 'web-components'),
);
const WEB_CONTEXT_PLUGINS = integrations?.webContextPlugins ?? [];
const I18N_CONFIG = (await importFileIfExists('i18n', WORKSPACE))
?.default as I18nConfig;
const CONFIG = {
...defaultConfig,
...((await importFileIfExists('brisa.config', rootDir))?.default ?? {}),
};
const IS_STATIC_EXPORT = staticExportOutputOption.has(CONFIG?.output);

// Remove trailing slash from pages
if (I18N_CONFIG?.pages) {
I18N_CONFIG.pages = JSON.parse(
JSON.stringify(I18N_CONFIG.pages, (key, value) =>
typeof value === 'string' && value.length > 1
? value.replace(/\/$/g, '')
: value,
),
);
}

const LOCALES_SET = new Set(I18N_CONFIG?.locales || []) as Set<string>;

if (CONFIG.basePath && !CONFIG.basePath.startsWith(path.sep)) {
CONFIG.basePath = path.sep + CONFIG.basePath;
}

// Add external libraries to the list of external libraries
if (!CONFIG.external) CONFIG.external = binaryExternalLibs;
else CONFIG.external = [...CONFIG.external, ...binaryExternalLibs];

// This is needed for some helpers like "navigate" to work properly
// in the server side. (For the client-side it's solved during the build process)
globalThis.__BASE_PATH__ = CONFIG.basePath;

return {
CSS_FILES,
CONFIG,
I18N_CONFIG,
WEB_CONTEXT_PLUGINS,
LOCALES_SET,
IS_STATIC_EXPORT,
};
}

// Update all that can change during hotreloading
export async function reinitConstants() {
constants = globalThis.mockConstants = {
...constants,
...(await loadDynamicConstants()),
...(await loadProjectConstants(internal)),
};
}

Expand Down
45 changes: 25 additions & 20 deletions packages/brisa/src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,24 @@ declare module 'bun' {
}
}

/**
* Internal types used by Brisa and output adapters.
*/
export type BrisaConstants = {
export type InternalConstants = {
BRISA_DIR: string;
IS_BUILD_PROCESS: boolean;
IS_SERVE_PROCESS: boolean;
WORKSPACE: string;
SRC_DIR: string;
BUILD_DIR: string;
ROOT_DIR: string;
IS_PRODUCTION: boolean;
IS_DEVELOPMENT: boolean;
JS_RUNTIME: 'bun' | 'node';
PAGE_404: string;
PAGE_500: string;
VERSION: string;
WEB_CONTEXT_PLUGINS: string[];
RESERVED_PAGES: string[];
IS_PRODUCTION: boolean;
IS_DEVELOPMENT: boolean;
IS_SERVE_PROCESS: boolean;
IS_BUILD_PROCESS: boolean;
PORT: number;
BUILD_DIR: string;
BRISA_DIR?: string;
ROOT_DIR: string;
SRC_DIR: string;
ASSETS_DIR: string;
PAGES_DIR: string;
I18N_CONFIG: I18nConfig;
CSS_FILES: string[];
LOG_PREFIX: {
WAIT: string;
READY: string;
Expand All @@ -59,15 +54,27 @@ export type BrisaConstants = {
WARN: string;
TICK: string;
};
LOCALES_SET: Set<string>;
CONFIG: Configuration;
IS_STATIC_EXPORT: boolean;
REGEX: Record<string, RegExp>;
HEADERS: {
CACHE_CONTROL: string;
};
};

// Project constants need to be refresed on hot-reload (DEV)
export type ProjectConstants = {
CSS_FILES: string[];
CONFIG: Configuration;
I18N_CONFIG: I18nConfig;
WEB_CONTEXT_PLUGINS: any[];
LOCALES_SET: Set<string>;
IS_STATIC_EXPORT: boolean;
};

/**
* Internal types used by Brisa and output adapters.
*/
export type BrisaConstants = InternalConstants & ProjectConstants;

/**
* Description:
*
Expand Down Expand Up @@ -1398,8 +1405,6 @@ export type WebComponentIntegrations = {
};
};

type ExtendedWebContext = typeof import('@/web-components/_integrations').ExtendedWebContext;

type I18nKey = typeof import('@/i18n').default extends I18nConfig<infer T>
? Paths<T extends object ? T : I18nDictionary>
: string;
Expand Down
43 changes: 43 additions & 0 deletions packages/brisa/src/utils/load-constants/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { describe, expect, it } from 'bun:test';
import { internalConstants } from '.';

describe('utils -> load-constants', () => {
describe('internalConstants', () => {
it('should return IS_SERVE_PROCESS as true and IS_BUILD_PROCESS as false', () => {
process.argv[1] = 'brisa/out/cli/serve/index.js';
const result = internalConstants();
expect(result.IS_SERVE_PROCESS).toBeTrue();
expect(result.IS_BUILD_PROCESS).toBeFalse();
});
it('should return IS_SERVE_PROCESS as false and IS_BUILD_PROCESS as true', () => {
process.argv[1] = 'brisa/out/cli/build.js';
const result = internalConstants();
expect(result.IS_SERVE_PROCESS).toBeFalse();
expect(result.IS_BUILD_PROCESS).toBeTrue();
});
it('should return IS_SERVE_PROCESS as true and IS_BUILD_PROCESS as false (argv Windows format)', () => {
process.argv[1] = 'brisa\\out\\cli\\serve\\index.js';
const result = internalConstants();
expect(result.IS_SERVE_PROCESS).toBeTrue();
expect(result.IS_BUILD_PROCESS).toBeFalse();
});
it('should return IS_SERVE_PROCESS as false and IS_BUILD_PROCESS as true (argv Windows format)', () => {
process.argv[1] = 'brisa\\out\\cli\\build.js';
const result = internalConstants();
expect(result.IS_SERVE_PROCESS).toBeFalse();
expect(result.IS_BUILD_PROCESS).toBeTrue();
});

it('should return BRISA_DIR', () => {
process.argv[1] = 'brisa/out/cli/serve/index.js';
const result = internalConstants();
expect(result.BRISA_DIR).toBe('brisa');
});

it('should return BRISA_DIR (argv Windows format)', () => {
process.argv[1] = 'brisa\\\\out\\\\cli\\\\serve\\\\index.js';
const result = internalConstants();
expect(result.BRISA_DIR).toBe('brisa');
});
});
});
Loading

0 comments on commit 59cb1c3

Please sign in to comment.