Skip to content

Commit 76f5dc4

Browse files
CompuIvesSaraVieira
andcommitted
Stencil Compiler POC (codesandbox#2203)
* Stencil POC * Base version of compiler from dependencies * Use imports info from stencil compiler * remove setting everything to stencil * remove import * fix lint Co-authored-by: Sara Vieira <[email protected]>
1 parent 7a4c271 commit 76f5dc4

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import babelTranspiler from '../../transpilers/babel';
2+
import jsonTranspiler from '../../transpilers/json';
3+
import rawTranspiler from '../../transpilers/raw';
4+
import stencilTranspiler from '../../transpilers/stencil';
5+
6+
import Preset from '..';
7+
8+
const babelOptions = {
9+
isV7: true,
10+
config: {
11+
presets: [],
12+
plugins: ['@babel/plugin-syntax-import-meta'],
13+
parserOpts: {
14+
plugins: ['dynamicImport', 'objectRestSpread', 'importMeta'],
15+
},
16+
},
17+
};
18+
19+
export default function initialize() {
20+
const stencilPreset = new Preset(
21+
'stencil',
22+
['js', 'ts', 'jsx', 'tsx', 'mjs'],
23+
{}
24+
);
25+
26+
stencilPreset.registerTranspiler(module => /\.(t|j)sx?$/.test(module.path), [
27+
{ transpiler: stencilTranspiler },
28+
]);
29+
30+
stencilPreset.registerTranspiler(module => /\.mjs$/.test(module.path), [
31+
{ transpiler: stencilTranspiler },
32+
{ transpiler: babelTranspiler, options: babelOptions },
33+
]);
34+
35+
stencilPreset.registerTranspiler(module => /\.json$/.test(module.path), [
36+
{ transpiler: jsonTranspiler },
37+
]);
38+
39+
stencilPreset.registerTranspiler(() => true, [{ transpiler: rawTranspiler }]);
40+
41+
return stencilPreset;
42+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// @ts-ignore
2+
import StencilWorker from 'worker-loader?publicPath=/&name=stencil-transpiler.[hash:8].worker.js!./stencil-worker.ts';
3+
4+
import WorkerTranspiler from '../worker-transpiler';
5+
import { LoaderContext } from '../../transpiled-module';
6+
import { TranspilerResult } from '..';
7+
8+
const DEFAULT_STENCIL_VERSION = '1.2.0-1';
9+
10+
const getStencilVersion = (packageJSON: any) => {
11+
if (!packageJSON || !packageJSON.parsed) {
12+
return DEFAULT_STENCIL_VERSION;
13+
}
14+
15+
const testVersion = (parsed, keyToCheck): string | undefined =>
16+
parsed[keyToCheck] && parsed[keyToCheck]['@stencil/core'];
17+
18+
return (
19+
testVersion(packageJSON.parsed, 'dependencies') ||
20+
testVersion(packageJSON.parsed, 'devDependencies') ||
21+
DEFAULT_STENCIL_VERSION
22+
);
23+
};
24+
25+
class StencilTranspiler extends WorkerTranspiler {
26+
worker: Worker;
27+
28+
constructor() {
29+
super('stencil-loader', StencilWorker, 2);
30+
}
31+
32+
doTranspilation(code: string, loaderContext: LoaderContext) {
33+
return new Promise<TranspilerResult>((resolve, reject) => {
34+
const path = loaderContext.path;
35+
const packageJSON = loaderContext.options.configurations.package;
36+
37+
const stencilVersion = getStencilVersion(packageJSON);
38+
39+
this.queueTask(
40+
{
41+
code,
42+
path,
43+
stencilVersion,
44+
},
45+
loaderContext._module.getId(),
46+
loaderContext,
47+
(err, data) => {
48+
if (err) {
49+
loaderContext.emitError(err);
50+
51+
return reject(err);
52+
}
53+
54+
return resolve(data);
55+
}
56+
);
57+
});
58+
}
59+
}
60+
61+
const transpiler = new StencilTranspiler();
62+
63+
export { StencilTranspiler };
64+
65+
export default transpiler;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const ctx = self as any;
2+
3+
let loadedStencilVersion: string;
4+
const loadStencilVersion = (version: string) => {
5+
if (version !== loadedStencilVersion) {
6+
loadedStencilVersion = version;
7+
8+
ctx.importScripts(
9+
`https://unpkg.com/@stencil/core@${version}/compiler/stencil.js`
10+
);
11+
}
12+
};
13+
14+
ctx.importScripts('https://unpkg.com/[email protected]/lib/typescript.js');
15+
ctx.postMessage('ready');
16+
17+
ctx.addEventListener('message', event => {
18+
const { code, path, stencilVersion } = event.data;
19+
20+
loadStencilVersion(stencilVersion);
21+
22+
const opts = {
23+
file: path,
24+
module: 'cjs',
25+
};
26+
27+
ctx.stencil.compile(code, opts).then(results => {
28+
results.imports.forEach(dependency => {
29+
ctx.postMessage({
30+
type: 'add-dependency',
31+
path: dependency.path,
32+
isGlob: false,
33+
});
34+
});
35+
36+
ctx.postMessage({
37+
type: 'result',
38+
// Code won't execute with an import.meta in the code, so removing it now as a hack
39+
transpiledCode: results.code.replace(/^.*import\.meta.*$/gm, ''),
40+
});
41+
});
42+
});

0 commit comments

Comments
 (0)