Skip to content

Commit

Permalink
feat: integrate compile function into pwc runtime (#29)
Browse files Browse the repository at this point in the history
* feat(compiler+runtime): integrate compile function into pwc runtime

* feat: use pkg-cli to compile packages

* chore(example): update rollup config

* build: update pnpm lock file

* chore: remove .js extension

* feat(plyground): add playground

* feat(compiler): handle situation without template block

* fix: lint error

* build: update lock file

* chore(example): update runtime

* feat(playground): support update code in editor

* fix(playground): lint error

* fix(compiler): miss add accessor

* test: add pwc-compiler test cases (#34)

* refactor(compiler): update data structure of get template

* feat(compiler): finish compileTemplateInRuntime method

* chore(example): update runtime example

* fix: lint error

* chore(playground): remove playground code

* refactor: attribute format

* chore: remove debugger

* chore: change type to interface

* chore: lint

* chore: add capture type

* fix(compiler): handle reactive import

* fix(compiler): test case of import specifiers in pwc

* chore(compiler): update for comment

* fix: get template method trigger times (#36)

* fix: get template method trigger times

* fix: get template method trigger times

* chore: remove useless code

* chore: typo

Co-authored-by: Rongyan Chen <[email protected]>
Co-authored-by: fushen <[email protected]>
  • Loading branch information
3 people authored Apr 2, 2022
1 parent 9ca4251 commit 3ad3c1f
Show file tree
Hide file tree
Showing 53 changed files with 799 additions and 303 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/edit-word/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const commonjs = require('@rollup/plugin-commonjs');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const livereload = require('rollup-plugin-livereload');
const css = require('rollup-plugin-css-only');
const pwc = require('rollup-plugin-pwc');
const pwc = require('rollup-plugin-pwc').default;


const production = !process.env.ROLLUP_WATCH;
Expand Down
2 changes: 1 addition & 1 deletion examples/project/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const commonjs = require('@rollup/plugin-commonjs');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const livereload = require('rollup-plugin-livereload');
const css = require('rollup-plugin-css-only');
const pwc = require('rollup-plugin-pwc');
const pwc = require('rollup-plugin-pwc').default;


const production = !process.env.ROLLUP_WATCH;
Expand Down
15 changes: 9 additions & 6 deletions examples/project/src/index.pwc
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
<template>
<div class="content">
<button @click={{addCount}}>+</button>
{{count}}
<button @click={{#addCount}}>+</button>
{{ #count }}
{{ publicField }}
<button @click={{reduceCount}}>-</button>
</div>
</template>

<script>
@customElement('custom-component')

export default class CustomComponent extends HTMLElement {
@reactive
accessor count = 0;
#count = 0;

publicField = 'pwc';


addCount() {
#addCount() {
this.count = this.count + 1;
}

Expand Down
19 changes: 19 additions & 0 deletions examples/runtime/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "project",
"version": "0.0.0",
"scripts": {
"start": "rollup -c -w",
"build": "rollup -c",
"serve": "sirv public --no-clear"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.2",
"@rollup/plugin-node-resolve": "^13.1.3",
"rollup": "^2.69.0",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.5",
"sirv-cli": "^2.0.2",
"pwc": "workspace:*",
"rollup-plugin-pwc": "workspace:*"
}
}
15 changes: 15 additions & 0 deletions examples/runtime/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />

<title>PWC Preview</title>

<script src="/dist/index.js" type="module"></script>
</head>

<body>
<runtime-component></runtime-component>
</body>
</html>
51 changes: 51 additions & 0 deletions examples/runtime/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const commonjs = require('@rollup/plugin-commonjs');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const livereload = require('rollup-plugin-livereload');
const css = require('rollup-plugin-css-only');
const pwc = require('rollup-plugin-pwc').default;


const production = !process.env.ROLLUP_WATCH;

function serve() {
let server;

function toExit() {
if (server) server.kill(0);
}

return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'serve', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true,
});

process.on('SIGTERM', toExit);
process.on('exit', toExit);
},
};
}

module.exports = {
input: 'src/index.pwc',
output: {
file: 'public/dist/index.js',
format: 'umd',
name: 'app',
sourcemap: 'inline',
},
plugins: [
pwc({ include: /\.pwc$/ }),
css({ output: 'index.css' }),
nodeResolve(),
commonjs(),
!production && serve(),
// !production && livereload('public'),

],
watch: {
clearScreen: false,
},
};
25 changes: 25 additions & 0 deletions examples/runtime/src/index.pwc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script>
import { html, reactive } from 'pwc';

export default class RuntimeComponent extends HTMLElement {
@reactive
accessor name = 'pwc';

className = 'container';

handleClick = () => {
console.log('click');
this.name = 'changed title';
};

get template() {
return html`<div class="${this.className}" @click.capture=${this.handleClick}>${this.name}${this.name}</div>`;
}
}
</script>

<style>
.container {
color: blue;
}
</style>
2 changes: 1 addition & 1 deletion examples/word-count/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const commonjs = require('@rollup/plugin-commonjs');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const livereload = require('rollup-plugin-livereload');
const css = require('rollup-plugin-css-only');
const pwc = require('rollup-plugin-pwc');
const pwc = require('rollup-plugin-pwc').default;


const production = !process.env.ROLLUP_WATCH;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
"setup": "npm run clean && pnpm install --reporter=append-only --registry=https://registry.npmjs.org/",
"setup": "npm run clean && pnpm install --reporter=append-only --registry=https://registry.npmjs.org/ && npm run build",
"clean": "rm -rf node_modules && rm -rf ./**/*/node_modules && npm run clean:result",
"clean:result": "rm -rf ./packages/*/lib ./packages/*/es ./packages/*/esnext ./packages/*/dist",
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./",
Expand All @@ -13,7 +13,7 @@
"test:watch": "jest --watch",
"start-bench-server": "ws -c lws.config.js --static.maxage 1 -d ./benchmarks",
"benchmark": "esno ./scripts/benchmarks/index.ts",
"start": "pnpm --filter \"./packages\" -r exec npm run start ",
"start": "pnpm run start --parallel --filter \"./packages\"",
"build": "pnpm run build -r --filter \"./packages\"",
"prepare-husky": "husky install"
},
Expand Down
5 changes: 0 additions & 5 deletions packages/pwc-compiler/__tests__/compileScript.spec.ts

This file was deleted.

131 changes: 131 additions & 0 deletions packages/pwc-compiler/__tests__/compileScript.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { parse, compileScript } from '../src';

const simpeComponent = `
<template>
<p>{{#text}}</p>
</template>
<script>
export default class CustomElement extends HTMLElement {
#text = '';
}
</script>`;

const noTemplateComponent = `
<script>
export default class CustomElement extends HTMLElement {
#text = '';
}
</script>`;

const mixNormalPropertyComponent = `
<template>
<p>{{#text}}</p>
</template>
<script>
export default class CustomElement extends HTMLElement {
#text = '';
data = {};
}
</script>
`;

const pureComponent = `
<template>
<p>hello</p>
</template>
<script>
export default class CustomElement extends HTMLElement {}
</script>`;

const definedComponent = `
<template>
<p>hello</p>
</template>
<script>
import { customElement } from 'pwc';
@customElement('custom-element')
export default class CustomElement extends HTMLElement {}
</script>
`;

describe('compileScript', () => {
test('It should inject pwc', () => {
const { descriptor } = parse(simpeComponent);
const result = compileScript(descriptor);

expect(result.content).toContain(`import { customElement, reactive } from \"pwc\";`);
});

test('It should inject decorators', () => {
const { descriptor } = parse(simpeComponent);
const result = compileScript(descriptor);

expect(result.content).toContain(`@customElement("custom-element")
export default class CustomElement extends HTMLElement {
@reactive
accessor #text = '';`);
});

test('It should inject template getter method', () => {
const { descriptor } = parse(simpeComponent);
const result = compileScript(descriptor);

expect(result.content).toContain(`get template() {
return [\"\\n <p><!--?pwc_t--></p>\\n\", [this.#text]];
}`);
});

test('It should not inject template getter method', () => {
const { descriptor } = parse(noTemplateComponent);
const result = compileScript(descriptor);

expect(result.content).not.toContain('get template()');
});

test('It should not add @reactive decorator to normal property', () => {
const { descriptor } = parse(mixNormalPropertyComponent);
const result = compileScript(descriptor);

expect(result.content).toEqual(`import { customElement, reactive } from "pwc";
@customElement("custom-element")
export default class CustomElement extends HTMLElement {
@reactive
accessor #text = '';
data = {};
get template() {
return ["\\n <p><!--?pwc_t--></p>\\n", [this.#text]];
}
}`);
});

test('It should not import pwc with pure component', () => {
const { descriptor } = parse(pureComponent);
const result = compileScript(descriptor);

expect(result.content).toEqual(`import { customElement } from \"pwc\";
@customElement(\"custom-element\")
export default class CustomElement extends HTMLElement {
get template() {
return [\"\\n <p>hello</p>\\n\", []];
}
}`);
});

test('It should not import customElement again with defined component', () => {
const { descriptor } = parse(definedComponent);
const result = compileScript(descriptor);

expect(result.content).toEqual(`import { customElement } from 'pwc';
@customElement('custom-element')
export default class CustomElement extends HTMLElement {
get template() {
return [\"\\n <p>hello</p>\\n\", []];
}
}`);
});
});
5 changes: 0 additions & 5 deletions packages/pwc-compiler/__tests__/compileTemplate.spec.ts

This file was deleted.

61 changes: 61 additions & 0 deletions packages/pwc-compiler/__tests__/compileTemplate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { compileTemplateAST, parse } from '../src';

describe('compileTemplate', () => {
it('compile a simple template ', () => {
const { descriptor } = parse('<template><p>{{text}}</p></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);

expect(templateString).toBe('<p><!--?pwc_t--></p>');
expect(values).toEqual(['text']);
});

it('compile a template with a event', () => {
const { descriptor } = parse('<template><p @click={{handleClick}}>{{text}}</p></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);

expect(templateString).toBe('<!--?pwc_p--><p><!--?pwc_t--></p>');
expect(values).toEqual([
[
{
name: 'onclick',
value: 'handleClick',
capture: false,
}
],
'text'
]);
});

it('compile a template with a capture event', () => {
const { descriptor } = parse('<template><p @click.capture={{handleClick}}>{{text}}</p></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);

expect(templateString).toBe('<!--?pwc_p--><p><!--?pwc_t--></p>');
expect(values).toEqual([
[
{
name: 'onclick',
value: 'handleClick',
capture: true,
}
],
'text'
]);
});

it('compile a template with attributes', () => {
const { descriptor } = parse('<template><p class={{className}}>{{text}}</p></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);

expect(templateString).toBe('<!--?pwc_p--><p><!--?pwc_t--></p>');
expect(values).toEqual([
[
{
name: 'class',
value: 'className',
}
],
'text'
]);
});
});
Loading

0 comments on commit 3ad3c1f

Please sign in to comment.