Skip to content

Commit

Permalink
refactor(lib, register): use esbuild for register. Implement fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
Masquerade-Circus committed Aug 4, 2021
1 parent f518465 commit b220a8e
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 108 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
### [5.0.15](https://github.com/Masquerade-Circus/valyrian.js/compare/5.0.14...5.0.15) (2021-07-30)


### Bug Fixes

* **lib:** fix valyrian.js not updating the v- handlers ([1a52654](https://github.com/Masquerade-Circus/valyrian.js/commit/1a526540d3030cd198d33b1772c4d32e8aaf3bae))
* **lib:** fix valyrian.js not updating the v- handlers ([1a52654](https://github.com/Masquerade-Circus/valyrian.js/commit/1a526540d3030cd198d33b1772c4d32e8aaf3bae))

### [5.0.14](https://github.com/Masquerade-Circus/valyrian.js/compare/5.0.13...5.0.14) (2021-07-30)

Expand Down
1 change: 1 addition & 0 deletions dist/@types/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ declare class VnodeComponent implements VnodeComponent {
}
interface Valyrian {
(tagOrComponent: string | ValyrianComponent, props?: Props | null, children?: VnodeOrUnknown): Vnode | VnodeComponent;
fragment: (props: Props, children: VnodeOrUnknown[]) => VnodeOrUnknown[];
isMounted: boolean;
isNode: boolean;
reservedWords: string[];
Expand Down
2 changes: 1 addition & 1 deletion dist/valyrian.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/valyrian.min.js.map

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class VnodeComponent implements VnodeComponent {

interface Valyrian {
(tagOrComponent: string | ValyrianComponent, props?: Props | null, children?: VnodeOrUnknown): Vnode | VnodeComponent;
fragment: (props: Props, children: VnodeOrUnknown[]) => VnodeOrUnknown[];
isMounted: boolean;
isNode: boolean;
reservedWords: string[];
Expand Down Expand Up @@ -160,6 +161,10 @@ function valyrian(): Valyrian {
}
};

v.fragment = (props: Props, vnodes: VnodeOrUnknown[]) => {
return vnodes;
};

v.isMounted = false;
v.isNode = isNode;
const reservedWords = ["key", "data", "v-once", "oncreate", "onupdate", "onremove", "onbeforeupdate"];
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"node-fetch": "^2.6.1",
"parse5": "^6.0.1",
"purgecss": "4.0.3",
"sucrase": "^3.20.0",
"terser": "^5.7.1",
"ts-node": "^10.1.0",
"tsc-prog": "^2.2.1",
Expand Down
7 changes: 5 additions & 2 deletions plugins/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ function fileMethodFactory() {
resolveJsonModule: true,
removeComments: true,
...(options.tsc || {}).compilerOptions
}
},
jsxFactory: "v",
jsxFragment: "v.fragment"
};

tsc.build(tscProgOptions);
Expand All @@ -79,8 +81,9 @@ function fileMethodFactory() {
write: false,
minify: options.compact,
outdir: "out",
target: ["es2020"],
target: "esnext",
jsxFactory: "v",
jsxFragment: "v.fragment",
loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" },
...(options.esbuild || {})
});
Expand Down
10 changes: 2 additions & 8 deletions plugins/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ let plugin = function (v) {
return obj;
}

v.Store = function ({
state = {},
getters = {},
actions = {},
mutations = {}
} = {}) {
v.Store = function ({ state = {}, getters = {}, actions = {}, mutations = {} } = {}) {
let frozen = true;

function isUnfrozen() {
Expand Down Expand Up @@ -76,8 +71,7 @@ let plugin = function (v) {
};
};

v.useStore = (store) =>
(v.$store = store instanceof v.Store ? store : new v.Store(store));
v.useStore = (store) => (v.$store = store instanceof v.Store ? store : new v.Store(store));
};

plugin.default = plugin;
Expand Down
91 changes: 74 additions & 17 deletions register.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,80 @@
const { addHook } = require("pirates");
const { transform } = require("sucrase");

const jsxOptions = {
production: true,
transforms: ["imports", "typescript", "jsx"],
jsxPragma: "v",
jsxFragmentPragma: "v"
};
const { transformSync } = require("esbuild");
const fs = require("fs");

addHook(
(code, filePath) => {
let { code: transformed, sourceMap } = transform(code, {
sourceMapOptions: { compiledFilename: filePath },
filePath,
...jsxOptions
});
let mapBase64 = Buffer.from(JSON.stringify(sourceMap)).toString("base64");
let suffix = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`;
return `${transformed}\n${suffix}`;
let fileName = filePath.split("/").pop();
let extension = fileName.split(".").pop();

let loader = "default";
if (["js", "jsx", "ts", "tsx", "css", "json", "txt"].includes(extension)) {
if (["js", "jsx", "mjs"].includes(extension)) {
loader = "jsx";
} else if (["ts", "tsx"].includes(extension)) {
loader = "tsx";
} else if (extension === "txt") {
loader = "text";
} else {
loader = extension;
}
} else if (["jpeg", "jpg", "png", "gif", "webp", "svg"].includes(extension)) {
loader = "dataurl";
}

let options = {
tsconfigRaw: {
compilerOptions: {
target: "ESNEXT",
module: "ESNEXT",
strict: true,
allowSyntheticDefaultImports: true,
allowJs: true,
esModuleInterop: true,
resolveJsonModule: true
}
},
loader,
format: "cjs",
target: "esnext",
logLevel: "warning",
jsxFactory: "v",
jsxFragment: "v.fragment"
};

// Check if tsconfig.json exists with fs module
if ((extension === "ts" || extension === "tsx") && fs.existsSync(process.cwd() + "/tsconfig.json")) {
let tsconfig = fs.readFileSync(process.cwd() + "/tsconfig.json", "utf8");

let tsconfigRaw = JSON.parse(tsconfig);
let compilerOptions = tsconfigRaw.compilerOptions || {};

options.tsconfigRaw = { ...options.tsconfigRaw, ...tsconfigRaw };
options.tsconfigRaw.compilerOptions = { ...options.tsconfigRaw.compilerOptions, ...compilerOptions };

if (compilerOptions.target) {
options.target = compilerOptions.target.toLowerCase();
}

if (compilerOptions.module) {
let format = compilerOptions.module.toLowerCase();
if (format === "commonjs") {
options.format = "cjs";
} else if (format.startsWith("es")) {
options.format = "esm";
}
}
}

let { code: transformed } = transformSync(code, options);
if (/"use strict"\;/gi.test(code) === false) {
transformed = '"use strict";\n' + transformed;
}

return transformed;
},
{ exts: [".js", ".jsx", ".ts", ".tsx", ".mjs"] }
{
exts: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".css", ".json", ".text", ".jpeg", ".jpg", ".png", ".gif", ".webp", ".svg", ".html"],
ignoreNodeModules: true
}
);
12 changes: 12 additions & 0 deletions test/mount_n_update_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,18 @@ describe("Mount and update", () => {
// For the second instance should be 'Hello world 1' because it is still mounted
expect(result4).toEqual("Hello world 1");
});

it("should allow to use fragments", () => {
let component = () => (
<>
<span>Hello</span>
<span>World</span>
</>
);

let result = v.mount("body", component);
expect(result).toEqual("<span>Hello</span><span>World</span>");
});
});

describe.skip("performance test", () => {
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "ES6" /* For reference check: https://node.green/#ES2020 */,
"module": "ES6",
"target": "ESNEXT",
"module": "ESNEXT",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
Expand Down
Loading

0 comments on commit b220a8e

Please sign in to comment.