Skip to content

Commit 3e2949b

Browse files
feat: remove node dependencies from compiler (#188)
1 parent 29dc343 commit 3e2949b

File tree

12 files changed

+3414
-2756
lines changed

12 files changed

+3414
-2756
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jobs:
1919
uses: actions/checkout@v3
2020

2121
- name: Install pnpm
22-
uses: pnpm/action-setup@v2.2.4
22+
uses: pnpm/action-setup@v4
2323
with:
24-
version: 7.14.0
24+
version: 9
2525

2626
- name: Set node version to ${{ matrix.node_version }}
2727
uses: actions/setup-node@v3

packages/abell/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "abell",
3-
"version": "1.0.0-beta.4",
3+
"version": "1.0.0-beta.5",
44
"description": "Abell is a static-site-generator for JavaScript developers. Powered by Vite, It tries to stay close to fundamentals while providing a great DX",
55
"bin": "./dist/bin.js",
66
"main": "./dist/index.js",

packages/abell/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ export { vitePluginAbell } from './vite-plugin-abell/index.js';
44
export { defineConfig, makeRoutesFromGlobImport } from './utils/api.js';
55

66
export { Route, AbellViteConfig } from './type-utils.js';
7-
export { evaluateAbellBlock } from './utils/internal-utils.js';

packages/abell/src/type-utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ export type AbellOptions = {
6565
* E.g. if you want to use top-level await in entry.build.ts, you can set target here without having to change target of your final client bundle
6666
*/
6767
serverBuild?: ViteUserConfig['build'];
68+
69+
/**
70+
* Allows `.abell` files to be imported in client-side code.
71+
*
72+
* Abell variables like `Abell.root`, `__dirname`, `__filename` etc return empty string when this flag is set
73+
*/
74+
experimentalAllowClientSide?: boolean;
6875
};
6976

7077
export interface AbellViteConfig extends ViteUserConfig {

packages/abell/src/utils/__tests__/internal-utils.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { test, describe, expect } from 'vitest';
2-
import {
3-
getURLFromFilePath,
4-
evaluateAbellBlock,
5-
getFilePathFromURL
6-
} from '../internal-utils';
2+
import { getURLFromFilePath, getFilePathFromURL } from '../internal-utils';
3+
import { evaluateAbellBlock } from '../evaluateAbellBlock';
74
import { BASE_PATH, prefix } from './test-utils';
85

96
describe('getURLFromFilePath()', () => {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Evaluates the abell block.
3+
*
4+
* Internally used to clean the output and return correct value.
5+
*
6+
*/
7+
export const evaluateAbellBlock = (val: unknown): string | boolean | number => {
8+
if (val === undefined || val === null) return ''; // never print undefined or null
9+
if (typeof val === 'function') return evaluateAbellBlock(val()); // if function, execute the function
10+
if (Array.isArray(val)) return val.join(''); // if array, join the array with ''
11+
if (typeof val === 'object') return JSON.stringify(val); // if object, stringify object
12+
if (
13+
typeof val === 'string' ||
14+
typeof val === 'boolean' || // string, boolean, number can take care of stringifying at the end
15+
typeof val === 'number'
16+
) {
17+
return val;
18+
}
19+
20+
// force stringification on rest
21+
return String(val);
22+
};

packages/abell/src/utils/internal-utils.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -408,26 +408,3 @@ export const addJStoBodyEnd = (
408408

409409
return htmlContent + jsLinks;
410410
};
411-
412-
/**
413-
* Evaluates the abell block.
414-
*
415-
* Internally used to clean the output and return correct value.
416-
*
417-
*/
418-
export const evaluateAbellBlock = (val: unknown): string | boolean | number => {
419-
if (val === undefined || val === null) return ''; // never print undefined or null
420-
if (typeof val === 'function') return evaluateAbellBlock(val()); // if function, execute the function
421-
if (Array.isArray(val)) return val.join(''); // if array, join the array with ''
422-
if (typeof val === 'object') return JSON.stringify(val); // if object, stringify object
423-
if (
424-
typeof val === 'string' ||
425-
typeof val === 'boolean' || // string, boolean, number can take care of stringifying at the end
426-
typeof val === 'number'
427-
) {
428-
return val;
429-
}
430-
431-
// force stringification on rest
432-
return String(val);
433-
};

packages/abell/src/vite-plugin-abell/compiler/compiler.spec.ts

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ describe('compile()', () => {
3636
});
3737
expect(js.trim().replace(`\\\\test.abell`, '/test.abell'))
3838
.toMatchInlineSnapshot(`
39-
"import { default as _path } from 'path';
40-
import { evaluateAbellBlock as e } from 'abell';
41-
42-
const __filename = \\"/test.abell\\";
43-
const __dirname = _path.dirname(__filename);
44-
const root = _path.relative(__dirname, \\"/\\")
45-
export const html = (props = {}) => {
46-
const Abell = { props, __filename, __dirname };
39+
"import { default as _path } from 'path';
40+
import { evaluateAbellBlock as e } from 'abell/dist/utils/evaluateAbellBlock';
4741
48-
return \`
49-
<nav>hello</nav>
50-
\`
51-
};
52-
export default html;"
53-
`);
42+
const __filename = \\"/test.abell\\";
43+
const __dirname = _path.dirname(__filename);
44+
const root = _path.relative(__dirname, \\"/\\");
45+
export const html = (props = {}) => {
46+
const Abell = { props, __filename, __dirname };
47+
48+
return \`
49+
<nav>hello</nav>
50+
\`
51+
};
52+
export default html;"
53+
`);
5454
});
5555

5656
test('should create first block as declaration block with declarations comment', () => {
@@ -94,30 +94,30 @@ describe('compile()', () => {
9494
});
9595
expect(js.trim().replace(`\\\\test.abell`, '/test.abell'))
9696
.toMatchInlineSnapshot(`
97-
"import { default as _path } from 'path';
98-
import { evaluateAbellBlock as e } from 'abell';
99-
100-
import x from './x';
101-
102-
const __filename = \\"/test.abell\\";
103-
const __dirname = _path.dirname(__filename);
104-
const root = _path.relative(__dirname, \\"/\\")
105-
export const html = (props = {}) => {
106-
const Abell = { props, __filename, __dirname };
107-
108-
/** @declarations */
109-
const x = 999;
110-
111-
return \`
97+
"import { default as _path } from 'path';
98+
import { evaluateAbellBlock as e } from 'abell/dist/utils/evaluateAbellBlock';
11299
100+
import x from './x';
101+
102+
const __filename = \\"/test.abell\\";
103+
const __dirname = _path.dirname(__filename);
104+
const root = _path.relative(__dirname, \\"/\\");
105+
export const html = (props = {}) => {
106+
const Abell = { props, __filename, __dirname };
107+
108+
/** @declarations */
109+
const x = 999;
110+
111+
return \`
112+
113113
114-
<b>\${e( 3 + 4 )}</b>
115-
116-
<nav>\${e( x * 2 )}</nav>
117-
\`
118-
};
119-
export default html;"
120-
`);
114+
<b>\${e( 3 + 4 )}</b>
115+
116+
<nav>\${e( x * 2 )}</nav>
117+
\`
118+
};
119+
export default html;"
120+
`);
121121
});
122122

123123
test('should successfully compile with imports', () => {

packages/abell/src/vite-plugin-abell/compiler/compiler.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface CompileOptions {
1818
filepath: string;
1919
cwd?: string;
2020
outputType?: 'js-string' | 'syntax-blocks';
21+
isClientSide?: boolean;
2122
}
2223

2324
interface HTMLOutputCompileOptions extends CompileOptions {
@@ -77,12 +78,20 @@ export function compile(
7778
}
7879

7980
const jsOut = `
80-
import { default as _path } from 'path';
81-
import { evaluateAbellBlock as e } from 'abell';
81+
${options.isClientSide ? '' : `import { default as _path } from 'path';`}
82+
import { evaluateAbellBlock as e } from 'abell/dist/utils/evaluateAbellBlock';
8283
${importBlock.text}
83-
const __filename = ${JSON.stringify(options.filepath)};
84-
const __dirname = _path.dirname(__filename);
85-
const root = _path.relative(__dirname, ${JSON.stringify(options.cwd)})
84+
const __filename = ${
85+
options.isClientSide ? '"";' : JSON.stringify(options.filepath)
86+
};
87+
const __dirname = ${
88+
options.isClientSide ? '"";' : '_path.dirname(__filename);'
89+
}
90+
const root = ${
91+
options.isClientSide
92+
? '"";'
93+
: `_path.relative(__dirname, ${JSON.stringify(options.cwd)});`
94+
}
8695
export const html = (props = {}) => {
8796
const Abell = { props, __filename, __dirname };
8897
${declarationBlocks.text}

packages/abell/src/vite-plugin-abell/vite-plugin-abell.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ export function vitePluginAbell(abellOptions?: AbellOptions): PluginOption {
2929
if (id.endsWith('.abell')) {
3030
const jsCode = compile(src, {
3131
filepath: id,
32-
cwd: process.cwd()
32+
cwd: process.cwd(),
33+
isClientSide: abellOptions?.experimentalAllowClientSide ?? false
3334
});
3435
let outCode = jsCode;
3536
// If loader is not defined, skip the esbuild transform

0 commit comments

Comments
 (0)