wc-compiler 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/wcc.dist.cjs +15679 -363
- package/package.json +12 -6
- package/src/dom-shim.js +11 -1
- package/src/jsx-loader.js +9 -2
- package/src/ts-loader.js +32 -0
- package/src/wcc.js +21 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wc-compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Experimental native Web Components compiler.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
30
|
"clean": "rimraf ./dist",
|
|
31
|
-
"lint": "
|
|
31
|
+
"lint": "eslint --ignore-pattern \"*.json\" \"*.*js\" \"./src/**/**/*.js*\" \"./sandbox/**/**/*.js*\" \"./docs/**/*.md\" \"./test/**/**/*.js*\"",
|
|
32
32
|
"docs:dev": "concurrently \"nodemon --watch src --watch docs -e js,md,css,html,jsx ./build.js\" \"http-server ./dist --open\"",
|
|
33
33
|
"docs:build": "node ./build.js",
|
|
34
34
|
"docs:serve": "npm run clean && npm run docs:build && http-server ./dist --open",
|
|
35
|
-
"sandbox": "npm run clean && concurrently \"nodemon --
|
|
35
|
+
"sandbox": "npm run clean && concurrently \"nodemon --loader ./test-exp-loader.js --watch src --watch sandbox -e js,md,css,html,jsx,ts ./sandbox.js\" \"http-server ./dist --open\" \"livereload ./dist\"",
|
|
36
36
|
"start": "npm run docs:serve",
|
|
37
|
-
"test": "mocha --exclude \"./test/cases/jsx*/**\" --exclude \"./test/cases/custom-extension/**\" \"./test/**/**/*.spec.js\"",
|
|
38
|
-
"test:exp": "c8 node --
|
|
37
|
+
"test": "mocha --exclude \"./test/cases/jsx*/**\" --exclude \"./test/cases/ts*/**\" --exclude \"./test/cases/custom-extension/**\" \"./test/**/**/*.spec.js\"",
|
|
38
|
+
"test:exp": "c8 node --loader ./test-exp-loader.js ./node_modules/mocha/bin/mocha \"./test/**/**/*.spec.js\"",
|
|
39
39
|
"test:tdd": "npm run test -- --watch",
|
|
40
40
|
"test:tdd:exp": "npm run test:exp -- --watch",
|
|
41
41
|
"dist": "rollup -c rollup.config.js",
|
|
@@ -45,10 +45,16 @@
|
|
|
45
45
|
"@projectevergreen/acorn-jsx-esm": "~0.1.0",
|
|
46
46
|
"@projectevergreen/escodegen-esm": "~0.1.0",
|
|
47
47
|
"acorn": "^8.7.0",
|
|
48
|
+
"acorn-import-attributes": "^1.9.5",
|
|
48
49
|
"acorn-walk": "^8.2.0",
|
|
49
|
-
"parse5": "^6.0.1"
|
|
50
|
+
"parse5": "^6.0.1",
|
|
51
|
+
"sucrase": "^3.35.0"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
54
|
+
"@babel/core": "^7.24.4",
|
|
55
|
+
"@babel/eslint-parser": "^7.24.1",
|
|
56
|
+
"@babel/plugin-syntax-import-assertions": "^7.24.1",
|
|
57
|
+
"@babel/preset-react": "^7.24.1",
|
|
52
58
|
"@ls-lint/ls-lint": "^1.10.0",
|
|
53
59
|
"@mapbox/rehype-prism": "^0.8.0",
|
|
54
60
|
"@rollup/plugin-commonjs": "^25.0.7",
|
package/src/dom-shim.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
function noop() { }
|
|
2
2
|
|
|
3
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet
|
|
4
|
+
class CSSStyleSheet {
|
|
5
|
+
insertRule() { }
|
|
6
|
+
deleteRule() { }
|
|
7
|
+
replace() { }
|
|
8
|
+
replaceSync() { }
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
|
|
4
12
|
class EventTarget {
|
|
5
13
|
constructor() {
|
|
@@ -93,6 +101,7 @@ class ShadowRoot extends DocumentFragment {
|
|
|
93
101
|
constructor(options) {
|
|
94
102
|
super();
|
|
95
103
|
this.mode = options.mode || 'closed';
|
|
104
|
+
this.adoptedStyleSheets = [];
|
|
96
105
|
}
|
|
97
106
|
}
|
|
98
107
|
|
|
@@ -146,4 +155,5 @@ class CustomElementsRegistry {
|
|
|
146
155
|
globalThis.addEventListener = globalThis.addEventListener ?? noop;
|
|
147
156
|
globalThis.document = globalThis.document ?? new Document();
|
|
148
157
|
globalThis.customElements = globalThis.customElements ?? new CustomElementsRegistry();
|
|
149
|
-
globalThis.HTMLElement = globalThis.HTMLElement ?? HTMLElement;
|
|
158
|
+
globalThis.HTMLElement = globalThis.HTMLElement ?? HTMLElement;
|
|
159
|
+
globalThis.CSSStyleSheet = globalThis.CSSStyleSheet ?? CSSStyleSheet;
|
package/src/jsx-loader.js
CHANGED
|
@@ -6,6 +6,9 @@ import { generate } from '@projectevergreen/escodegen-esm';
|
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import jsx from '@projectevergreen/acorn-jsx-esm';
|
|
8
8
|
import { parse, parseFragment, serialize } from 'parse5';
|
|
9
|
+
// Need an acorn plugin for now - https://github.com/ProjectEvergreen/greenwood/issues/1218
|
|
10
|
+
import { importAttributes } from 'acorn-import-attributes';
|
|
11
|
+
import { transform } from 'sucrase';
|
|
9
12
|
|
|
10
13
|
const jsxRegex = /\.(jsx)$/;
|
|
11
14
|
|
|
@@ -29,7 +32,7 @@ export function getParser(moduleURL) {
|
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
return {
|
|
32
|
-
parser: acorn.Parser.extend(jsx()),
|
|
35
|
+
parser: acorn.Parser.extend(jsx(), importAttributes),
|
|
33
36
|
config: {
|
|
34
37
|
// https://github.com/acornjs/acorn/issues/829#issuecomment-1172586171
|
|
35
38
|
...walk.base,
|
|
@@ -230,13 +233,17 @@ function findThisReferences(context, statement) {
|
|
|
230
233
|
|
|
231
234
|
export function parseJsx(moduleURL) {
|
|
232
235
|
const moduleContents = fs.readFileSync(moduleURL, 'utf-8');
|
|
236
|
+
const result = transform(moduleContents, {
|
|
237
|
+
transforms: ['typescript', 'jsx'],
|
|
238
|
+
jsxRuntime: 'preserve'
|
|
239
|
+
});
|
|
233
240
|
// would be nice if we could do this instead, so we could know ahead of time
|
|
234
241
|
// const { inferredObservability } = await import(moduleURL);
|
|
235
242
|
// however, this requires making parseJsx async, but WCC acorn walking is done sync
|
|
236
243
|
const hasOwnObservedAttributes = undefined;
|
|
237
244
|
let inferredObservability = false;
|
|
238
245
|
let observedAttributes = [];
|
|
239
|
-
let tree = acorn.Parser.extend(jsx()).parse(
|
|
246
|
+
let tree = acorn.Parser.extend(jsx(), importAttributes).parse(result.code, {
|
|
240
247
|
ecmaVersion: 'latest',
|
|
241
248
|
sourceType: 'module'
|
|
242
249
|
});
|
package/src/ts-loader.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import { transform } from 'sucrase';
|
|
3
|
+
|
|
4
|
+
const tsRegex = /\.(ts)$/;
|
|
5
|
+
|
|
6
|
+
export function resolve(specifier, context, defaultResolve) {
|
|
7
|
+
const { parentURL } = context;
|
|
8
|
+
|
|
9
|
+
if (tsRegex.test(specifier)) {
|
|
10
|
+
return {
|
|
11
|
+
url: new URL(specifier, parentURL).href,
|
|
12
|
+
shortCircuit: true
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return defaultResolve(specifier, context, defaultResolve);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function load(url, context, defaultLoad) {
|
|
20
|
+
if (tsRegex.test(url)) {
|
|
21
|
+
const contents = await fs.readFile(new URL(url), 'utf-8');
|
|
22
|
+
const result = transform(contents, { transforms: ['typescript'] });
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
format: 'module',
|
|
26
|
+
shortCircuit: true,
|
|
27
|
+
source: result.code
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return defaultLoad(url, context, defaultLoad);
|
|
32
|
+
}
|
package/src/wcc.js
CHANGED
|
@@ -7,6 +7,9 @@ import * as walk from 'acorn-walk';
|
|
|
7
7
|
import { generate } from '@projectevergreen/escodegen-esm';
|
|
8
8
|
import { getParser, parseJsx } from './jsx-loader.js';
|
|
9
9
|
import { parse, parseFragment, serialize } from 'parse5';
|
|
10
|
+
// Need an acorn plugin for now - https://github.com/ProjectEvergreen/greenwood/issues/1218
|
|
11
|
+
import { importAttributes } from 'acorn-import-attributes';
|
|
12
|
+
import { transform } from 'sucrase';
|
|
10
13
|
import fs from 'fs';
|
|
11
14
|
|
|
12
15
|
function getParse(html) {
|
|
@@ -59,14 +62,18 @@ async function renderComponentRoots(tree, definitions) {
|
|
|
59
62
|
|
|
60
63
|
function registerDependencies(moduleURL, definitions, depth = 0) {
|
|
61
64
|
const moduleContents = fs.readFileSync(moduleURL, 'utf-8');
|
|
65
|
+
const result = transform(moduleContents, {
|
|
66
|
+
transforms: ['typescript', 'jsx'],
|
|
67
|
+
jsxRuntime: 'preserve'
|
|
68
|
+
});
|
|
62
69
|
const nextDepth = depth += 1;
|
|
63
70
|
const customParser = getParser(moduleURL);
|
|
64
|
-
const parser = customParser ? customParser.parser : acorn;
|
|
71
|
+
const parser = customParser ? customParser.parser : acorn.Parser;
|
|
65
72
|
const config = customParser ? customParser.config : {
|
|
66
73
|
...walk.base
|
|
67
74
|
};
|
|
68
75
|
|
|
69
|
-
walk.simple(parser.parse(
|
|
76
|
+
walk.simple(parser.extend(importAttributes).parse(result.code, {
|
|
70
77
|
ecmaVersion: 'latest',
|
|
71
78
|
sourceType: 'module'
|
|
72
79
|
}), {
|
|
@@ -76,7 +83,8 @@ function registerDependencies(moduleURL, definitions, depth = 0) {
|
|
|
76
83
|
const extension = specifier.split('.').pop();
|
|
77
84
|
|
|
78
85
|
// TODO would like to decouple .jsx from the core, ideally
|
|
79
|
-
|
|
86
|
+
// https://github.com/ProjectEvergreen/wcc/issues/122
|
|
87
|
+
if (!isBareSpecifier && ['js', 'jsx', 'ts'].includes(extension)) {
|
|
80
88
|
const dependencyModuleURL = new URL(node.source.value, moduleURL);
|
|
81
89
|
|
|
82
90
|
registerDependencies(dependencyModuleURL, definitions, nextDepth);
|
|
@@ -105,14 +113,18 @@ function registerDependencies(moduleURL, definitions, depth = 0) {
|
|
|
105
113
|
|
|
106
114
|
async function getTagName(moduleURL) {
|
|
107
115
|
const moduleContents = await fs.promises.readFile(moduleURL, 'utf-8');
|
|
116
|
+
const result = transform(moduleContents, {
|
|
117
|
+
transforms: ['typescript', 'jsx'],
|
|
118
|
+
jsxRuntime: 'preserve'
|
|
119
|
+
});
|
|
108
120
|
const customParser = getParser(moduleURL);
|
|
109
|
-
const parser = customParser ? customParser.parser : acorn;
|
|
121
|
+
const parser = customParser ? customParser.parser : acorn.Parser;
|
|
110
122
|
const config = customParser ? customParser.config : {
|
|
111
123
|
...walk.base
|
|
112
124
|
};
|
|
113
125
|
let tagName;
|
|
114
126
|
|
|
115
|
-
walk.simple(parser.parse(
|
|
127
|
+
walk.simple(parser.extend(importAttributes).parse(result.code, {
|
|
116
128
|
ecmaVersion: 'latest',
|
|
117
129
|
sourceType: 'module'
|
|
118
130
|
}), {
|
|
@@ -133,9 +145,10 @@ async function initializeCustomElement(elementURL, tagName, attrs = [], definiti
|
|
|
133
145
|
}
|
|
134
146
|
|
|
135
147
|
// https://github.com/ProjectEvergreen/wcc/pull/67/files#r902061804
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
const
|
|
148
|
+
// https://github.com/ProjectEvergreen/wcc/pull/159
|
|
149
|
+
const { href } = elementURL;
|
|
150
|
+
const element = customElements.get(tagName) ?? (await import(href)).default;
|
|
151
|
+
const dataLoader = (await import(href)).getData;
|
|
139
152
|
const data = props
|
|
140
153
|
? props
|
|
141
154
|
: dataLoader
|